{
if( !checkProcess() ) return null;
if( (insertPos < 0) || (insertPos > timeline.getLength()) ) throw new IllegalArgumentException( String.valueOf( insertPos ));
final ProcessingThread proc;
final Span oldSelSpan, insertSpan, copySpan, cutTimelineSpan;
final AbstractCompoundEdit edit;
final Flag hasSelectedAudio;
final List tis;
final boolean expTimeline, cutTimeline;
final long docLength, pasteLength, preMaxLen, postMaxLen;
final BlendContext bcPre, bcPost;
hasSelectedAudio = new Flag( false );
tis = Track.getInfos( selectedTracks.getAll(), tracks.getAll() );
if( !AudioTracks.checkSyncedAudio( tis, mode == EDIT_INSERT, null, hasSelectedAudio )) return null;
expTimeline = (mode == EDIT_INSERT) && hasSelectedAudio.isSet();
docLength = timeline.getLength();
pasteLength = expTimeline ? tl.getSpan().getLength() :
Math.min( tl.getSpan().getLength(), docLength - insertPos );
if( pasteLength == 0 ) return null;
if( mode == EDIT_INSERT ) {
/*
* before paste:
*
* maxRight / post maxLeft / pre
*
* | | |
* | | |
* | | |
* | A | B |
* +-----------------+--------------+
* |
* insertPos
*
* after paste:
*
* | | B #$$$$# A | |
* | | ##$$$$## | |
* | | ###$$$$### | |
* | A |####$$$$####| B |
* +-----------------+------------+--------------+
* |
* insertPos
*/
// note: now the discrepancy between postMaxLen and preMaxLen is
// limited to 100%, so pasting at the very end or beginning of
// a doc will not produce a single sided xfade any more
// (answering bug 1922862)
if( insertPos < (docLength - insertPos) ) {
postMaxLen = Math.min( insertPos, pasteLength >> 1 );
// preMaxLen = Math.min( docLength - insertPos, pasteLength - postMaxLen );
preMaxLen = Math.min( postMaxLen << 1, Math.min( docLength - insertPos, pasteLength - postMaxLen ));
//System.out.println( "A" );
} else {
preMaxLen = Math.min( docLength - insertPos, pasteLength >> 1 );
postMaxLen = Math.min( preMaxLen << 1, Math.min( insertPos, pasteLength - preMaxLen ));
//System.out.println( "B" );
}
} else {
preMaxLen = pasteLength >> 1; // note: pasteLength already clipped to be <= docLength - insertPos !
postMaxLen = pasteLength - preMaxLen;
//System.out.println( "C" );
}
bcPre = createBlendContext( preMaxLen, 0, hasSelectedAudio.isSet() );
bcPost = createBlendContext( postMaxLen, 0, hasSelectedAudio.isSet() );
//System.out.println( "D ; preMaxLen = " + preMaxLen + "; postMaxLen = " + postMaxLen + "; bcPre.getLeftLen() = " + (bcPre == null ? null : String.valueOf( bcPre.getLeftLen())) + "; bcPre.getRightLen() = " + (bcPre == null ? null : String.valueOf( bcPre.getRightLen() )) + "; bcPost.getLeftLen() = " + (bcPost == null ? null : String.valueOf( bcPost.getLeftLen() )) + "; bcPost.getRightLen() = " + (bcPost == null ? null : String.valueOf( bcPost.getRightLen() )));
// if( bcPre != null ) System.out.println( "bcPre : " + bcPre.getLen() + ", " + bcPre.getLeftLen() + ", "+ bcPre.getRightLen() );
// if( bcPost != null ) System.out.println( "bcPost : " + bcPost.getLen() + ", " + bcPost.getLeftLen() + ", "+ bcPost.getRightLen() );
insertSpan = new Span( insertPos, insertPos + pasteLength );
copySpan = new Span( tl.getSpan().start, tl.getSpan().start + pasteLength );
cutTimeline = (mode == EDIT_INSERT) && !hasSelectedAudio.isSet();
cutTimelineSpan = cutTimeline ? new Span( docLength, docLength + pasteLength ) : null;
edit = new BasicCompoundEdit( procName );
oldSelSpan = timeline.getSelectionSpan();
if( !oldSelSpan.isEmpty() ) { // deselect
edit.addPerform( TimelineVisualEdit.select( this, Session.this, new Span() ));
}
proc = new ProcessingThread( this, getFrame(), procName );
proc.putClientArg( "tl", tl );
proc.putClientArg( "pos", new Long( insertPos ));
proc.putClientArg( "mode", new Integer( mode ));
proc.putClientArg( "tis", tis );
proc.putClientArg( "pasteLen", new Long( pasteLength ));
proc.putClientArg( "exp", new Boolean( expTimeline ));
proc.putClientArg( "bcPre", bcPre );
proc.putClientArg( "bcPost", bcPost );
proc.putClientArg( "insertSpan", insertSpan );
proc.putClientArg( "copySpan", copySpan );
proc.putClientArg( "cut", new Boolean( cutTimeline ));
proc.putClientArg( "cutSpan", cutTimelineSpan );
proc.putClientArg( "edit", edit );
return proc;
}