diff --git a/timeline/src/Audio_Sequence.C b/timeline/src/Audio_Sequence.C index 8f21b0b..f8dddd5 100644 --- a/timeline/src/Audio_Sequence.C +++ b/timeline/src/Audio_Sequence.C @@ -253,6 +253,95 @@ Audio_Sequence::draw ( void ) fl_pop_clip(); } +int +Audio_Sequence::handle_paste ( const char *text ) +{ + int X = Fl::event_x(); + + if ( ! strcmp( text, "Audio_Region" ) ) + return 1; + + char *file; + + if ( ! sscanf( text, "file://%m[^\r\n]\n", &file ) ) + { + WARNING( "invalid drop \"%s\"\n", text ); + return 0; + } + + unescape_url( file ); + + printf( "pasted file \"%s\"\n", file ); + + fl_cursor( FL_CURSOR_WAIT ); + Fl::check(); + + char *t = strdup( file ); + + char *filebase = strdup( basename( t ) ); + + free( t ); + + char *s = 0; + + int i = 0; + + for ( ; ; i++ ) + { + if ( i ) + { + free( s ); + asprintf( &s, "sources/%s-%i", filebase, i ); + } + else + asprintf( &s, "sources/%s", filebase ); + + DMESSAGE( "Symlink %s -> %s", file, s ); + if ( symlink( file, s ) == 0 ) + break; + + if ( errno != EEXIST ) + { + WARNING( "Failed to create symlink: %s", strerror( errno ) ); + break; + } + } + + Audio_File *c = Audio_File::from_file( basename( s ) ); + + free( s ); + free( filebase ); + + fl_cursor( FL_CURSOR_DEFAULT ); + Fl::check(); + + if ( ! c || c->dummy() ) + { + fl_alert( "Could not import file \"%s\"", file ); + free( file ); + + if ( c ) + { + delete c; + c = NULL; + } + + return 0; + } + + free( file ); + + Audio_Region *r = + new Audio_Region( c, this, timeline->xoffset + timeline->x_to_ts( X - drawable_x() ) ); + + r->log_create(); + + redraw(); + + return 1; + +} + /** event handler that supports DND of audio clips */ int Audio_Sequence::handle ( int m ) @@ -261,91 +350,15 @@ Audio_Sequence::handle ( int m ) { case FL_PASTE: { - if ( ! Fl::event_inside( this ) ) - return 0; - const char *text = Fl::event_text(); - - if ( ! strcmp( text, "Audio_Region" ) ) - return 1; - - char *file; - - if ( ! sscanf( text, "file://%a[^\r\n]\n", &file ) ) - { - WARNING( "invalid drop \"%s\"\n", text ); - return 0; - } - - unescape_url( file ); - - printf( "pasted file \"%s\"\n", file ); - - fl_cursor( FL_CURSOR_WAIT ); - Fl::check(); - - char *t = strdup( file ); - - char *filebase = strdup( basename( t ) ); - - free( t ); - - char *s = 0; - - int i = 0; - - for ( ; ; i++ ) - { - if ( i ) - { - free( s ); - asprintf( &s, "sources/%s-%i", filebase, i ); - } - else - asprintf( &s, "sources/%s", filebase ); - - DMESSAGE( "Symlink %s -> %s", file, s ); - if ( symlink( file, s ) == 0 ) - break; + DMESSAGE("Got sequence paste"); - if ( errno != EEXIST ) - { - WARNING( "Failed to create symlink: %s", strerror( errno ) ); - break; - } - } - - Audio_File *c = Audio_File::from_file( basename( s ) ); - - free( s ); - free( filebase ); - - fl_cursor( FL_CURSOR_DEFAULT ); - Fl::check(); - - if ( ! c || c->dummy() ) + if ( ! Fl::event_inside( this ) ) { - fl_alert( "Could not import file \"%s\"", file ); - free( file ); - - if ( c ) - { - delete c; - c = NULL; - } - + DMESSAGE("ignoring"); return 0; } - free( file ); - - Audio_Region *r = - new Audio_Region( c, this, timeline->xoffset + timeline->x_to_ts( Fl::event_x() - drawable_x() ) ); - - r->log_create(); - - redraw(); - - return 1; + return handle_paste(Fl::event_text()); } default: return Sequence::handle( m ); diff --git a/timeline/src/Audio_Sequence.H b/timeline/src/Audio_Sequence.H index 62c2646..756144a 100644 --- a/timeline/src/Audio_Sequence.H +++ b/timeline/src/Audio_Sequence.H @@ -51,6 +51,8 @@ protected: public: + int handle_paste ( const char *text ); + int handle ( int m ); LOG_CREATE_FUNC( Audio_Sequence ); diff --git a/timeline/src/Timeline.C b/timeline/src/Timeline.C index cf7e073..ccde2a1 100644 --- a/timeline/src/Timeline.C +++ b/timeline/src/Timeline.C @@ -30,6 +30,7 @@ #include #include #include +#include #include "Timeline.H" #include "Tempo_Sequence.H" @@ -373,6 +374,9 @@ Timeline::add_take_for_armed_tracks ( void ) track_lock.unlock(); } +/* coordinates of mouse at time context menu is brought up. */ +static int menu_event_x = 0; +static int menu_event_y = 0; void Timeline::menu_cb ( Fl_Menu_ *m ) { @@ -570,6 +574,31 @@ Timeline::menu_cb ( Fl_Menu_ *m ) { redraw(); } + else if ( ! strcmp( picked, "Import source at mouse" ) ) + { + Fl::e_x = menu_event_x; + Fl::e_y = menu_event_y; + + Track *t = Timeline::event_inside(); + + if ( t ) + { + const char *name = fl_file_chooser( "Import source", "*", NULL ); + + if ( name ) + { + char *url; + asprintf( &url, "file:///%s\n", name ); + + Fl::e_x = menu_event_x; + Fl::e_y = menu_event_y; + + t->sequence()->handle_paste(url); + + free(url); + } + } + } else WARNING( "programming error: Unknown menu item" ); } @@ -630,6 +659,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : BASE( X, Y, W menu->add( "Edit end to playhead", FL_CTRL + ']', 0, 0 ); menu->add( "Punch from edit", FL_CTRL + FL_SHIFT + 'p', 0, 0 ); menu->add( "Playback from edit", FL_CTRL + FL_SHIFT + 'l', 0, 0 ); + menu->add( "Import source at mouse", 0, 0, 0 ); menu->add( "Redraw", FL_CTRL + 'l', 0, 0 ); menu_set_callback( const_cast(menu->menu()), &Timeline::menu_cb, (void*)this ); @@ -1730,6 +1760,20 @@ Timeline::handle ( int m ) } else if ( test_press( FL_BUTTON3 ) ) { + { + menu_event_x = X; + menu_event_y = Y; + + Track *t = Timeline::event_inside(); + + Fl_Menu_Item *mi = (Fl_Menu_Item*)menu->find_item("Import source at mouse"); + + if ( t ) + mi->activate(); + else + mi->deactivate(); + } + menu_popup( menu ); return 1; @@ -1738,59 +1782,59 @@ Timeline::handle ( int m ) return 0; - case FL_DRAG: - { - int ox = X - drag->x; - int oy = Y - drag->y; - - if ( ox < 0 ) - _selection.x = X; - if ( oy < 0 ) - _selection.y = Y; - - _selection.w = abs( ox ); - _selection.h = abs( oy ); - - if ( range ) + case FL_DRAG: { - range_start( x_to_offset( _selection.x ) ); - range_end( x_to_offset( _selection.x + _selection.w ) ); - redraw(); + int ox = X - drag->x; + int oy = Y - drag->y; + + if ( ox < 0 ) + _selection.x = X; + if ( oy < 0 ) + _selection.y = Y; + + _selection.w = abs( ox ); + _selection.h = abs( oy ); + + if ( range ) + { + range_start( x_to_offset( _selection.x ) ); + range_end( x_to_offset( _selection.x + _selection.w ) ); + redraw(); + } + + redraw_overlay(); + return 1; + + break; } - - redraw_overlay(); - return 1; - - break; - } - case FL_RELEASE: - { - delete drag; - drag = NULL; - - if ( range ) + case FL_RELEASE: { - range_start( x_to_offset( _selection.x ) ); - range_end( x_to_offset( _selection.x + _selection.w ) ); - redraw(); + delete drag; + drag = NULL; + + if ( range ) + { + range_start( x_to_offset( _selection.x ) ); + range_end( x_to_offset( _selection.x + _selection.w ) ); + redraw(); + } + else + select( _selection ); + + _selection.x = _selection.y =_selection.w = _selection.h = 0; + + redraw_overlay(); + return 1; } - else - select( _selection ); - - _selection.x = _selection.y =_selection.w = _selection.h = 0; - - redraw_overlay(); - return 1; + default: + return 0; + break; } - default: - return 0; - break; + + return 0; } - - return 0; } } -} /** retrun a pointer to the track named /name/, or NULL if no track is named /name/ */ Track *