/* -*- 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 "RosegardenGUIView.h"
# include <kapplication.h>
# include "sound/Midi.h"
# include "gui/editors/segment/TrackButtons.h"
# include <klocale.h>
# include "misc/Debug.h"
# include "misc/Strings.h"
# include "document/ConfigGroups.h"
# include "gui/application/RosegardenDCOP.h"
# include "base/AudioLevel.h"
# include "base/Composition.h"
# include "base/Instrument.h"
# include "base/MidiDevice.h"
# include "base/MidiProgram.h"
# include "base/NotationTypes.h"
# include "base/RealTime.h"
# include "base/RulerScale.h"
# include "base/Segment.h"
# include "base/Selection.h"
# include "base/Studio.h"
# include "base/Track.h"
# include "commands/segment/AudioSegmentAutoSplitCommand.h"
# include "commands/segment/AudioSegmentInsertCommand.h"
# include "commands/segment/SegmentSingleRepeatToCopyCommand.h"
# include "document/MultiViewCommandHistory.h"
# include "document/RosegardenGUIDoc.h"
# include "RosegardenApplication.h"
# include "gui/configuration/GeneralConfigurationPage.h"
# include "gui/configuration/AudioConfigurationPage.h"
# include "gui/dialogs/AudioSplitDialog.h"
# include "gui/dialogs/AudioManagerDialog.h"
# include "gui/dialogs/DocumentConfigureDialog.h"
# include "gui/dialogs/TempoDialog.h"
# include "gui/editors/eventlist/EventView.h"
# include "gui/editors/matrix/MatrixView.h"
# include "gui/editors/notation/NotationView.h"
# include "gui/editors/parameters/InstrumentParameterBox.h"
# include "gui/editors/parameters/SegmentParameterBox.h"
# include "gui/editors/parameters/TrackParameterBox.h"
# include "gui/editors/segment/segmentcanvas/CompositionView.h"
# include "gui/editors/segment/segmentcanvas/SegmentSelector.h"
# include "gui/editors/segment/TrackEditor.h"
# include "gui/seqmanager/SequenceManager.h"
# include "gui/seqmanager/SequencerMapper.h"
# include "gui/rulers/ChordNameRuler.h"
# include "gui/rulers/LoopRuler.h"
# include "gui/rulers/TempoRuler.h"
# include "gui/rulers/StandardRuler.h"
# include "gui/widgets/ProgressDialog.h"
# include "gui/widgets/CurrentProgressDialog.h"
# include "RosegardenGUIApp.h"
# include "SetWaitCursor.h"
# include "sound/AudioFile.h"
# include "sound/AudioFileManager.h"
# include "sound/MappedEvent.h"
# include <kcommand.h>
# include <kconfig.h>
# include <kmessagebox.h>
# include <kprocess.h>
# include <tqapplication.h>
# include <tqcursor.h>
# include <tqdialog.h>
# include <tqfileinfo.h>
# include <tqobject.h>
# include <tqstring.h>
# include <tqvbox.h>
# include <tqwidget.h>
namespace Rosegarden
{
// Use this to define the basic unit of the main TQCanvas size.
//
// This apparently arbitrary figure is what we think is an
// appropriate width in pixels for a 4/4 bar. Beware of making it
// too narrow, as shorter bars will be proportionally smaller --
// the visual difference between 2/4 and 4/4 is perhaps greater
// than it sounds.
//
static double barWidth44 = 100.0 ;
const TQWidget * RosegardenGUIView : : m_lastActiveMainWindow = 0 ;
// This is the maximum number of matrix, event view or percussion
// matrix editors to open in a single operation (not the maximum that
// can be open at a time -- there isn't one)
//
static int maxEditorsToOpen = 8 ;
RosegardenGUIView : : RosegardenGUIView ( bool showTrackLabels ,
SegmentParameterBox * segmentParameterBox ,
InstrumentParameterBox * instrumentParameterBox ,
TrackParameterBox * trackParameterBox ,
TQWidget * parent ,
const char * /*name*/ )
: TQVBox ( parent ) ,
m_rulerScale ( 0 ) ,
m_trackEditor ( 0 ) ,
m_segmentParameterBox ( segmentParameterBox ) ,
m_instrumentParameterBox ( instrumentParameterBox ) ,
m_trackParameterBox ( trackParameterBox )
{
RosegardenGUIDoc * doc = getDocument ( ) ;
Composition * comp = & doc - > getComposition ( ) ;
double unitsPerPixel =
TimeSignature ( 4 , 4 ) . getBarDuration ( ) / barWidth44 ;
m_rulerScale = new SimpleRulerScale ( comp , 0 , unitsPerPixel ) ;
// Construct the trackEditor first so we can then
// query it for placement information
//
m_trackEditor = new TrackEditor ( doc , this ,
m_rulerScale , showTrackLabels , unitsPerPixel , this /*hbox*/ ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editSegment ( Segment * ) ) ,
TQT_SLOT ( slotEditSegment ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editSegmentNotation ( Segment * ) ) ,
TQT_SLOT ( slotEditSegmentNotation ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editSegmentMatrix ( Segment * ) ) ,
TQT_SLOT ( slotEditSegmentMatrix ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editSegmentAudio ( Segment * ) ) ,
TQT_SLOT ( slotEditSegmentAudio ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( audioSegmentAutoSplit ( Segment * ) ) ,
TQT_SLOT ( slotSegmentAutoSplit ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editSegmentEventList ( Segment * ) ) ,
TQT_SLOT ( slotEditSegmentEventList ( Segment * ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( editRepeat ( Segment * , timeT ) ) ,
TQT_SLOT ( slotEditRepeat ( Segment * , timeT ) ) ) ;
connect ( m_trackEditor - > getSegmentCanvas ( ) ,
TQT_SIGNAL ( setPointerPosition ( timeT ) ) ,
doc , TQT_SLOT ( slotSetPointerPosition ( timeT ) ) ) ;
connect ( m_trackEditor ,
TQT_SIGNAL ( droppedDocument ( TQString ) ) ,
parent ,
TQT_SLOT ( slotOpenDroppedURL ( TQString ) ) ) ;
connect ( m_trackEditor ,
TQT_SIGNAL ( droppedAudio ( TQString ) ) ,
this ,
TQT_SLOT ( slotDroppedAudio ( TQString ) ) ) ;
connect ( m_trackEditor ,
TQT_SIGNAL ( droppedNewAudio ( TQString ) ) ,
this ,
TQT_SLOT ( slotDroppedNewAudio ( TQString ) ) ) ;
connect ( m_instrumentParameterBox ,
TQT_SIGNAL ( changeInstrumentLabel ( InstrumentId , TQString ) ) ,
this ,
TQT_SLOT ( slotChangeInstrumentLabel ( InstrumentId , TQString ) ) ) ;
connect ( m_instrumentParameterBox ,
TQT_SIGNAL ( changeInstrumentLabel ( InstrumentId , TQString ) ) ,
m_trackParameterBox ,
TQT_SLOT ( slotInstrumentLabelChanged ( InstrumentId , TQString ) ) ) ;
connect ( m_trackEditor - > getTrackButtons ( ) ,
TQT_SIGNAL ( nameChanged ( ) ) ,
m_trackParameterBox ,
TQT_SLOT ( slotSelectedTrackNameChanged ( ) ) ) ;
connect ( m_trackEditor - > getTrackButtons ( ) ,
TQT_SIGNAL ( instrumentSelected ( int ) ) ,
m_trackParameterBox ,
TQT_SLOT ( slotUpdateControls ( int ) ) ) ;
connect ( m_trackParameterBox ,
TQT_SIGNAL ( instrumentSelected ( TrackId , int ) ) ,
m_trackEditor - > getTrackButtons ( ) ,
TQT_SLOT ( slotTrackInstrumentSelection ( TrackId , int ) ) ) ;
connect ( this , TQT_SIGNAL ( controllerDeviceEventReceived ( MappedEvent * , const void * ) ) ,
this , TQT_SLOT ( slotControllerDeviceEventReceived ( MappedEvent * , const void * ) ) ) ;
if ( doc ) {
/* signal no longer exists
connect ( doc , TQT_SIGNAL ( recordingSegmentUpdated ( Segment * ,
timeT ) ) ,
this , TQT_SLOT ( slotUpdateRecordingSegment ( Segment * ,
timeT ) ) ) ;
*/
TQObject : : connect
( getCommandHistory ( ) , TQT_SIGNAL ( commandExecuted ( ) ) ,
m_trackEditor - > getSegmentCanvas ( ) , TQT_SLOT ( slotUpdateSegmentsDrawBuffer ( ) ) ) ;
}
}
RosegardenGUIView : : ~ RosegardenGUIView ( )
{
RG_DEBUG < < " ~RosegardenGUIView() " < < endl ;
delete m_rulerScale ;
}
RosegardenGUIDoc *
RosegardenGUIView : : getDocument ( ) const
{
return RosegardenGUIApp : : self ( ) - > getDocument ( ) ;
}
void RosegardenGUIView : : print ( Composition * p , bool previewOnly )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
for ( Composition : : iterator i = p - > begin ( ) ; i ! = p - > end ( ) ; + + i ) {
if ( ( * i ) - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( * i ) ;
}
}
if ( segmentsToEdit . empty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " No non-audio segments in composition " ) ) ;
return ;
}
NotationView * notationView = new NotationView ( getDocument ( ) ,
segmentsToEdit ,
this ,
( NotationView * ) 0 ) ;
if ( ! notationView - > isOK ( ) ) {
RG_DEBUG < < " RosegardenGUIView::print : operation cancelled " < < endl ;
delete notationView ;
return ;
}
notationView - > print ( previewOnly ) ;
delete notationView ;
}
void RosegardenGUIView : : selectTool ( const TQString toolName )
{
m_trackEditor - > getSegmentCanvas ( ) - > slotSetTool ( toolName ) ;
}
bool
RosegardenGUIView : : haveSelection ( )
{
return m_trackEditor - > getSegmentCanvas ( ) - > haveSelection ( ) ;
}
SegmentSelection
RosegardenGUIView : : getSelection ( )
{
return m_trackEditor - > getSegmentCanvas ( ) - > getSelectedSegments ( ) ;
}
void RosegardenGUIView : : updateSelectionContents ( )
{
m_trackEditor - > getSegmentCanvas ( ) - > updateSelectionContents ( ) ;
}
/* hjj: WHAT DO DO WITH THIS ?
void
RosegardenGUIView : : slotEditMetadata ( TQString name )
{
const TQWidget * ww = dynamic_cast < const TQWidget * > ( sender ( ) ) ;
TQWidget * w = const_cast < TQWidget * > ( ww ) ;
DocumentConfigureDialog * configDlg =
new DocumentConfigureDialog ( getDocument ( ) , w ? w : this ) ;
configDlg - > selectMetadata ( name ) ;
configDlg - > show ( ) ;
}
*/
void RosegardenGUIView : : slotEditSegment ( Segment * segment )
{
Segment : : SegmentType type = Segment : : Internal ;
if ( segment ) {
type = segment - > getType ( ) ;
} else {
if ( haveSelection ( ) ) {
bool haveType = false ;
SegmentSelection selection = getSelection ( ) ;
for ( SegmentSelection : : iterator i = selection . begin ( ) ;
i ! = selection . end ( ) ; + + i ) {
Segment : : SegmentType myType = ( * i ) - > getType ( ) ;
if ( haveType ) {
if ( myType ! = type ) {
KMessageBox : : sorry ( this , i18n ( " Selection must contain only audio or non-audio segments " ) ) ;
return ;
}
} else {
type = myType ;
haveType = true ;
segment = * i ;
}
}
} else
return ;
}
if ( type = = Segment : : Audio ) {
slotEditSegmentAudio ( segment ) ;
} else {
KConfig * config = kapp - > config ( ) ;
config - > setGroup ( GeneralOptionsConfigGroup ) ;
GeneralConfigurationPage : : DoubleClickClient
client =
( GeneralConfigurationPage : : DoubleClickClient )
( config - > readUnsignedNumEntry ( " doubleclickclient " ,
( unsigned int ) GeneralConfigurationPage : : NotationView ) ) ;
if ( client = = GeneralConfigurationPage : : MatrixView ) {
bool isPercussion = false ;
Track * track = getDocument ( ) - > getComposition ( ) . getTrackById
( segment - > getTrack ( ) ) ;
if ( track ) {
InstrumentId iid = track - > getInstrument ( ) ;
Instrument * instrument =
getDocument ( ) - > getStudio ( ) . getInstrumentById ( iid ) ;
if ( instrument & & instrument - > isPercussion ( ) ) isPercussion = true ;
}
if ( isPercussion ) {
slotEditSegmentPercussionMatrix ( segment ) ;
} else {
slotEditSegmentMatrix ( segment ) ;
}
} else if ( client = = GeneralConfigurationPage : : EventView ) {
slotEditSegmentEventList ( segment ) ;
} else {
slotEditSegmentNotation ( segment ) ;
}
}
}
void RosegardenGUIView : : slotEditRepeat ( Segment * segment ,
timeT time )
{
SegmentSingleRepeatToCopyCommand * command =
new SegmentSingleRepeatToCopyCommand ( segment , time ) ;
slotAddCommandToHistory ( command ) ;
}
void RosegardenGUIView : : slotEditSegmentNotation ( Segment * p )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
RG_DEBUG < < " \n \n \n \n RosegardenGUIView::slotEditSegmentNotation: p is " < < p < < endl ;
// The logic here is: If we're calling for this operation to
// happen on a particular segment, then open that segment and if
// it's part of a selection open all other selected segments too.
// If we're not calling for any particular segment, then open all
// selected segments if there are any.
if ( haveSelection ( ) ) {
SegmentSelection selection = getSelection ( ) ;
if ( ! p | | ( selection . find ( p ) ! = selection . end ( ) ) ) {
for ( SegmentSelection : : iterator i = selection . begin ( ) ;
i ! = selection . end ( ) ; + + i ) {
if ( ( * i ) - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( * i ) ;
}
}
} else {
if ( p - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( p ) ;
}
}
} else if ( p ) {
if ( p - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( p ) ;
}
} else {
return ;
}
if ( segmentsToEdit . empty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " No non-audio segments selected " ) ) ;
return ;
}
slotEditSegmentsNotation ( segmentsToEdit ) ;
}
void RosegardenGUIView : : slotEditSegmentsNotation ( std : : vector < Segment * > segmentsToEdit )
{
NotationView * view = createNotationView ( segmentsToEdit ) ;
if ( view )
view - > show ( ) ;
}
NotationView *
RosegardenGUIView : : createNotationView ( std : : vector < Segment * > segmentsToEdit )
{
NotationView * notationView =
new NotationView ( getDocument ( ) , segmentsToEdit , this , true ) ;
if ( ! notationView - > isOK ( ) ) {
RG_DEBUG < < " slotEditSegmentNotation : operation cancelled " < < endl ;
delete notationView ;
return 0 ;
}
// For tempo changes (ugh -- it'd be nicer to make a tempo change
// command that could interpret all this stuff from the dialog)
//
connect ( notationView , TQT_SIGNAL ( changeTempo ( timeT ,
tempoT ,
tempoT ,
TempoDialog : : TempoDialogAction ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotChangeTempo ( timeT ,
tempoT ,
tempoT ,
TempoDialog : : TempoDialogAction ) ) ) ;
connect ( notationView , TQT_SIGNAL ( windowActivated ( ) ) ,
this , TQT_SLOT ( slotActiveMainWindowChanged ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( selectTrack ( int ) ) ,
this , TQT_SLOT ( slotSelectTrackSegments ( int ) ) ) ;
connect ( notationView , TQT_SIGNAL ( play ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotPlay ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( stop ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotStop ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( fastForwardPlayback ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFastforward ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( rewindPlayback ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotRewind ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( fastForwardPlaybackToEnd ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFastForwardToEnd ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( rewindPlaybackToBeginning ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotRewindToBeginning ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( panic ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotPanic ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( saveFile ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFileSave ( ) ) ) ;
connect ( notationView , TQT_SIGNAL ( jumpPlaybackTo ( timeT ) ) ,
getDocument ( ) , TQT_SLOT ( slotSetPointerPosition ( timeT ) ) ) ;
connect ( notationView , TQT_SIGNAL ( openInNotation ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsNotation ( std : : vector < Segment * > ) ) ) ;
connect ( notationView , TQT_SIGNAL ( openInMatrix ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsMatrix ( std : : vector < Segment * > ) ) ) ;
connect ( notationView , TQT_SIGNAL ( openInPercussionMatrix ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsPercussionMatrix ( std : : vector < Segment * > ) ) ) ;
connect ( notationView , TQT_SIGNAL ( openInEventList ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsEventList ( std : : vector < Segment * > ) ) ) ;
/* hjj: WHAT DO DO WITH THIS ?
connect ( notationView , TQT_SIGNAL ( editMetadata ( TQString ) ) ,
this , TQT_SLOT ( slotEditMetadata ( TQString ) ) ) ;
*/
connect ( notationView , TQT_SIGNAL ( editTriggerSegment ( int ) ) ,
this , TQT_SLOT ( slotEditTriggerSegment ( int ) ) ) ;
connect ( notationView , TQT_SIGNAL ( staffLabelChanged ( TrackId , TQString ) ) ,
this , TQT_SLOT ( slotChangeTrackLabel ( TrackId , TQString ) ) ) ;
connect ( notationView , TQT_SIGNAL ( toggleSolo ( bool ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotToggleSolo ( bool ) ) ) ;
connect ( notationView , TQT_SIGNAL ( editTimeSignature ( timeT ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotEditTempos ( timeT ) ) ) ;
SequenceManager * sM = getDocument ( ) - > getSequenceManager ( ) ;
connect ( sM , TQT_SIGNAL ( insertableNoteOnReceived ( int , int ) ) ,
notationView , TQT_SLOT ( slotInsertableNoteOnReceived ( int , int ) ) ) ;
connect ( sM , TQT_SIGNAL ( insertableNoteOffReceived ( int , int ) ) ,
notationView , TQT_SLOT ( slotInsertableNoteOffReceived ( int , int ) ) ) ;
connect ( notationView , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ,
this , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ) ;
connect ( this , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ,
notationView , TQT_SLOT ( slotStepByStepTargetRequested ( TQObject * ) ) ) ;
connect ( RosegardenGUIApp : : self ( ) , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
notationView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
connect ( this , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
notationView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
// Encourage the notation view window to open to the same
// interval as the current segment view
if ( m_trackEditor - > getSegmentCanvas ( ) - > horizontalScrollBar ( ) - > value ( ) > 1 ) { // don't scroll unless we need to
// first find the time at the center of the visible segment canvas
int centerX = ( int ) ( m_trackEditor - > getSegmentCanvas ( ) - > contentsX ( ) +
m_trackEditor - > getSegmentCanvas ( ) - > visibleWidth ( ) / 2 ) ;
timeT centerSegmentView = m_trackEditor - > getRulerScale ( ) - > getTimeForX ( centerX ) ;
// then scroll the notation view to that time, "localized" for the current segment
notationView - > scrollToTime ( centerSegmentView ) ;
notationView - > updateView ( ) ;
}
return notationView ;
}
void RosegardenGUIView : : slotEditSegmentMatrix ( Segment * p )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
// unlike notation, if we're calling for this on a particular
// segment we don't open all the other selected segments as well
// (fine in notation because they're in a single window)
if ( p ) {
if ( p - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( p ) ;
}
} else {
int count = 0 ;
SegmentSelection selection = getSelection ( ) ;
for ( SegmentSelection : : iterator i = selection . begin ( ) ;
i ! = selection . end ( ) ; + + i ) {
if ( ( * i ) - > getType ( ) ! = Segment : : Audio ) {
slotEditSegmentMatrix ( * i ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
return ;
}
if ( segmentsToEdit . empty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " No non-audio segments selected " ) ) ;
return ;
}
slotEditSegmentsMatrix ( segmentsToEdit ) ;
}
void RosegardenGUIView : : slotEditSegmentPercussionMatrix ( Segment * p )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
// unlike notation, if we're calling for this on a particular
// segment we don't open all the other selected segments as well
// (fine in notation because they're in a single window)
if ( p ) {
if ( p - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( p ) ;
}
} else {
int count = 0 ;
SegmentSelection selection = getSelection ( ) ;
for ( SegmentSelection : : iterator i = selection . begin ( ) ;
i ! = selection . end ( ) ; + + i ) {
if ( ( * i ) - > getType ( ) ! = Segment : : Audio ) {
slotEditSegmentPercussionMatrix ( * i ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
return ;
}
if ( segmentsToEdit . empty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " No non-audio segments selected " ) ) ;
return ;
}
slotEditSegmentsPercussionMatrix ( segmentsToEdit ) ;
}
void RosegardenGUIView : : slotEditSegmentsMatrix ( std : : vector < Segment * > segmentsToEdit )
{
int count = 0 ;
for ( std : : vector < Segment * > : : iterator i = segmentsToEdit . begin ( ) ;
i ! = segmentsToEdit . end ( ) ; + + i ) {
std : : vector < Segment * > tmpvec ;
tmpvec . push_back ( * i ) ;
MatrixView * view = createMatrixView ( tmpvec , false ) ;
if ( view ) {
view - > show ( ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
}
void RosegardenGUIView : : slotEditSegmentsPercussionMatrix ( std : : vector < Segment * > segmentsToEdit )
{
int count = 0 ;
for ( std : : vector < Segment * > : : iterator i = segmentsToEdit . begin ( ) ;
i ! = segmentsToEdit . end ( ) ; + + i ) {
std : : vector < Segment * > tmpvec ;
tmpvec . push_back ( * i ) ;
MatrixView * view = createMatrixView ( tmpvec , true ) ;
if ( view ) {
view - > show ( ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
}
MatrixView *
RosegardenGUIView : : createMatrixView ( std : : vector < Segment * > segmentsToEdit , bool drumMode )
{
MatrixView * matrixView = new MatrixView ( getDocument ( ) ,
segmentsToEdit ,
this ,
drumMode ) ;
// For tempo changes (ugh -- it'd be nicer to make a tempo change
// command that could interpret all this stuff from the dialog)
//
connect ( matrixView , TQT_SIGNAL ( changeTempo ( timeT ,
tempoT ,
tempoT ,
TempoDialog : : TempoDialogAction ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotChangeTempo ( timeT ,
tempoT ,
tempoT ,
TempoDialog : : TempoDialogAction ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( windowActivated ( ) ) ,
this , TQT_SLOT ( slotActiveMainWindowChanged ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( selectTrack ( int ) ) ,
this , TQT_SLOT ( slotSelectTrackSegments ( int ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( play ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotPlay ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( stop ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotStop ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( fastForwardPlayback ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFastforward ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( rewindPlayback ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotRewind ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( fastForwardPlaybackToEnd ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFastForwardToEnd ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( rewindPlaybackToBeginning ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotRewindToBeginning ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( panic ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotPanic ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( saveFile ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFileSave ( ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( jumpPlaybackTo ( timeT ) ) ,
getDocument ( ) , TQT_SLOT ( slotSetPointerPosition ( timeT ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( openInNotation ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsNotation ( std : : vector < Segment * > ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( openInMatrix ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsMatrix ( std : : vector < Segment * > ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( openInEventList ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsEventList ( std : : vector < Segment * > ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( editTriggerSegment ( int ) ) ,
this , TQT_SLOT ( slotEditTriggerSegment ( int ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( toggleSolo ( bool ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotToggleSolo ( bool ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( editTimeSignature ( timeT ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotEditTempos ( timeT ) ) ) ;
SequenceManager * sM = getDocument ( ) - > getSequenceManager ( ) ;
connect ( sM , TQT_SIGNAL ( insertableNoteOnReceived ( int , int ) ) ,
matrixView , TQT_SLOT ( slotInsertableNoteOnReceived ( int , int ) ) ) ;
connect ( sM , TQT_SIGNAL ( insertableNoteOffReceived ( int , int ) ) ,
matrixView , TQT_SLOT ( slotInsertableNoteOffReceived ( int , int ) ) ) ;
connect ( matrixView , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ,
this , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ) ;
connect ( this , TQT_SIGNAL ( stepByStepTargetRequested ( TQObject * ) ) ,
matrixView , TQT_SLOT ( slotStepByStepTargetRequested ( TQObject * ) ) ) ;
connect ( RosegardenGUIApp : : self ( ) , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
matrixView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
connect ( this , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
matrixView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
connect ( this ,
TQT_SIGNAL ( instrumentLevelsChanged ( InstrumentId ,
const LevelInfo & ) ) ,
matrixView ,
TQT_SLOT ( slotInstrumentLevelsChanged ( InstrumentId ,
const LevelInfo & ) ) ) ;
// Encourage the matrix view window to open to the same
// interval as the current segment view
if ( m_trackEditor - > getSegmentCanvas ( ) - > horizontalScrollBar ( ) - > value ( ) > 1 ) { // don't scroll unless we need to
// first find the time at the center of the visible segment canvas
int centerX = ( int ) ( m_trackEditor - > getSegmentCanvas ( ) - > contentsX ( ) ) ;
// Seems to work better for matrix view to scroll to left side
// + m_trackEditor->getSegmentCanvas()->visibleWidth() / 2);
timeT centerSegmentView = m_trackEditor - > getRulerScale ( ) - > getTimeForX ( centerX ) ;
// then scroll the notation view to that time, "localized" for the current segment
matrixView - > scrollToTime ( centerSegmentView ) ;
matrixView - > updateView ( ) ;
}
return matrixView ;
}
void RosegardenGUIView : : slotEditSegmentEventList ( Segment * p )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
// unlike notation, if we're calling for this on a particular
// segment we don't open all the other selected segments as well
// (fine in notation because they're in a single window)
if ( p ) {
if ( p - > getType ( ) ! = Segment : : Audio ) {
segmentsToEdit . push_back ( p ) ;
}
} else {
int count = 0 ;
SegmentSelection selection = getSelection ( ) ;
for ( SegmentSelection : : iterator i = selection . begin ( ) ;
i ! = selection . end ( ) ; + + i ) {
if ( ( * i ) - > getType ( ) ! = Segment : : Audio ) {
slotEditSegmentEventList ( * i ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
return ;
}
if ( segmentsToEdit . empty ( ) ) {
KMessageBox : : sorry ( this , i18n ( " No non-audio segments selected " ) ) ;
return ;
}
slotEditSegmentsEventList ( segmentsToEdit ) ;
}
void RosegardenGUIView : : slotEditSegmentsEventList ( std : : vector < Segment * > segmentsToEdit )
{
int count = 0 ;
for ( std : : vector < Segment * > : : iterator i = segmentsToEdit . begin ( ) ;
i ! = segmentsToEdit . end ( ) ; + + i ) {
std : : vector < Segment * > tmpvec ;
tmpvec . push_back ( * i ) ;
EventView * view = createEventView ( tmpvec ) ;
if ( view ) {
view - > show ( ) ;
if ( + + count = = maxEditorsToOpen )
break ;
}
}
}
void RosegardenGUIView : : slotEditTriggerSegment ( int id )
{
SetWaitCursor waitCursor ;
std : : vector < Segment * > segmentsToEdit ;
Segment * s = getDocument ( ) - > getComposition ( ) . getTriggerSegment ( id ) ;
if ( s ) {
segmentsToEdit . push_back ( s ) ;
} else {
return ;
}
slotEditSegmentsEventList ( segmentsToEdit ) ;
}
void RosegardenGUIView : : slotSegmentAutoSplit ( Segment * segment )
{
AudioSplitDialog aSD ( this , segment , getDocument ( ) ) ;
if ( aSD . exec ( ) = = TQDialog : : Accepted ) {
KCommand * command =
new AudioSegmentAutoSplitCommand ( getDocument ( ) ,
segment , aSD . getThreshold ( ) ) ;
slotAddCommandToHistory ( command ) ;
}
}
void RosegardenGUIView : : slotEditSegmentAudio ( Segment * segment )
{
std : : cout < < " RosegardenGUIView::slotEditSegmentAudio() - "
< < " starting external audio editor " < < std : : endl ;
KConfig * config = kapp - > config ( ) ;
config - > setGroup ( GeneralOptionsConfigGroup ) ;
TQString application = config - > readEntry ( " externalaudioeditor " , " " ) ;
if ( application = = " " ) {
application = AudioConfigurationPage : : getBestAvailableAudioEditor ( ) ;
}
TQStringList splitCommand = TQStringList : : split ( " " , application ) ;
if ( splitCommand . size ( ) = = 0 ) {
std : : cerr < < " RosegardenGUIView::slotEditSegmentAudio() - "
< < " external editor \" " < < application . ascii ( )
< < " \" not found " < < std : : endl ;
KMessageBox : : sorry ( this ,
i18n ( " You've not yet defined an audio editor for Rosegarden to use. \n See Settings -> Configure Rosegarden -> Audio. " ) ) ;
return ;
}
TQFileInfo * appInfo = new TQFileInfo ( splitCommand [ 0 ] ) ;
if ( appInfo - > exists ( ) = = false | | appInfo - > isExecutable ( ) = = false ) {
std : : cerr < < " RosegardenGUIView::slotEditSegmentAudio() - "
< < " can't execute \" " < < splitCommand [ 0 ] . ascii ( ) < < " \" "
< < std : : endl ;
return ;
}
AudioFile * aF = getDocument ( ) - > getAudioFileManager ( ) .
getAudioFile ( segment - > getAudioFileId ( ) ) ;
if ( aF = = 0 ) {
std : : cerr < < " RosegardenGUIView::slotEditSegmentAudio() - "
< < " can't find audio file " < < std : : endl ;
return ;
}
// wait cursor
TQApplication : : setOverrideCursor ( TQCursor ( TQt : : waitCursor ) ) ;
// Prepare the process
//
KProcess * process = new KProcess ( ) ;
( * process ) < < splitCommand ;
( * process ) < < TQString ( aF - > getFilename ( ) . c_str ( ) ) ;
// Start it
//
if ( ! process - > start ( ) ) {
std : : cerr < < " RosegardenGUIView::slotEditSegmentAudio() - "
< < " can't start external editor " < < std : : endl ;
}
// restore cursor
TQApplication : : restoreOverrideCursor ( ) ;
}
void RosegardenGUIView : : setZoomSize ( double size )
{
m_rulerScale - > setUnitsPerPixel ( size ) ;
double duration44 = TimeSignature ( 4 , 4 ) . getBarDuration ( ) ;
double xScale = duration44 / ( size * barWidth44 ) ;
RG_DEBUG < < " RosegardenGUIView::setZoomSize - xScale = " < < xScale < < endl ;
m_trackEditor - > slotSetPointerPosition
( getDocument ( ) - > getComposition ( ) . getPosition ( ) ) ;
m_trackEditor - > getSegmentCanvas ( ) - > clearSegmentRectsCache ( true ) ;
m_trackEditor - > getSegmentCanvas ( ) - > slotUpdateSize ( ) ;
m_trackEditor - > getSegmentCanvas ( ) - > slotUpdateSegmentsDrawBuffer ( ) ;
if ( m_trackEditor - > getTempoRuler ( ) ) {
m_trackEditor - > getTempoRuler ( ) - > tqrepaint ( ) ;
}
if ( m_trackEditor - > getChordNameRuler ( ) ) {
m_trackEditor - > getChordNameRuler ( ) - > tqrepaint ( ) ;
}
if ( m_trackEditor - > getTopStandardRuler ( ) ) {
m_trackEditor - > getTopStandardRuler ( ) - > tqrepaint ( ) ;
}
if ( m_trackEditor - > getBottomStandardRuler ( ) ) {
m_trackEditor - > getBottomStandardRuler ( ) - > tqrepaint ( ) ;
}
}
void RosegardenGUIView : : slotSelectTrackSegments ( int trackId )
{
// update the instrument parameter box
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Track * track = comp . getTrackById ( trackId ) ;
if ( track = = 0 )
return ;
// Show the selection on the track buttons. Find the position.
//
m_trackEditor - > getTrackButtons ( ) - > selectLabel ( track - > getPosition ( ) ) ;
m_trackEditor - > slotScrollToTrack ( track - > getPosition ( ) ) ;
SegmentSelection segments ;
for ( Composition : : iterator i =
getDocument ( ) - > getComposition ( ) . begin ( ) ;
i ! = getDocument ( ) - > getComposition ( ) . end ( ) ; i + + ) {
if ( ( ( int ) ( * i ) - > getTrack ( ) ) = = trackId )
segments . insert ( * i ) ;
}
// Store the selected Track in the Composition
//
comp . setSelectedTrack ( trackId ) ;
m_trackParameterBox - > slotSelectedTrackChanged ( ) ;
slotUpdateInstrumentParameterBox ( comp . getTrackById ( trackId ) - >
getInstrument ( ) ) ;
slotPropagateSegmentSelection ( segments ) ;
// inform
emit segmentsSelected ( segments ) ;
emit compositionStateUpdate ( ) ;
}
void RosegardenGUIView : : slotPropagateSegmentSelection ( const SegmentSelection & segments )
{
// Send this signal to the GUI to activate the correct tool
// on the toolbar so that we have a SegmentSelector object
// to write the Segments into
//
if ( ! segments . empty ( ) ) {
emit activateTool ( SegmentSelector : : ToolName ) ;
}
// Send the segment list even if it's empty as we
// use that to clear any current selection
//
m_trackEditor - > getSegmentCanvas ( ) - > slotSelectSegments ( segments ) ;
// update the segment parameter box
m_segmentParameterBox - > useSegments ( segments ) ;
if ( ! segments . empty ( ) ) {
emit stateChange ( " have_selection " , true ) ;
if ( ! segments . hasNonAudioSegment ( ) ) {
emit stateChange ( " audio_segment_selected " , true ) ;
}
} else {
emit stateChange ( " have_selection " , false ) ;
}
}
void RosegardenGUIView : : slotSelectAllSegments ( )
{
SegmentSelection segments ;
InstrumentId instrument = 0 ;
bool haveInstrument = false ;
bool multipleInstruments = false ;
Composition & comp = getDocument ( ) - > getComposition ( ) ;
for ( Composition : : iterator i = comp . begin ( ) ; i ! = comp . end ( ) ; + + i ) {
InstrumentId myInstrument =
comp . getTrackById ( ( * i ) - > getTrack ( ) ) - > getInstrument ( ) ;
if ( haveInstrument ) {
if ( myInstrument ! = instrument ) {
multipleInstruments = true ;
}
} else {
instrument = myInstrument ;
haveInstrument = true ;
}
segments . insert ( * i ) ;
}
// Send this signal to the GUI to activate the correct tool
// on the toolbar so that we have a SegmentSelector object
// to write the Segments into
//
if ( ! segments . empty ( ) ) {
emit activateTool ( SegmentSelector : : ToolName ) ;
}
// Send the segment list even if it's empty as we
// use that to clear any current selection
//
m_trackEditor - > getSegmentCanvas ( ) - > slotSelectSegments ( segments ) ;
// update the segment parameter box
m_segmentParameterBox - > useSegments ( segments ) ;
// update the instrument parameter box
if ( haveInstrument & & ! multipleInstruments ) {
slotUpdateInstrumentParameterBox ( instrument ) ;
} else {
m_instrumentParameterBox - > useInstrument ( 0 ) ;
}
//!!! similarly, how to set no selected track?
//comp.setSelectedTrack(trackId);
if ( ! segments . empty ( ) ) {
emit stateChange ( " have_selection " , true ) ;
if ( ! segments . hasNonAudioSegment ( ) ) {
emit stateChange ( " audio_segment_selected " , true ) ;
}
} else {
emit stateChange ( " have_selection " , false ) ;
}
// inform
//!!! inform what? is this signal actually used?
emit segmentsSelected ( segments ) ;
}
void RosegardenGUIView : : slotUpdateInstrumentParameterBox ( int id )
{
Studio & studio = getDocument ( ) - > getStudio ( ) ;
Instrument * instrument = studio . getInstrumentById ( id ) ;
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Track * track = comp . getTrackById ( comp . getSelectedTrack ( ) ) ;
// Reset the instrument
//
m_instrumentParameterBox - > useInstrument ( instrument ) ;
// Then do this instrument/track fiddling
//
/*
if ( track & & instrument & &
instrument - > getType ( ) = = Instrument : : Audio )
{
// Set the mute status
m_instrumentParameterBox - > setMute ( track - > isMuted ( ) ) ;
// Set the record track
m_instrumentParameterBox - > setRecord (
track - > getId ( ) = = comp . getRecordTrack ( ) ) ;
// Set solo
m_instrumentParameterBox - > setSolo (
comp . isSolo ( ) & & ( track - > getId ( ) = = comp . getSelectedTrack ( ) ) ) ;
}
*/
emit checkTrackAssignments ( ) ;
}
void RosegardenGUIView : : showVisuals ( const MappedEvent * mE )
{
double valueLeft = ( ( double ) mE - > getData1 ( ) ) / 127.0 ;
double valueRight = ( ( double ) mE - > getData2 ( ) ) / 127.0 ;
if ( mE - > getType ( ) = = MappedEvent : : AudioLevel ) {
// Send to the high sensitivity instrument parameter box
// (if any)
//
if ( m_instrumentParameterBox - > getSelectedInstrument ( ) & &
mE - > getInstrument ( ) = =
m_instrumentParameterBox - > getSelectedInstrument ( ) - > getId ( ) ) {
float dBleft = AudioLevel : : fader_to_dB
( mE - > getData1 ( ) , 127 , AudioLevel : : LongFader ) ;
float dBright = AudioLevel : : fader_to_dB
( mE - > getData2 ( ) , 127 , AudioLevel : : LongFader ) ;
m_instrumentParameterBox - > setAudioMeter ( dBleft , dBright ,
AudioLevel : : DB_FLOOR ,
AudioLevel : : DB_FLOOR ) ;
}
// Don't always send all audio levels so we don't
// get vu meter flickering on track meters
//
if ( valueLeft < 0.05 & & valueRight < 0.05 )
return ;
} else if ( mE - > getType ( ) ! = MappedEvent : : MidiNote )
return ;
m_trackEditor - > getTrackButtons ( ) - >
slotSetMetersByInstrument ( ( valueLeft + valueRight ) / 2 ,
mE - > getInstrument ( ) ) ;
}
void
RosegardenGUIView : : updateMeters ( SequencerMapper * mapper )
{
const int unknownState = 0 , oldState = 1 , newState = 2 ;
typedef std : : map < InstrumentId , int > StateMap ;
static StateMap states ;
static StateMap recStates ;
typedef std : : map < InstrumentId , LevelInfo > LevelMap ;
static LevelMap levels ;
static LevelMap recLevels ;
for ( StateMap : : iterator i = states . begin ( ) ; i ! = states . end ( ) ; + + i ) {
i - > second = unknownState ;
}
for ( StateMap : : iterator i = recStates . begin ( ) ; i ! = recStates . end ( ) ; + + i ) {
i - > second = unknownState ;
}
for ( Composition : : trackcontainer : : iterator i =
getDocument ( ) - > getComposition ( ) . getTracks ( ) . begin ( ) ;
i ! = getDocument ( ) - > getComposition ( ) . getTracks ( ) . end ( ) ; + + i ) {
Track * track = i - > second ;
if ( ! track )
continue ;
InstrumentId instrumentId = track - > getInstrument ( ) ;
if ( states [ instrumentId ] = = unknownState ) {
bool isNew = mapper - > getInstrumentLevel ( instrumentId ,
levels [ instrumentId ] ) ;
states [ instrumentId ] = ( isNew ? newState : oldState ) ;
}
if ( recStates [ instrumentId ] = = unknownState ) {
bool isNew = mapper - > getInstrumentRecordLevel ( instrumentId ,
recLevels [ instrumentId ] ) ;
recStates [ instrumentId ] = ( isNew ? newState : oldState ) ;
}
if ( states [ instrumentId ] = = oldState & &
recStates [ instrumentId ] = = oldState )
continue ;
Instrument * instrument =
getDocument ( ) - > getStudio ( ) . getInstrumentById ( instrumentId ) ;
if ( ! instrument )
continue ;
// This records the level of this instrument, not neccessarily
// caused by notes on this particular track.
LevelInfo & info = levels [ instrumentId ] ;
LevelInfo & recInfo = recLevels [ instrumentId ] ;
if ( instrument - > getType ( ) = = Instrument : : Audio | |
instrument - > getType ( ) = = Instrument : : SoftSynth ) {
float dBleft = AudioLevel : : DB_FLOOR ;
float dBright = AudioLevel : : DB_FLOOR ;
float recDBleft = AudioLevel : : DB_FLOOR ;
float recDBright = AudioLevel : : DB_FLOOR ;
bool toSet = false ;
if ( states [ instrumentId ] = = newState & &
( getDocument ( ) - > getSequenceManager ( ) - > getTransporttqStatus ( )
! = STOPPED ) ) {
if ( info . level ! = 0 | | info . levelRight ! = 0 ) {
dBleft = AudioLevel : : fader_to_dB
( info . level , 127 , AudioLevel : : LongFader ) ;
dBright = AudioLevel : : fader_to_dB
( info . levelRight , 127 , AudioLevel : : LongFader ) ;
}
toSet = true ;
m_trackEditor - > getTrackButtons ( ) - > slotSetTrackMeter
( ( info . level + info . levelRight ) / 254.0 , track - > getPosition ( ) ) ;
}
if ( recStates [ instrumentId ] = = newState & &
instrument - > getType ( ) = = Instrument : : Audio & &
( getDocument ( ) - > getSequenceManager ( ) - > getTransporttqStatus ( )
! = PLAYING ) ) {
if ( recInfo . level ! = 0 | | recInfo . levelRight ! = 0 ) {
recDBleft = AudioLevel : : fader_to_dB
( recInfo . level , 127 , AudioLevel : : LongFader ) ;
recDBright = AudioLevel : : fader_to_dB
( recInfo . levelRight , 127 , AudioLevel : : LongFader ) ;
}
toSet = true ;
}
if ( toSet & &
m_instrumentParameterBox - > getSelectedInstrument ( ) & &
instrument - > getId ( ) = =
m_instrumentParameterBox - > getSelectedInstrument ( ) - > getId ( ) ) {
m_instrumentParameterBox - > setAudioMeter ( dBleft , dBright ,
recDBleft , recDBright ) ;
}
} else {
// Not audio or softsynth
if ( info . level = = 0 )
continue ;
if ( getDocument ( ) - > getSequenceManager ( ) - > getTransporttqStatus ( )
! = STOPPED ) {
// The information in 'info' is specific for this instrument, not
// for this track.
//m_trackEditor->getTrackButtons()->slotSetTrackMeter
// (info.level / 127.0, track->getPosition());
m_trackEditor - > getTrackButtons ( ) - > slotSetMetersByInstrument
( info . level / 127.0 , instrumentId ) ;
}
}
}
for ( StateMap : : iterator i = states . begin ( ) ; i ! = states . end ( ) ; + + i ) {
if ( i - > second = = newState ) {
emit instrumentLevelsChanged ( i - > first , levels [ i - > first ] ) ;
}
}
}
void
RosegardenGUIView : : updateMonitorMeters ( SequencerMapper * mapper )
{
Instrument * instrument =
m_instrumentParameterBox - > getSelectedInstrument ( ) ;
if ( ! instrument | |
( instrument - > getType ( ) ! = Instrument : : Audio ) )
return ;
LevelInfo level ;
if ( ! mapper - > getInstrumentRecordLevel ( instrument - > getId ( ) , level ) )
return ;
float dBleft = AudioLevel : : fader_to_dB
( level . level , 127 , AudioLevel : : LongFader ) ;
float dBright = AudioLevel : : fader_to_dB
( level . levelRight , 127 , AudioLevel : : LongFader ) ;
m_instrumentParameterBox - > setAudioMeter
( AudioLevel : : DB_FLOOR , AudioLevel : : DB_FLOOR ,
dBleft , dBright ) ;
}
void
RosegardenGUIView : : slotSelectedSegments ( const SegmentSelection & segments )
{
// update the segment parameter box
m_segmentParameterBox - > useSegments ( segments ) ;
if ( ! segments . empty ( ) ) {
emit stateChange ( " have_selection " , true ) ;
if ( ! segments . hasNonAudioSegment ( ) )
emit stateChange ( " audio_segment_selected " , true ) ;
} else {
emit stateChange ( " have_selection " , false ) ;
}
emit segmentsSelected ( segments ) ;
}
void RosegardenGUIView : : slotShowRulers ( bool v )
{
if ( v ) {
m_trackEditor - > getTopStandardRuler ( ) - > getLoopRuler ( ) - > show ( ) ;
m_trackEditor - > getBottomStandardRuler ( ) - > getLoopRuler ( ) - > show ( ) ;
} else {
m_trackEditor - > getTopStandardRuler ( ) - > getLoopRuler ( ) - > hide ( ) ;
m_trackEditor - > getBottomStandardRuler ( ) - > getLoopRuler ( ) - > hide ( ) ;
}
}
void RosegardenGUIView : : slotShowTempoRuler ( bool v )
{
if ( v ) {
m_trackEditor - > getTempoRuler ( ) - > show ( ) ;
} else {
m_trackEditor - > getTempoRuler ( ) - > hide ( ) ;
}
}
void RosegardenGUIView : : slotShowChordNameRuler ( bool v )
{
if ( v ) {
m_trackEditor - > getChordNameRuler ( ) - > setStudio ( & getDocument ( ) - > getStudio ( ) ) ;
m_trackEditor - > getChordNameRuler ( ) - > show ( ) ;
} else {
m_trackEditor - > getChordNameRuler ( ) - > hide ( ) ;
}
}
void RosegardenGUIView : : slotShowPreviews ( bool v )
{
m_trackEditor - > getSegmentCanvas ( ) - > setShowPreviews ( v ) ;
m_trackEditor - > getSegmentCanvas ( ) - > slotUpdateSegmentsDrawBuffer ( ) ;
}
void RosegardenGUIView : : slotShowSegmentLabels ( bool v )
{
m_trackEditor - > getSegmentCanvas ( ) - > setShowSegmentLabels ( v ) ;
m_trackEditor - > getSegmentCanvas ( ) - > slotUpdateSegmentsDrawBuffer ( ) ;
}
void RosegardenGUIView : : slotAddTracks ( unsigned int nbTracks ,
InstrumentId id , int pos )
{
RG_DEBUG < < " RosegardenGUIView::slotAddTracks( " < < nbTracks < < " , " < < pos < < " ) " < < endl ;
m_trackEditor - > slotAddTracks ( nbTracks , id , pos ) ;
}
void RosegardenGUIView : : slotDeleteTracks (
std : : vector < TrackId > tracks )
{
RG_DEBUG < < " RosegardenGUIView::slotDeleteTracks - "
< < " deleting " < < tracks . size ( ) < < " tracks "
< < endl ;
m_trackEditor - > slotDeleteTracks ( tracks ) ;
}
MultiViewCommandHistory *
RosegardenGUIView : : getCommandHistory ( )
{
return getDocument ( ) - > getCommandHistory ( ) ;
}
void
RosegardenGUIView : : slotAddCommandToHistory ( KCommand * command )
{
getCommandHistory ( ) - > addCommand ( command ) ;
}
void
RosegardenGUIView : : slotChangeInstrumentLabel ( InstrumentId id ,
TQString label )
{
m_trackEditor - > getTrackButtons ( ) - > changeInstrumentLabel ( id , label ) ;
}
void
RosegardenGUIView : : slotChangeTrackLabel ( TrackId id ,
TQString label )
{
m_trackEditor - > getTrackButtons ( ) - > changeTrackLabel ( id , label ) ;
}
void
RosegardenGUIView : : slotAddAudioSegment ( AudioFileId audioId ,
TrackId trackId ,
timeT position ,
const RealTime & startTime ,
const RealTime & endTime )
{
AudioSegmentInsertCommand * command =
new AudioSegmentInsertCommand ( getDocument ( ) ,
trackId ,
position ,
audioId ,
startTime ,
endTime ) ;
slotAddCommandToHistory ( command ) ;
Segment * newSegment = command - > getNewSegment ( ) ;
if ( newSegment ) {
SegmentSelection selection ;
selection . insert ( newSegment ) ;
slotPropagateSegmentSelection ( selection ) ;
emit segmentsSelected ( selection ) ;
}
}
void
RosegardenGUIView : : slotAddAudioSegmentCurrentPosition ( AudioFileId audioFileId ,
const RealTime & startTime ,
const RealTime & endTime )
{
Composition & comp = getDocument ( ) - > getComposition ( ) ;
AudioSegmentInsertCommand * command =
new AudioSegmentInsertCommand ( getDocument ( ) ,
comp . getSelectedTrack ( ) ,
comp . getPosition ( ) ,
audioFileId ,
startTime ,
endTime ) ;
slotAddCommandToHistory ( command ) ;
Segment * newSegment = command - > getNewSegment ( ) ;
if ( newSegment ) {
SegmentSelection selection ;
selection . insert ( newSegment ) ;
slotPropagateSegmentSelection ( selection ) ;
emit segmentsSelected ( selection ) ;
}
}
void
RosegardenGUIView : : slotAddAudioSegmentDefaultPosition ( AudioFileId audioFileId ,
const RealTime & startTime ,
const RealTime & endTime )
{
// Add at current track if it's an audio track, otherwise at first
// empty audio track if there is one, otherwise at first audio track.
// This behaviour should be of no interest to proficient users (who
// should have selected the right track already, or be using drag-
// and-drop) but it should save beginners from inserting an audio
// segment and being quite unable to work out why it won't play
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Studio & studio = getDocument ( ) - > getStudio ( ) ;
TrackId currentTrackId = comp . getSelectedTrack ( ) ;
Track * track = comp . getTrackById ( currentTrackId ) ;
if ( track ) {
InstrumentId ii = track - > getInstrument ( ) ;
Instrument * instrument = studio . getInstrumentById ( ii ) ;
if ( instrument & &
instrument - > getType ( ) = = Instrument : : Audio ) {
slotAddAudioSegment ( audioFileId , currentTrackId ,
comp . getPosition ( ) , startTime , endTime ) ;
return ;
}
}
// current track is not an audio track, find a more suitable one
TrackId bestSoFar = currentTrackId ;
for ( Composition : : trackcontainer : : const_iterator
ti = comp . getTracks ( ) . begin ( ) ;
ti ! = comp . getTracks ( ) . end ( ) ; + + ti ) {
InstrumentId ii = ti - > second - > getInstrument ( ) ;
Instrument * instrument = studio . getInstrumentById ( ii ) ;
if ( instrument & &
instrument - > getType ( ) = = Instrument : : Audio ) {
if ( bestSoFar = = currentTrackId )
bestSoFar = ti - > first ;
bool haveSegment = false ;
for ( Composition : : segmentcontainer : : const_iterator si =
comp . getSegments ( ) . begin ( ) ;
si ! = comp . getSegments ( ) . end ( ) ; + + si ) {
if ( ( * si ) - > getTrack ( ) = = ti - > first ) {
// there's a segment on this track
haveSegment = true ;
break ;
}
}
if ( ! haveSegment ) { // perfect
slotAddAudioSegment ( audioFileId , ti - > first ,
comp . getPosition ( ) , startTime , endTime ) ;
return ;
}
}
}
slotAddAudioSegment ( audioFileId , bestSoFar ,
comp . getPosition ( ) , startTime , endTime ) ;
return ;
}
void
RosegardenGUIView : : slotDroppedNewAudio ( TQString audioDesc )
{
TQTextIStream s ( & audioDesc ) ;
TQString url ;
int trackId ;
timeT time ;
url = s . readLine ( ) ;
s > > trackId ;
s > > time ;
std : : cerr < < " RosegardenGUIView::slotDroppedNewAudio: url " < < url . ascii ( ) < < " , trackId " < < trackId < < " , time " < < time < < std : : endl ;
RosegardenGUIApp * app = RosegardenGUIApp : : self ( ) ;
AudioFileManager & aFM = getDocument ( ) - > getAudioFileManager ( ) ;
AudioFileId audioFileId = 0 ;
int sampleRate = 0 ;
if ( getDocument ( ) - > getSequenceManager ( ) ) {
sampleRate = getDocument ( ) - > getSequenceManager ( ) - > getSampleRate ( ) ;
}
KURL kurl ( url ) ;
if ( ! kurl . isLocalFile ( ) ) {
if ( ! RosegardenGUIApp : : self ( ) - > testAudioPath ( " importing a remote audio file " ) ) return ;
} else if ( aFM . fileNeedsConversion ( qstrtostr ( kurl . path ( ) ) , sampleRate ) ) {
if ( ! RosegardenGUIApp : : self ( ) - > testAudioPath ( " importing an audio file that needs to be converted or resampled " ) ) return ;
}
ProgressDialog progressDlg ( i18n ( " Adding audio file... " ) ,
100 ,
this ) ;
CurrentProgressDialog : : set ( & progressDlg ) ;
progressDlg . progressBar ( ) - > hide ( ) ;
progressDlg . show ( ) ;
// Connect the progress dialog
//
connect ( & aFM , TQT_SIGNAL ( setProgress ( int ) ) ,
progressDlg . progressBar ( ) , TQT_SLOT ( setValue ( int ) ) ) ;
connect ( & aFM , TQT_SIGNAL ( setOperationName ( TQString ) ) ,
& progressDlg , TQT_SLOT ( slotSetOperationName ( TQString ) ) ) ;
connect ( & progressDlg , TQT_SIGNAL ( cancelClicked ( ) ) ,
& aFM , TQT_SLOT ( slotStopImport ( ) ) ) ;
try {
audioFileId = aFM . importURL ( kurl , sampleRate ) ;
} catch ( AudioFileManager : : BadAudioPathException e ) {
CurrentProgressDialog : : freeze ( ) ;
TQString errorString = i18n ( " Can't add dropped file. " ) + strtoqstr ( e . getMessage ( ) ) ;
KMessageBox : : sorry ( this , errorString ) ;
return ;
} catch ( SoundFile : : BadSoundFileException e ) {
CurrentProgressDialog : : freeze ( ) ;
TQString errorString = i18n ( " Can't add dropped file. " ) + strtoqstr ( e . getMessage ( ) ) ;
KMessageBox : : sorry ( this , errorString ) ;
return ;
}
disconnect ( & progressDlg , TQT_SIGNAL ( cancelClicked ( ) ) ,
& aFM , TQT_SLOT ( slotStopImport ( ) ) ) ;
connect ( & progressDlg , TQT_SIGNAL ( cancelClicked ( ) ) ,
& aFM , TQT_SLOT ( slotStopPreview ( ) ) ) ;
progressDlg . progressBar ( ) - > show ( ) ;
progressDlg . slotSetOperationName ( i18n ( " Generating audio preview... " ) ) ;
try {
aFM . generatePreview ( audioFileId ) ;
} catch ( Exception e ) {
CurrentProgressDialog : : freeze ( ) ;
TQString message = strtoqstr ( e . getMessage ( ) ) + " \n \n " +
i18n ( " Try copying this file to a directory where you have write permission and re-add it " ) ;
KMessageBox : : information ( this , message ) ;
//return false;
}
disconnect ( & progressDlg , TQT_SIGNAL ( cancelClicked ( ) ) ,
& aFM , TQT_SLOT ( slotStopPreview ( ) ) ) ;
// add the file at the sequencer
emit addAudioFile ( audioFileId ) ;
// Now fetch file details
//
AudioFile * aF = aFM . getAudioFile ( audioFileId ) ;
if ( aF ) {
slotAddAudioSegment ( audioFileId , trackId , time ,
RealTime ( 0 , 0 ) , aF - > getLength ( ) ) ;
RG_DEBUG < < " RosegardenGUIView::slotDroppedNewAudio( "
< < " file = " < < url
< < " , trackid = " < < trackId
< < " , time = " < < time < < endl ;
}
}
void
RosegardenGUIView : : slotDroppedAudio ( TQString audioDesc )
{
TQTextIStream s ( & audioDesc ) ;
AudioFileId audioFileId ;
TrackId trackId ;
timeT position ;
RealTime startTime , endTime ;
// read the audio info
s > > audioFileId ;
s > > trackId ;
s > > position ;
s > > startTime . sec ;
s > > startTime . nsec ;
s > > endTime . sec ;
s > > endTime . nsec ;
RG_DEBUG < < " RosegardenGUIView::slotDroppedAudio( "
//<< audioDesc
< < " ) : audioFileId = " < < audioFileId
< < " - trackId = " < < trackId
< < " - position = " < < position
< < " - startTime.sec = " < < startTime . sec
< < " - startTime.nsec = " < < startTime . nsec
< < " - endTime.sec = " < < endTime . sec
< < " - endTime.nsec = " < < endTime . nsec
< < endl ;
slotAddAudioSegment ( audioFileId , trackId , position , startTime , endTime ) ;
}
void
RosegardenGUIView : : slotSetMuteButton ( TrackId track , bool value )
{
RG_DEBUG < < " RosegardenGUIView::slotSetMuteButton - track id = " < < track
< < " , value = " < < value < < endl ;
m_trackEditor - > getTrackButtons ( ) - > setMuteButton ( track , value ) ;
Track * trackObj = getDocument ( ) - >
getComposition ( ) . getTrackById ( track ) ;
/*
// to fix 739544
if ( m_instrumentParameterBox - > getSelectedInstrument ( ) & &
m_instrumentParameterBox - > getSelectedInstrument ( ) - > getId ( ) = =
trackObj - > getInstrument ( ) )
{
m_instrumentParameterBox - > setMute ( value ) ;
}
*/
// set the value in the composition
trackObj - > setMuted ( value ) ;
getDocument ( ) - > slotDocumentModified ( ) ; // set the modification flag
}
void
RosegardenGUIView : : slotSetMute ( InstrumentId id , bool value )
{
RG_DEBUG < < " RosegardenGUIView::slotSetMute - "
< < " id = " < < id
< < " ,value = " < < value < < endl ;
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Composition : : trackcontainer & tracks = comp . getTracks ( ) ;
Composition : : trackiterator it ;
for ( it = tracks . begin ( ) ; it ! = tracks . end ( ) ; + + it ) {
if ( ( * it ) . second - > getInstrument ( ) = = id )
slotSetMuteButton ( ( * it ) . second - > getId ( ) , value ) ;
}
}
void
RosegardenGUIView : : slotSetRecord ( InstrumentId id , bool value )
{
RG_DEBUG < < " RosegardenGUIView::slotSetRecord - "
< < " id = " < < id
< < " ,value = " < < value < < endl ;
/*
// IPB
//
m_instrumentParameterBox - > setRecord ( value ) ;
*/
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Composition : : trackcontainer & tracks = comp . getTracks ( ) ;
Composition : : trackiterator it ;
# ifdef NOT_DEFINED
for ( it = tracks . begin ( ) ; it ! = tracks . end ( ) ; + + it ) {
if ( comp . getSelectedTrack ( ) = = ( * it ) . second - > getId ( ) ) {
//!!! MTR m_trackEditor->getTrackButtons()->
// setRecordTrack((*it).second->getPosition());
//!!! MTR is this needed? I think probably not
slotUpdateInstrumentParameterBox ( ( * it ) . second - > getInstrument ( ) ) ;
}
}
# endif
Studio & studio = getDocument ( ) - > getStudio ( ) ;
Instrument * instr = studio . getInstrumentById ( id ) ;
}
void
RosegardenGUIView : : slotSetSolo ( InstrumentId id , bool value )
{
RG_DEBUG < < " RosegardenGUIView::slotSetSolo - "
< < " id = " < < id
< < " ,value = " < < value < < endl ;
emit toggleSolo ( value ) ;
}
void
RosegardenGUIView : : slotUpdateRecordingSegment ( Segment * segment ,
timeT )
{
// We're only interested in this on the first call per recording segment,
// when we possibly create a view for it
static Segment * lastRecordingSegment = 0 ;
if ( segment = = lastRecordingSegment )
return ;
lastRecordingSegment = segment ;
KConfig * config = kapp - > config ( ) ;
config - > setGroup ( GeneralOptionsConfigGroup ) ;
int tracking = config - > readUnsignedNumEntry ( " recordtracking " , 0 ) ;
if ( tracking ! = 1 )
return ;
RG_DEBUG < < " RosegardenGUIView::slotUpdateRecordingSegment: segment is " < < segment < < " , lastRecordingSegment is " < < lastRecordingSegment < < " , opening a new view " < < endl ;
std : : vector < Segment * > segments ;
segments . push_back ( segment ) ;
NotationView * view = createNotationView ( segments ) ;
if ( ! view )
return ;
/* signal no longer exists
TQObject : : connect
( getDocument ( ) , TQT_SIGNAL ( recordingSegmentUpdated ( Segment * , timeT ) ) ,
view , TQT_SLOT ( slotUpdateRecordingSegment ( Segment * , timeT ) ) ) ;
*/
view - > show ( ) ;
}
void
RosegardenGUIView : : slotSynchroniseWithComposition ( )
{
// Track buttons
//
m_trackEditor - > getTrackButtons ( ) - > slotSynchroniseWithComposition ( ) ;
// Update all IPBs
//
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Track * track = comp . getTrackById ( comp . getSelectedTrack ( ) ) ;
slotUpdateInstrumentParameterBox ( track - > getInstrument ( ) ) ;
m_instrumentParameterBox - > slotUpdateAllBoxes ( ) ;
}
void
RosegardenGUIView : : windowActivationChange ( bool )
{
if ( isActiveWindow ( ) ) {
slotActiveMainWindowChanged ( this ) ;
}
}
void
RosegardenGUIView : : slotActiveMainWindowChanged ( const TQWidget * w )
{
m_lastActiveMainWindow = w ;
}
void
RosegardenGUIView : : slotActiveMainWindowChanged ( )
{
const TQWidget * w = dynamic_cast < const TQWidget * > ( sender ( ) ) ;
if ( w )
slotActiveMainWindowChanged ( w ) ;
}
void
RosegardenGUIView : : slotControllerDeviceEventReceived ( MappedEvent * e )
{
RG_DEBUG < < " Controller device event received - send to " < < ( void * ) m_lastActiveMainWindow < < " (I am " < < this < < " ) " < < endl ;
//!!! So, what _should_ we do with these?
// -- external controller that sends e.g. volume control for each
// of a number of channels -> if mixer present, use control to adjust
// tracks on mixer
// -- external controller that sends e.g. separate controllers on
// the same channel for adjusting various parameters -> if IPB
// visible, adjust it. Should we use the channel to select the
// track? maybe as an option
// do we actually need the last active main window for either of
// these? -- yes, to determine whether to send to mixer or to IPB
// in the first place. Send to audio mixer if active, midi mixer
// if active, plugin dialog if active, otherwise keep it for
// ourselves for the IPB. But, we'll do that by having the edit
// views pass it back to us.
// -- then we need to send back out to device.
//!!! special cases: controller 81 received by any window ->
// select window 0->main, 1->audio mix, 2->midi mix
//!!! controller 82 received by main window -> select track
//!!! these obviously should be configurable
if ( e - > getType ( ) = = MappedEvent : : MidiController ) {
if ( e - > getData1 ( ) = = 81 ) {
// select window
int window = e - > getData2 ( ) ;
if ( window < 10 ) { // me
show ( ) ;
raise ( ) ;
setActiveWindow ( ) ;
} else if ( window < 20 ) {
RosegardenGUIApp : : self ( ) - > slotOpenAudioMixer ( ) ;
} else if ( window < 30 ) {
RosegardenGUIApp : : self ( ) - > slotOpenMidiMixer ( ) ;
}
}
}
emit controllerDeviceEventReceived ( e , m_lastActiveMainWindow ) ;
}
void
RosegardenGUIView : : slotControllerDeviceEventReceived ( MappedEvent * e , const void * preferredCustomer )
{
if ( preferredCustomer ! = this )
return ;
RG_DEBUG < < " RosegardenGUIView::slotControllerDeviceEventReceived: this one's for me " < < endl ;
raise ( ) ;
RG_DEBUG < < " Event is type: " < < int ( e - > getType ( ) ) < < " , channel " < < int ( e - > getRecordedChannel ( ) ) < < " , data1 " < < int ( e - > getData1 ( ) ) < < " , data2 " < < int ( e - > getData2 ( ) ) < < endl ;
Composition & comp = getDocument ( ) - > getComposition ( ) ;
Studio & studio = getDocument ( ) - > getStudio ( ) ;
TrackId currentTrackId = comp . getSelectedTrack ( ) ;
Track * track = comp . getTrackById ( currentTrackId ) ;
// If the event is a control change on channel n, then (if
// follow-channel is on) switch to the nth track of the same type
// as the current track -- or the first track of the given
// channel?, and set the control appropriately. Any controls in
// IPB are supported for a MIDI device plus program and bank; only
// volume and pan are supported for audio/synth devices.
//!!! complete this
if ( e - > getType ( ) ! = MappedEvent : : MidiController ) {
if ( e - > getType ( ) = = MappedEvent : : MidiProgramChange ) {
int program = e - > getData1 ( ) ;
if ( ! track )
return ;
InstrumentId ii = track - > getInstrument ( ) ;
Instrument * instrument = studio . getInstrumentById ( ii ) ;
if ( ! instrument )
return ;
instrument - > setProgramChange ( program ) ;
emit instrumentParametersChanged ( ii ) ;
}
return ;
}
unsigned int channel = e - > getRecordedChannel ( ) ;
MidiByte controller = e - > getData1 ( ) ;
MidiByte value = e - > getData2 ( ) ;
if ( controller = = 82 ) { //!!! magic select-track controller
int tracks = comp . getNbTracks ( ) ;
Track * track = comp . getTrackByPosition ( value * tracks / 127 ) ;
if ( track ) {
slotSelectTrackSegments ( track - > getId ( ) ) ;
}
return ;
}
if ( ! track )
return ;
InstrumentId ii = track - > getInstrument ( ) ;
Instrument * instrument = studio . getInstrumentById ( ii ) ;
if ( ! instrument )
return ;
switch ( instrument - > getType ( ) ) {
case Instrument : : Midi : {
MidiDevice * md = dynamic_cast < MidiDevice * >
( instrument - > getDevice ( ) ) ;
if ( ! md ) {
std : : cerr < < " WARNING: MIDI instrument has no MIDI device in slotControllerDeviceEventReceived " < < std : : endl ;
return ;
}
//!!! we need a central clearing house for these changes,
// for a proper mvc structure. reqd for automation post-1.2.
// in the mean time this duplicates much of
// MIDIInstrumentParameterPanel::slotControllerChanged etc
switch ( controller ) {
case MIDI_CONTROLLER_VOLUME :
RG_DEBUG < < " Setting volume for instrument " < < instrument - > getId ( ) < < " to " < < value < < endl ;
instrument - > setVolume ( value ) ;
break ;
case MIDI_CONTROLLER_PAN :
RG_DEBUG < < " Setting pan for instrument " < < instrument - > getId ( ) < < " to " < < value < < endl ;
instrument - > setPan ( value ) ;
break ;
default : {
ControlList cl = md - > getIPBControlParameters ( ) ;
for ( ControlList : : const_iterator i = cl . begin ( ) ;
i ! = cl . end ( ) ; + + i ) {
if ( ( * i ) . getControllerValue ( ) = = controller ) {
RG_DEBUG < < " Setting controller " < < controller < < " for instrument " < < instrument - > getId ( ) < < " to " < < value < < endl ;
instrument - > setControllerValue ( controller , value ) ;
break ;
}
}
break ;
}
}
break ;
}
case Instrument : : SoftSynth :
case Instrument : : Audio :
switch ( controller ) {
case MIDI_CONTROLLER_VOLUME :
RG_DEBUG < < " Setting volume for instrument " < < instrument - > getId ( ) < < " to " < < value < < endl ;
instrument - > setLevel ( AudioLevel : : fader_to_dB
( value , 127 , AudioLevel : : ShortFader ) ) ;
break ;
case MIDI_CONTROLLER_PAN :
RG_DEBUG < < " Setting pan for instrument " < < instrument - > getId ( ) < < " to " < < value < < endl ;
instrument - > setPan ( MidiByte ( ( value / 64.0 ) * 100.0 + 0.01 ) ) ;
break ;
default :
break ;
}
break ;
}
emit instrumentParametersChanged ( instrument - > getId ( ) ) ;
//!!! send out updates via MIDI
}
void
RosegardenGUIView : : initChordNameRuler ( )
{
getTrackEditor ( ) - > getChordNameRuler ( ) - > setReady ( ) ;
}
EventView *
RosegardenGUIView : : createEventView ( std : : vector < Segment * > segmentsToEdit )
{
EventView * eventView = new EventView ( getDocument ( ) ,
segmentsToEdit ,
this ) ;
connect ( eventView , TQT_SIGNAL ( windowActivated ( ) ) ,
this , TQT_SLOT ( slotActiveMainWindowChanged ( ) ) ) ;
connect ( eventView , TQT_SIGNAL ( selectTrack ( int ) ) ,
this , TQT_SLOT ( slotSelectTrackSegments ( int ) ) ) ;
connect ( eventView , TQT_SIGNAL ( saveFile ( ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotFileSave ( ) ) ) ;
connect ( eventView , TQT_SIGNAL ( openInNotation ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsNotation ( std : : vector < Segment * > ) ) ) ;
connect ( eventView , TQT_SIGNAL ( openInMatrix ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsMatrix ( std : : vector < Segment * > ) ) ) ;
connect ( eventView , TQT_SIGNAL ( openInPercussionMatrix ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsPercussionMatrix ( std : : vector < Segment * > ) ) ) ;
connect ( eventView , TQT_SIGNAL ( openInEventList ( std : : vector < Segment * > ) ) ,
this , TQT_SLOT ( slotEditSegmentsEventList ( std : : vector < Segment * > ) ) ) ;
connect ( eventView , TQT_SIGNAL ( editTriggerSegment ( int ) ) ,
this , TQT_SLOT ( slotEditTriggerSegment ( int ) ) ) ;
connect ( this , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
eventView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
connect ( RosegardenGUIApp : : self ( ) , TQT_SIGNAL ( compositionStateUpdate ( ) ) ,
eventView , TQT_SLOT ( slotCompositionStateUpdate ( ) ) ) ;
connect ( eventView , TQT_SIGNAL ( toggleSolo ( bool ) ) ,
RosegardenGUIApp : : self ( ) , TQT_SLOT ( slotToggleSolo ( bool ) ) ) ;
// create keyboard accelerators on view
//
RosegardenGUIApp * par = dynamic_cast < RosegardenGUIApp * > ( parent ( ) ) ;
if ( par ) {
par - > plugAccelerators ( eventView , eventView - > getAccelerators ( ) ) ;
}
return eventView ;
}
}
# include "RosegardenGUIView.moc"