001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.trackimpl;
025:
026: import jacareto.cleverphl.session.Session;
027: import jacareto.record.AudioClipRecordable;
028: import jacareto.record.MediaClipRecordable;
029: import jacareto.record.Record;
030: import jacareto.record.RecordChangeEvent;
031: import jacareto.record.RecordChangeListener;
032: import jacareto.record.RecordException;
033: import jacareto.record.Recordable;
034: import jacareto.record.VectorRecord;
035: import jacareto.record.VideoClipRecordable;
036: import jacareto.record.WindowPropertiesRecordable;
037: import jacareto.starter.Starter;
038: import jacareto.struct.Structure;
039: import jacareto.system.Environment;
040: import jacareto.track.TrackModel;
041: import jacareto.track.TrackModelEvent;
042: import jacareto.track.TrackModelListener;
043: import jacareto.track.block.Block;
044: import jacareto.track.block.BlockType;
045: import jacareto.trackimpl.blockimpl.AudioBlock;
046: import jacareto.trackimpl.blockimpl.DefaultBlock;
047: import jacareto.trackimpl.blockimpl.VideoBlock;
048:
049: import org.apache.commons.lang.Validate;
050:
051: import java.util.List;
052:
053: import javax.swing.event.TreeModelEvent;
054: import javax.swing.event.TreeModelListener;
055:
056: /**
057: * <p>
058: * Connects the DataModel of Jacareto with the Synchronizer TrackModel (and eevntually SyncModel).
059: * </p>
060: *
061: * <p>
062: * Just listens for data changes and informs the data models.
063: * </p>
064: *
065: * @author Oliver Specht
066: * @version $revision$
067: */
068: public class DataModelConnector {
069: /** The current session to be displayed */
070: Session session;
071:
072: /** The Structure of the session */
073: Structure structure;
074:
075: /** The Record of the session */
076: Record record;
077:
078: /** The current TrackModel */
079: TrackModel trackModel;
080:
081: /** The RecordChangeListener */
082: RecordChangeListener recordChangeListener;
083:
084: /** The StructureChangeListener */
085: TreeModelListener treeModelListener;
086:
087: /** The TrackSelectionListener which is switched on and off */
088: TrackModelListener trackModelListener;
089:
090: /** The Environment to set to RecordStructureCompound if record has changed */
091: Environment env;
092:
093: /**
094: * Creates a new SelectionModelConnector. Connects the {@link TrackModel} with the {@link
095: * Record} from the given {@link Session}.
096: *
097: * @param trackModel {@link TrackModel} to connect
098: * @param session {@link Session} which has to be connected
099: */
100: private DataModelConnector(TrackModel trackModel, Session session) {
101: // init
102: this .recordChangeListener = new RecordChangeListenerAdapter();
103: this .treeModelListener = new TreeModelListenerAdapter();
104: this .trackModelListener = new TrackModelListenerAdapter();
105:
106: this .trackModel = trackModel;
107: this .session = session;
108: this .record = this .session.getRecord();
109: this .structure = this .session.getStructure();
110:
111: this .trackModel.addTrackModelListener(this .trackModelListener);
112: this .record.addRecordChangeListener(this .recordChangeListener);
113: this .structure.addTreeModelListener(this .treeModelListener);
114: }
115:
116: /**
117: * Reinitializes the Connector with the given {@link Session} and {@link TrackModel}.
118: *
119: * @param session {@link Session}
120: * @param trackModel {@link TrackModel} to be used
121: */
122: public void reInit(Session session, TrackModel trackModel) {
123: this .session = session;
124: this .record = this .session.getRecord();
125: this .structure = this .session.getStructure();
126: this .trackModel = trackModel;
127:
128: this .trackModel.addTrackModelListener(this .trackModelListener);
129: this .record.addRecordChangeListener(this .recordChangeListener);
130: this .structure.addTreeModelListener(this .treeModelListener);
131: }
132:
133: /**
134: * Creates a new SelectionModelConnector
135: *
136: * @param trackModel {@link TrackModel}
137: * @param session {@link Session}
138: *
139: * @return SelectionModelConnector
140: */
141: public static DataModelConnector create(TrackModel trackModel,
142: Session session) {
143: return new DataModelConnector(trackModel, session);
144: }
145:
146: /**
147: * Sets the Environment to create a RecordStructureCompund
148: *
149: * @param env
150: */
151: public void setEnvironment(Environment env) {
152: this .env = env;
153: }
154:
155: private void changeAlignment(Block block) {
156: Validate.notNull(block);
157: Validate
158: .isTrue(((block.getType().equals(BlockType.AUDIO)) || (block
159: .getType().equals(BlockType.VIDEO))));
160:
161: Recordable alignedToRecordable = ((DefaultBlock) this .trackModel
162: .getAlignedToBlock(block)).getRecordable();
163:
164: if (block.getType().equals(BlockType.AUDIO)) {
165: AudioClipRecordable alignedRecordable = (AudioClipRecordable) ((AudioBlock) block)
166: .getRecordable();
167: alignedRecordable.setAlignedTo(alignedToRecordable);
168: } else if (block.getType().equals(BlockType.VIDEO)) {
169: VideoClipRecordable alignedRecordable = (VideoClipRecordable) ((VideoBlock) block)
170: .getRecordable();
171: alignedRecordable.setAlignedTo(alignedToRecordable);
172: }
173: }
174:
175: /**
176: * Reinitializes the TrackModel with the actual record from the StructureTree
177: */
178: private void reinitTrackModel() {
179: this .trackModel
180: .removeTrackModelListener(this .trackModelListener);
181: ((DefaultTrackModel) this .trackModel).reInit(this .session
182: .getRecord());
183: this .trackModel.addTrackModelListener(this .trackModelListener);
184: }
185:
186: /**
187: * Reinitializes the record.
188: *
189: * @param event {@link TrackModelEvent}
190: */
191: private void reinitRecord(TrackModelEvent event) {
192: Validate.notNull(event, "DMC.reinitRecord(): Event is null!");
193: Validate
194: .notNull(event.getChangedBlock(),
195: "DMC.reinitRecord(): changedBlock in TrackModelEvent is null!");
196:
197: this .record
198: .removeRecordChangeListener(this .recordChangeListener);
199: this .structure.removeTreeModelListener(this .treeModelListener);
200:
201: Recordable changedRecordable = ((DefaultBlock) event
202: .getChangedBlock()).getRecordable();
203:
204: // remove recordable from record
205: try {
206: ((VectorRecord) this .record).remove(changedRecordable);
207: } catch (RecordException e) {
208: e.printStackTrace();
209: }
210:
211: // get recordable to insert after
212: List blocks = this .trackModel.getBlocksInRange(null, 0,
213: this .trackModel.getEndTime(), true);
214: int position = 0;
215:
216: for (int i = 0; i < blocks.size(); i++) {
217: if (((DefaultBlock) blocks.get(i)).getRecordable().equals(
218: changedRecordable)) {
219: position = i;
220:
221: break;
222: }
223: }
224:
225: // insert recordable at new position
226: try {
227: ((VectorRecord) this .record).insert(changedRecordable,
228: position);
229: } catch (RecordException e1) {
230: e1.printStackTrace();
231: }
232:
233: this .session.restructureRecord();
234: this .record.addRecordChangeListener(this .recordChangeListener);
235: this .structure.addTreeModelListener(this .treeModelListener);
236: }
237:
238: private class TreeModelListenerAdapter implements TreeModelListener {
239: //~ Methods --------------------------------------------------------------------------------
240:
241: /**
242: * Is called everytime a tree node "changes", but does not imply change of the object
243: * itself so ignore this event!!!
244: *
245: * @param event TreeModelEvent
246: */
247: public void treeNodesChanged(TreeModelEvent event) {
248: }
249:
250: /**
251: * <p>
252: * Called when new tree nodes have been inserted.
253: * </p>
254: *
255: * <p>
256: * Important for the TrackModel so inform it.
257: * </p>
258: *
259: * @param event TreeModelEvent
260: */
261: public void treeNodesInserted(TreeModelEvent event) {
262: // reinitTrackModel ();
263: }
264:
265: /**
266: * Called when new tree nodes have been removed. Important for the TrackModel so inform
267: * it.
268: *
269: * @param event TreeModelEvent
270: */
271: public void treeNodesRemoved(TreeModelEvent event) {
272: reinitTrackModel();
273: }
274:
275: /**
276: * Called when the whole tree structure has changed Important for the TrackModel so inform
277: * it.
278: *
279: * @param event TreeModelEvent
280: */
281: public void treeStructureChanged(TreeModelEvent event) {
282: reinitTrackModel();
283: }
284: }
285:
286: private class RecordChangeListenerAdapter implements
287: RecordChangeListener {
288: //~ Methods --------------------------------------------------------------------------------
289:
290: /**
291: * {@inheritDoc}
292: */
293: public void recordHasChanged(RecordChangeEvent event) {
294: // !!! Attention !!! RECORDABLES_CHANGED is called when StructureElementEvent is thrown
295: if (event.getID() == RecordChangeEvent.RECORDABLES_CHANGED) {
296: Recordable[] recordables = event.getRecordables();
297:
298: if (recordables != null) {
299: if (recordables[0] instanceof MediaClipRecordable) {
300: if (recordables[0] instanceof VideoClipRecordable) {
301: ;
302: }
303:
304: reinitTrackModel();
305: }
306: }
307: } else if (event.getID() == RecordChangeEvent.RECORD_OPENED) {
308: ;
309: } else if (event.getID() == RecordChangeEvent.RECORDABLES_ADDED) {
310: Recordable[] recordables = event.getRecordables();
311:
312: if (recordables != null) {
313: // SIMPLE WORKAROUND. SHOULD BE CHANGED
314: // Dieser Fall wird nur behandelt, wenn Adds ausgefuehrt werden ausserhalb des Aufzeichnens
315: // Ansonsten sinds inserts (siehe unten)
316: // Das geht schief, wenn noch mehr solche Faelle dazukommen
317: // Diese Instanz sollte eigentlich informiert werden, wenn sie nach ADDS lauschen soll
318: // und wann nicht (beispielsweise sollte sie beim Start einer Aufzeichnung informiert
319: // werden, nicht zu hoeren, und am Ende der Aufzeichnung schon. Das Update am Ende
320: // einer Aufzeichnung uebernimmt der TrackModelEditor. Dieser ruft die reinit-Methode
321: // des DataModelConnectors auf.)
322: if ((recordables[0] instanceof Starter)
323: || (recordables[0] instanceof WindowPropertiesRecordable)) {
324: reinitTrackModel();
325: }
326: }
327:
328: ;
329: } else if (event.getID() == RecordChangeEvent.RECORDABLES_CHANGED) {
330: ;
331: } else if (event.getID() == RecordChangeEvent.RECORDABLES_INSERTED) {
332: reinitTrackModel();
333: } else if (event.getID() == RecordChangeEvent.RECORDABLES_REMOVED) {
334: ;
335: } else if (event.getID() == RecordChangeEvent.RECORD_RESETTED) {
336: ;
337: }
338: }
339: }
340:
341: private class TrackModelListenerAdapter implements
342: TrackModelListener {
343: //~ Methods --------------------------------------------------------------------------------
344:
345: /**
346: * <p>
347: * The start time of a {@link jacareto.track.block.Block} in the {@link TrackModel} has
348: * changed, so restructure the record.
349: * </p>
350: *
351: * <p>
352: * This method is only called, if a block has been dragged and dropped.
353: * </p>
354: *
355: * @param event {@link TrackModelEvent}
356: */
357: public void blockTimeChanged(TrackModelEvent event) {
358: reinitRecord(event);
359: }
360:
361: /**
362: * Called when a block has been aligned.
363: *
364: * @param event {@link TrackModelEvent}
365: */
366: public void blockAlignmentChanged(TrackModelEvent event) {
367: changeAlignment(event.getChangedBlock());
368: }
369:
370: /**
371: * Not yet implemented. TrackViewPanel does not (yet) provide functionality for removing
372: * blocks.
373: *
374: * @param event {@link TrackModelEvent}
375: */
376: public void blockRemoved(TrackModelEvent event) {
377: }
378:
379: /**
380: * Not yet implemented. TrackViewPanel does not (yet) provide functionality for adding
381: * blocks.
382: *
383: * @param event {@link TrackModelEvent}
384: */
385: public void blockAdded(TrackModelEvent event) {
386: }
387:
388: /**
389: * Doesn't do anything. This method is only called, if the track model has been
390: * reinitialized.
391: *
392: * @param event {@link TrackModelEvent}
393: */
394: public void trackModelChanged(TrackModelEvent event) {
395: }
396: }
397: }
|