/*
* ClipboardTrackList.java
* Eisenkraut
*
* Copyright (c) 2004-2016 Hanns Holger Rutz. All rights reserved.
*
* This software is published under the GNU General Public License v3+
*
*
* For further information, please contact Hanns Holger Rutz at
* contact@sciss.de
*/
package de.sciss.eisenkraut.session;
import java.awt.EventQueue;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.sciss.eisenkraut.timeline.Track;
import de.sciss.io.Span;
import de.sciss.timebased.Trail;
import de.sciss.util.Disposable;
public class ClipboardTrackList
implements Transferable, ClipboardOwner, Disposable {
private static final boolean DEBUG = false;
public static final DataFlavor trackListFlavor = new DataFlavor( ClipboardTrackList.class, null );
// the items in this map are only removed in disposeAll(), it's therefore
// crucial that disposeAll() is called when a document is closed!
private static final Map<Session, Set<ClipboardTrackList>> mapTrackLists =
new HashMap<Session, Set<ClipboardTrackList>>(); // key = Document, value = Set (element = ClipboardTrackList)
private final static DataFlavor[] flavors = {
trackListFlavor // , AudioFileRegion.flavor
};
private final static DataFlavor[] noFlavors = new DataFlavor[ 0 ];
private final Span span;
private boolean disposed = false;
// key = Class of Trail ; value = Track.Info
private final Map<Class<?>, Track.Info> mapInfos = new HashMap<Class<?>, Track.Info>();
// key = Class of Trail; value = Trail (sub)
private final Map<Class<?>, Trail> mapTrails = new HashMap<Class<?>, Trail>();
public ClipboardTrackList( Session doc )
{
this( doc, doc.timeline.getSelectionSpan(), doc.selectedTracks.getAll() );
}
public ClipboardTrackList( Session doc, Span span, List<SessionObject> tracks )
{
if( !EventQueue.isDispatchThread() ) throw new IllegalMonitorStateException();
this.span = span;
final List<Track.Info> infos = Track.getInfos( tracks, doc.tracks.getAll() );
Trail subTrail;
Set<ClipboardTrackList> setTrackLists;
for (Track.Info ti : infos) {
subTrail = ti.trail.getCutTrail(span, Trail.TOUCH_SPLIT, 0);
mapTrails.put(ti.trail.getClass(), subTrail);
mapInfos .put(ti.trail.getClass(), ti);
}
setTrackLists = mapTrackLists.get(doc);
if (setTrackLists == null) {
setTrackLists = new HashSet<ClipboardTrackList>();
mapTrackLists.put(doc, setTrackLists);
}
setTrackLists.add(this);
if (DEBUG) System.err.println("new : " + hashCode());
}
public Span getSpan()
{
return span;
}
public int getTrackNum(Class<? extends Trail> trailClass) {
final Track.Info ti = mapInfos.get(trailClass);
if (ti == null) return 0;
return ti.numTracks;
}
public boolean[] getTrackMap(Class<?> trailClass) {
final Track.Info ti = mapInfos.get(trailClass);
if (ti == null) return new boolean[0];
return ti.trackMap;
}
public Trail getSubTrail(Class<?> trailClass) {
return (mapTrails.get(trailClass));
}
public void dispose() {
if (DEBUG) System.err.println("dispose : " + hashCode());
if (!EventQueue.isDispatchThread()) throw new IllegalMonitorStateException();
if (disposed) return;
for (Trail trail : mapTrails.values()) {
trail.dispose();
}
mapInfos.clear();
mapTrails.clear();
// final Set setTrackLists = (Set) mapTrackLists.get( doc );
// if( setTrackLists
disposed = true;
}
public static void disposeAll(Session doc) {
if (!EventQueue.isDispatchThread()) throw new IllegalMonitorStateException();
final Set<ClipboardTrackList> setTrackLists = mapTrackLists.remove(doc);
if (setTrackLists != null) {
for (ClipboardTrackList setTrackList : setTrackLists) {
setTrackList.dispose();
}
}
// try {
// final Transferable t = clipboard.getContents( ClipboardTrackList.class );
// if( (t != null) && (t instanceof ClipboardTrackList) ) {
// System.err.println( "yessa." );
// ((ClipboardTrackList) t).dispose();
// return true;
// } else {
// System.err.println( "nopa. t is " + (t == null ? "null" : t.getClass().getName()) );
// return false;
// }
// }
// catch( IllegalStateException e1 ) {
// System.err.println( AbstractApplication.getApplication().getResourceString( "errClipboard" ));
// return false;
// }
}
// ---------------- ClipboardOwner interface ----------------
public void lostOwnership(Clipboard clipboard, Transferable contents) {
dispose();
}
// ---------------- Transferable interface ----------------
public DataFlavor[] getTransferDataFlavors()
{
return disposed ? noFlavors : flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
if (disposed) return false;
for (DataFlavor flavor1 : flavors) {
if (flavor.equals(flavor1)) return true;
}
return false;
}
/**
* Returns the transfer data which is a SampledChunkList
* whose contents is equal to this object's list.
* It's safe to manipulate the returned SampledChunkList.
*
* @param flavor must be <code>trackListFlavor</code>
* @throws UnsupportedFlavorException if the flavor is not <code>trackListFlavor</code>
* @throws IOException when data cannot be transferred
*/
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if (!disposed && flavor.equals(trackListFlavor)) {
return this;
// } else if( flavor.equals( AudioFileRegion.flavor ) && (size() == 1) ) {
// final SampledChunk ts = get( 0 );
// return new AudioFileRegion( ts.f.getFile(), ts.span );
} else {
throw new UnsupportedFlavorException(flavor);
}
}
}