/*
* Jacareto Copyright (c) 2002-2005
* Applied Computer Science Research Group, Darmstadt University of
* Technology, Institute of Mathematics & Computer Science,
* Ludwigsburg University of Education, and Computer Based
* Learning Research Group, Aachen University. All rights reserved.
*
* Jacareto 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.
*
* Jacareto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with Jacareto; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
package jacareto.trackimpl;
import jacareto.cleverphl.session.Session;
import jacareto.record.AudioClipRecordable;
import jacareto.record.MediaClipRecordable;
import jacareto.record.Record;
import jacareto.record.RecordChangeEvent;
import jacareto.record.RecordChangeListener;
import jacareto.record.RecordException;
import jacareto.record.Recordable;
import jacareto.record.VectorRecord;
import jacareto.record.VideoClipRecordable;
import jacareto.record.WindowPropertiesRecordable;
import jacareto.starter.Starter;
import jacareto.struct.Structure;
import jacareto.system.Environment;
import jacareto.track.TrackModel;
import jacareto.track.TrackModelEvent;
import jacareto.track.TrackModelListener;
import jacareto.track.block.Block;
import jacareto.track.block.BlockType;
import jacareto.trackimpl.blockimpl.AudioBlock;
import jacareto.trackimpl.blockimpl.DefaultBlock;
import jacareto.trackimpl.blockimpl.VideoBlock;
import org.apache.commons.lang.Validate;
import java.util.List;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
/**
* <p>
* Connects the DataModel of Jacareto with the Synchronizer TrackModel (and eevntually SyncModel).
* </p>
*
* <p>
* Just listens for data changes and informs the data models.
* </p>
*
* @author Oliver Specht
* @version $revision$
*/
public class DataModelConnector {
/** The current session to be displayed */
Session session;
/** The Structure of the session */
Structure structure;
/** The Record of the session */
Record record;
/** The current TrackModel */
TrackModel trackModel;
/** The RecordChangeListener */
RecordChangeListener recordChangeListener;
/** The StructureChangeListener */
TreeModelListener treeModelListener;
/** The TrackSelectionListener which is switched on and off */
TrackModelListener trackModelListener;
/** The Environment to set to RecordStructureCompound if record has changed */
Environment env;
/**
* Creates a new SelectionModelConnector. Connects the {@link TrackModel} with the {@link
* Record} from the given {@link Session}.
*
* @param trackModel {@link TrackModel} to connect
* @param session {@link Session} which has to be connected
*/
private DataModelConnector (TrackModel trackModel, Session session) {
// init
this.recordChangeListener = new RecordChangeListenerAdapter();
this.treeModelListener = new TreeModelListenerAdapter();
this.trackModelListener = new TrackModelListenerAdapter();
this.trackModel = trackModel;
this.session = session;
this.record = this.session.getRecord ();
this.structure = this.session.getStructure ();
this.trackModel.addTrackModelListener (this.trackModelListener);
this.record.addRecordChangeListener (this.recordChangeListener);
this.structure.addTreeModelListener (this.treeModelListener);
}
/**
* Reinitializes the Connector with the given {@link Session} and {@link TrackModel}.
*
* @param session {@link Session}
* @param trackModel {@link TrackModel} to be used
*/
public void reInit (Session session, TrackModel trackModel) {
this.session = session;
this.record = this.session.getRecord ();
this.structure = this.session.getStructure ();
this.trackModel = trackModel;
this.trackModel.addTrackModelListener (this.trackModelListener);
this.record.addRecordChangeListener (this.recordChangeListener);
this.structure.addTreeModelListener (this.treeModelListener);
}
/**
* Creates a new SelectionModelConnector
*
* @param trackModel {@link TrackModel}
* @param session {@link Session}
*
* @return SelectionModelConnector
*/
public static DataModelConnector create (TrackModel trackModel, Session session) {
return new DataModelConnector(trackModel, session);
}
/**
* Sets the Environment to create a RecordStructureCompund
*
* @param env
*/
public void setEnvironment (Environment env) {
this.env = env;
}
private void changeAlignment (Block block) {
Validate.notNull (block);
Validate.isTrue (((block.getType ().equals (BlockType.AUDIO)) ||
(block.getType ().equals (BlockType.VIDEO))));
Recordable alignedToRecordable = ((DefaultBlock) this.trackModel.getAlignedToBlock (block)).getRecordable ();
if (block.getType ().equals (BlockType.AUDIO)) {
AudioClipRecordable alignedRecordable = (AudioClipRecordable) ((AudioBlock) block).getRecordable ();
alignedRecordable.setAlignedTo (alignedToRecordable);
} else if (block.getType ().equals (BlockType.VIDEO)) {
VideoClipRecordable alignedRecordable = (VideoClipRecordable) ((VideoBlock) block).getRecordable ();
alignedRecordable.setAlignedTo (alignedToRecordable);
}
}
/**
* Reinitializes the TrackModel with the actual record from the StructureTree
*/
private void reinitTrackModel () {
this.trackModel.removeTrackModelListener (this.trackModelListener);
((DefaultTrackModel) this.trackModel).reInit (this.session.getRecord ());
this.trackModel.addTrackModelListener (this.trackModelListener);
}
/**
* Reinitializes the record.
*
* @param event {@link TrackModelEvent}
*/
private void reinitRecord (TrackModelEvent event) {
Validate.notNull (event, "DMC.reinitRecord(): Event is null!");
Validate.notNull (event.getChangedBlock (),
"DMC.reinitRecord(): changedBlock in TrackModelEvent is null!");
this.record.removeRecordChangeListener (this.recordChangeListener);
this.structure.removeTreeModelListener (this.treeModelListener);
Recordable changedRecordable = ((DefaultBlock) event.getChangedBlock ()).getRecordable ();
// remove recordable from record
try {
((VectorRecord) this.record).remove (changedRecordable);
} catch (RecordException e) {
e.printStackTrace ();
}
// get recordable to insert after
List blocks = this.trackModel.getBlocksInRange (null, 0, this.trackModel.getEndTime (), true);
int position = 0;
for (int i = 0; i < blocks.size (); i++) {
if (((DefaultBlock) blocks.get (i)).getRecordable ().equals (changedRecordable)) {
position = i;
break;
}
}
// insert recordable at new position
try {
((VectorRecord) this.record).insert (changedRecordable, position);
} catch (RecordException e1) {
e1.printStackTrace ();
}
this.session.restructureRecord ();
this.record.addRecordChangeListener (this.recordChangeListener);
this.structure.addTreeModelListener (this.treeModelListener);
}
private class TreeModelListenerAdapter implements TreeModelListener {
//~ Methods --------------------------------------------------------------------------------
/**
* Is called everytime a tree node "changes", but does not imply change of the object
* itself so ignore this event!!!
*
* @param event TreeModelEvent
*/
public void treeNodesChanged (TreeModelEvent event) {
}
/**
* <p>
* Called when new tree nodes have been inserted.
* </p>
*
* <p>
* Important for the TrackModel so inform it.
* </p>
*
* @param event TreeModelEvent
*/
public void treeNodesInserted (TreeModelEvent event) {
// reinitTrackModel ();
}
/**
* Called when new tree nodes have been removed. Important for the TrackModel so inform
* it.
*
* @param event TreeModelEvent
*/
public void treeNodesRemoved (TreeModelEvent event) {
reinitTrackModel ();
}
/**
* Called when the whole tree structure has changed Important for the TrackModel so inform
* it.
*
* @param event TreeModelEvent
*/
public void treeStructureChanged (TreeModelEvent event) {
reinitTrackModel ();
}
}
private class RecordChangeListenerAdapter implements RecordChangeListener {
//~ Methods --------------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public void recordHasChanged (RecordChangeEvent event) {
// !!! Attention !!! RECORDABLES_CHANGED is called when StructureElementEvent is thrown
if (event.getID () == RecordChangeEvent.RECORDABLES_CHANGED) {
Recordable[] recordables = event.getRecordables ();
if (recordables != null) {
if (recordables[0] instanceof MediaClipRecordable) {
if (recordables[0] instanceof VideoClipRecordable) {
;
}
reinitTrackModel ();
}
}
} else if (event.getID () == RecordChangeEvent.RECORD_OPENED) {
;
} else if (event.getID () == RecordChangeEvent.RECORDABLES_ADDED) {
Recordable[] recordables = event.getRecordables ();
if (recordables != null) {
// SIMPLE WORKAROUND. SHOULD BE CHANGED
// Dieser Fall wird nur behandelt, wenn Adds ausgefuehrt werden ausserhalb des Aufzeichnens
// Ansonsten sinds inserts (siehe unten)
// Das geht schief, wenn noch mehr solche Faelle dazukommen
// Diese Instanz sollte eigentlich informiert werden, wenn sie nach ADDS lauschen soll
// und wann nicht (beispielsweise sollte sie beim Start einer Aufzeichnung informiert
// werden, nicht zu hoeren, und am Ende der Aufzeichnung schon. Das Update am Ende
// einer Aufzeichnung uebernimmt der TrackModelEditor. Dieser ruft die reinit-Methode
// des DataModelConnectors auf.)
if ((recordables[0] instanceof Starter) ||
(recordables[0] instanceof WindowPropertiesRecordable)) {
reinitTrackModel ();
}
}
;
} else if (event.getID () == RecordChangeEvent.RECORDABLES_CHANGED) {
;
} else if (event.getID () == RecordChangeEvent.RECORDABLES_INSERTED) {
reinitTrackModel ();
} else if (event.getID () == RecordChangeEvent.RECORDABLES_REMOVED) {
;
} else if (event.getID () == RecordChangeEvent.RECORD_RESETTED) {
;
}
}
}
private class TrackModelListenerAdapter implements TrackModelListener {
//~ Methods --------------------------------------------------------------------------------
/**
* <p>
* The start time of a {@link jacareto.track.block.Block} in the {@link TrackModel} has
* changed, so restructure the record.
* </p>
*
* <p>
* This method is only called, if a block has been dragged and dropped.
* </p>
*
* @param event {@link TrackModelEvent}
*/
public void blockTimeChanged (TrackModelEvent event) {
reinitRecord (event);
}
/**
* Called when a block has been aligned.
*
* @param event {@link TrackModelEvent}
*/
public void blockAlignmentChanged (TrackModelEvent event) {
changeAlignment (event.getChangedBlock ());
}
/**
* Not yet implemented. TrackViewPanel does not (yet) provide functionality for removing
* blocks.
*
* @param event {@link TrackModelEvent}
*/
public void blockRemoved (TrackModelEvent event) {
}
/**
* Not yet implemented. TrackViewPanel does not (yet) provide functionality for adding
* blocks.
*
* @param event {@link TrackModelEvent}
*/
public void blockAdded (TrackModelEvent event) {
}
/**
* Doesn't do anything. This method is only called, if the track model has been
* reinitialized.
*
* @param event {@link TrackModelEvent}
*/
public void trackModelChanged (TrackModelEvent event) {
}
}
}
|