00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #include <iostream>
00025 using std::cerr;
00026 using std::endl;
00027
00028 #include <sys/time.h>
00029 #include <sys/types.h>
00030 #include <dirent.h>
00031 #include <pthread.h>
00032
00033 #include "page_trim.h"
00034 #include "avi.h"
00035 #include "error.h"
00036 #include "message.h"
00037 #include "filehandler.h"
00038 #include "frame.h"
00039 #include "commands.h"
00040 #include "page_editor.h"
00041 #include "ieee1394io.h"
00042
00043 #undef PLAY_WITH_STATS
00044
00045 #define TRIM_ADJ_POS 0
00046 #define TRIM_ADJ_IN 1
00047 #define TRIM_ADJ_OUT 2
00048
00049 extern "C"
00050 {
00051 #include "support.h"
00052
00053 extern KinoCommon *common;
00054 extern struct navigate_control g_nav_ctl;
00055 extern char cmd[];
00056 static char lastcmd[ 256 ] = { 0 };
00057 static int _getOneSecond( void );
00058
00059 static void resetThreads( );
00060 static void *readThread( void * info );
00061 static void *videoThread( void * info );
00062 static void *audioThread( void * info );
00063 static pthread_t readthreadTrim;
00064 static pthread_t audiothreadTrim;
00065 static pthread_t videothreadTrim;
00066 static pthread_mutex_t threadlock = PTHREAD_MUTEX_INITIALIZER;
00067 static pthread_mutex_t readlock = PTHREAD_MUTEX_INITIALIZER;
00068 static GtkAdjustment *trim_adj[ 3 ];
00069 static gboolean skipPosUpdate = FALSE;
00070 static GtkSpinButton *spin_in;
00071 static GtkSpinButton *spin_out;
00072 static GtkToggleButton *link_toggle;
00073 static GtkToggleButton *loop_toggle;
00074 static gboolean doScrub = false;
00075 static int newFrame = 0;
00076 static int lastFrame = -1;
00077
00078 #define PLAYBACK_FRAMES 50
00079
00080 static Frame *frameContent[ PLAYBACK_FRAMES ];
00081 extern IEEE1394Writer *writer1394;
00082
00083
00084 gboolean
00085 on_trim_value_changed_event ( GtkWidget * widget,
00086 GdkEventButton * event,
00087 gpointer user_data )
00088 {
00089 int value = ( int ) GTK_ADJUSTMENT( widget ) ->value;
00090 if ( GTK_ADJUSTMENT( widget ) == trim_adj[ TRIM_ADJ_IN ] )
00091 {
00092 int diff = common->getPageTrim() ->getOutPoint() - common->getPageTrim() ->getInPoint() + value;
00093
00094 if ( gtk_toggle_button_get_active( link_toggle ) == TRUE && skipPosUpdate == FALSE )
00095 {
00096 if ( diff <= common->getPageTrim() ->getTotalFrames() )
00097 {
00098 if ( value >= common->getPageTrim() ->getOutPoint() )
00099 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00100 else
00101 common->getPageTrim() ->setInPoint( value );
00102
00103 skipPosUpdate = TRUE;
00104 gtk_spin_button_set_value( spin_out, ( gfloat ) diff );
00105 skipPosUpdate = TRUE;
00106 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], diff );
00107 }
00108 else
00109 {
00110 skipPosUpdate = TRUE;
00111 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], common->getPageTrim() ->getInPoint() );
00112 }
00113 }
00114 else
00115 {
00116 if ( value > common->getPageTrim() ->getOutPoint() )
00117 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00118 common->getPageTrim() ->setInPoint( value );
00119 }
00120 skipPosUpdate = TRUE;
00121 common->getPageTrim() ->movedToFrame( value );
00122 gtk_spin_button_set_value( spin_in, ( gfloat ) value );
00123
00124 }
00125 else if ( GTK_ADJUSTMENT( widget ) == trim_adj[ TRIM_ADJ_OUT ] )
00126 {
00127 int diff = common->getPageTrim() ->getInPoint() - common->getPageTrim() ->getOutPoint() + value;
00128
00129 if ( gtk_toggle_button_get_active( link_toggle ) == TRUE && skipPosUpdate == FALSE )
00130 {
00131 if ( diff >= 0 )
00132 {
00133 if ( value <= common->getPageTrim() ->getInPoint() )
00134 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value - 1 );
00135 common->getPageTrim() ->setOutPoint( value );
00136
00137 skipPosUpdate = TRUE;
00138 gtk_spin_button_set_value( spin_in, ( gfloat ) diff );
00139 skipPosUpdate = TRUE;
00140 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], diff );
00141 }
00142 else
00143 {
00144 skipPosUpdate = TRUE;
00145 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], common->getPageTrim() ->getOutPoint() );
00146 }
00147 }
00148 else
00149 {
00150 if ( value < common->getPageTrim() ->getInPoint() )
00151 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00152 common->getPageTrim() ->setOutPoint( value );
00153 }
00154 skipPosUpdate = TRUE;
00155 common->getPageTrim() ->movedToFrame( value );
00156 gtk_spin_button_set_value( spin_out, ( gfloat ) value );
00157
00158 }
00159 else if ( skipPosUpdate == FALSE )
00160 {
00161 skipPosUpdate = TRUE;
00162 common->getPageTrim() ->movedToFrame( value );
00163 }
00164 skipPosUpdate = FALSE;
00165 return FALSE;
00166 }
00167
00168 void
00169 on_spinbutton_trim_in_value_changed ( GtkSpinButton * spinbutton,
00170 gpointer user_data )
00171 {
00172 if ( strcmp( gtk_entry_get_text( GTK_ENTRY( spin_in ) ), "" ) )
00173 {
00174 int value = atoi( gtk_entry_get_text( GTK_ENTRY( spin_in ) ) );
00175 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00176 }
00177 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( spinbutton ), "entry_trim_in" ) ),
00178 common->getTime().parseFramesToString( ( int )gtk_spin_button_get_value( spinbutton ),
00179 common->getTimeFormat() ).c_str() );
00180 }
00181
00182 void
00183 on_spinbutton_trim_out_value_changed ( GtkSpinButton * spinbutton,
00184 gpointer user_data )
00185 {
00186 if ( strcmp( gtk_entry_get_text( GTK_ENTRY( spin_out ) ), "" ) )
00187 {
00188 int value = atoi( gtk_entry_get_text( GTK_ENTRY( spin_out ) ) );
00189 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00190 }
00191 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( spinbutton ), "entry_trim_out" ) ),
00192 common->getTime().parseFramesToString( ( int )gtk_spin_button_get_value( spinbutton ),
00193 common->getTimeFormat() ).c_str() );
00194 }
00195
00196 void
00197 on_button_trim_in_reset_clicked ( GtkButton * button,
00198 gpointer user_data )
00199 {
00200 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00201 common->getPageTrim() ->resetInPoint();
00202 }
00203
00204 void
00205 on_button_trim_out_reset_clicked ( GtkButton * button,
00206 gpointer user_data )
00207 {
00208 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00209 common->getPageTrim() ->resetOutPoint();
00210 }
00211
00212 void
00213 on_button_trim_in_set_clicked ( GtkButton * button,
00214 gpointer user_data )
00215 {
00216 int value = common->getPageTrim() ->getPosition();
00217 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00218 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00219 }
00220
00221 void
00222 on_button_trim_out_set_clicked ( GtkButton * button,
00223 gpointer user_data )
00224 {
00225 int value = common->getPageTrim() ->getPosition();
00226 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00227 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00228 }
00229
00230 void
00231 on_togglebutton_trim_link_toggled ( GtkToggleButton * togglebutton,
00232 gpointer user_data )
00233 {
00234 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( togglebutton ), "eventbox_trim" ) );
00235 GtkImage *image = GTK_IMAGE( lookup_widget( GTK_WIDGET( togglebutton ), "pixmap_trim_link" ) );
00236 if ( gtk_toggle_button_get_active( togglebutton ) )
00237 gtk_image_set_from_file( image, DATADIR "/kino/link.xpm" );
00238 else
00239 gtk_image_set_from_file( image, DATADIR "/kino/link_off.xpm" );
00240 }
00241
00242 gboolean
00243 on_spinbutton_trim_in_focus_in_event ( GtkWidget * widget,
00244 GdkEventFocus * event,
00245 gpointer user_data )
00246 {
00247 g_nav_ctl.escaped = TRUE;
00248 return FALSE;
00249 }
00250
00251 gboolean
00252 on_spinbutton_trim_in_focus_out_event ( GtkWidget * widget,
00253 GdkEventFocus * event,
00254 gpointer user_data )
00255 {
00256 g_nav_ctl.escaped = FALSE;
00257 return FALSE;
00258 }
00259
00260 gboolean
00261 on_spinbutton_trim_out_focus_in_event ( GtkWidget * widget,
00262 GdkEventFocus * event,
00263 gpointer user_data )
00264 {
00265 g_nav_ctl.escaped = TRUE;
00266 return FALSE;
00267 }
00268
00269
00270 gboolean
00271 on_spinbutton_trim_out_focus_out_event ( GtkWidget * widget,
00272 GdkEventFocus * event,
00273 gpointer user_data )
00274 {
00275 g_nav_ctl.escaped = FALSE;
00276 return FALSE;
00277 }
00278
00279 gboolean
00280 on_trim_button_press_event ( GtkWidget * widget,
00281 GdkEventButton * event,
00282 gpointer user_data )
00283 {
00284 doScrub = TRUE;
00285 videoPause();
00286 return FALSE;
00287 }
00288
00289
00290 gboolean
00291 on_trim_button_release_event ( GtkWidget * widget,
00292 GdkEventButton * event,
00293 gpointer user_data )
00294 {
00295 doScrub = FALSE;
00296 return FALSE;
00297 }
00298
00299
00300
00301 gboolean
00302 on_combo_trim_clip_entry_focus_in_event( GtkWidget *widget,
00303 GdkEventFocus *event,
00304 gpointer user_data)
00305 {
00306 g_nav_ctl.escaped = TRUE;
00307 return FALSE;
00308 }
00309
00310 gboolean
00311 on_combo_trim_clip_entry_focus_out_event( GtkWidget *widget,
00312 GdkEventFocus *event,
00313 gpointer user_data)
00314 {
00315 g_nav_ctl.escaped = FALSE;
00316 const gchar* filename = gtk_entry_get_text( GTK_ENTRY( widget ) );
00317 if ( strlen( filename ) )
00318 {
00319 switch ( common->checkFile( ( char* ) filename ) )
00320 {
00321 case AVI:
00322 case RAW_DV:
00323 case QT:
00324 if ( common->getPageTrim()->loadFile( filename ) )
00325 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00326 break;
00327 default:
00328
00329
00330 break;
00331 }
00332 }
00333 return FALSE;
00334 }
00335
00336 void
00337 on_combo_trim_clip_entry_changed( GtkEditable *editable,
00338 gpointer user_data)
00339 {
00340 if ( g_nav_ctl.escaped == FALSE )
00341 {
00342 const gchar* filename = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ) );
00343 if ( strlen( filename ) )
00344 {
00345 switch ( common->checkFile( ( char* ) filename ) )
00346 {
00347 case AVI:
00348 case RAW_DV:
00349 case QT:
00350 if ( common->getPageTrim()->loadFile( filename ) )
00351 {
00352 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00353 break;
00354 }
00355 default:
00356 {
00357 const std::string& importedFile = common->importFile( filename );
00358 if ( common->getPageTrim()->loadFile( const_cast<char*>( importedFile.c_str() ) ) )
00359 {
00360 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ), const_cast<char*>( importedFile.c_str() ) );
00361 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00362 }
00363 else
00364 {
00365 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ), "" );
00366 }
00367 break;
00368 }
00369
00370
00371
00372 }
00373 }
00374 }
00375 }
00376
00377 void
00378 on_button_trim_open_clicked( GtkButton *button,
00379 gpointer user_data)
00380 {
00381 char *filename = common->getFileToOpen( _("Choose a DV file") );
00382 if ( filename && strcmp( filename, "" ) )
00383 {
00384 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( button ), "entry_trim_clip" ) ),
00385 filename );
00386 }
00387 }
00388
00389 void
00390 on_button_trim_insert_before_clicked( GtkButton *button,
00391 gpointer user_data)
00392 {
00393 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00394 common->getPageTrim()->insertScene( TRIM_INSERT_MODE_BEFORE );
00395 }
00396
00397 void
00398 on_button_trim_insert_after_clicked( GtkButton *button,
00399 gpointer user_data)
00400 {
00401 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00402 common->getPageTrim()->insertScene( TRIM_INSERT_MODE_AFTER );
00403 }
00404
00405 void
00406 on_menuitem_trim_update_activate( GtkMenuItem *menuitem,
00407 gpointer user_data)
00408 {
00409 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( menuitem ), "eventbox_trim" ) );
00410 common->getPageTrim()->setMode( PAGE_TRIM_MODE_UPDATE );
00411 }
00412
00413 void
00414 on_menuitem_trim_insert_activate( GtkMenuItem *menuitem,
00415 gpointer user_data)
00416 {
00417 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( menuitem ), "eventbox_trim" ) );
00418 common->getPageTrim()->setMode( PAGE_TRIM_MODE_INSERT );
00419 }
00420
00421 void
00422 on_button_trim_apply_clicked( GtkButton *button,
00423 gpointer user_data)
00424 {
00425 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00426 processCommand( "Enter" );
00427 }
00428
00429 void
00430 on_entry_trim_in_activate (GtkEntry *entry,
00431 gpointer user_data)
00432 {
00433 common->getTime().parseValueToString( gtk_entry_get_text( entry ), common->getTimeFormat() );
00434 GtkSpinButton *spinbutton = GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET( entry ), "spinbutton_trim_in" ) );
00435 gtk_spin_button_set_value( spinbutton, common->getTime().getFrames() );
00436 on_spinbutton_trim_in_value_changed( spinbutton, NULL );
00437 }
00438
00439 gboolean
00440 on_entry_trim_in_focus_out_event (GtkWidget *widget,
00441 GdkEventFocus *event,
00442 gpointer user_data)
00443 {
00444 on_entry_trim_in_activate( GTK_ENTRY( widget ), NULL );
00445 g_nav_ctl.escaped = FALSE;
00446 return FALSE;
00447 }
00448
00449 void
00450 on_entry_trim_out_activate (GtkEntry *entry,
00451 gpointer user_data)
00452 {
00453 common->getTime().parseValueToString( gtk_entry_get_text( entry ), common->getTimeFormat() );
00454 GtkSpinButton *spinbutton = GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET( entry ), "spinbutton_trim_out" ) );
00455 gtk_spin_button_set_value( spinbutton, common->getTime().getFrames() );
00456 on_spinbutton_trim_out_value_changed( spinbutton, NULL );
00457 }
00458
00459 gboolean
00460 on_entry_trim_out_focus_out_event (GtkWidget *widget,
00461 GdkEventFocus *event,
00462 gpointer user_data)
00463 {
00464 on_entry_trim_out_activate( GTK_ENTRY( widget ), NULL );
00465 g_nav_ctl.escaped = FALSE;
00466 return FALSE;
00467 }
00468
00469 }
00470
00475 GArray *scenes = NULL;
00476 PageTrim::PageTrim( KinoCommon *common ) :
00477 start_orig( 0 ), update_start(0), end_orig( 0 ), in_orig( 0 ), out_orig( 0 ), in( 0 ), out( 0 ),
00478 max( 0 ), pos( -1 ), currentScene( 0 ), lastPos( -1 ), mode( PAGE_TRIM_MODE_UNKNOWN ),
00479 changed( false )
00480 {
00481 cerr << "> Creating page trim" << endl;
00482 this->common = common;
00483 this->frameArea = GTK_DRAWING_AREA( lookup_widget( common->getWidget(), "drawingarea_trim" ) );
00484 gtk_widget_set_double_buffered( GTK_WIDGET( frameArea ), FALSE );
00485 this->positionLabelCurrent = GTK_LABEL( lookup_widget( common->getWidget(), "position_label_current" ) );
00486 this->positionLabelTotal = GTK_LABEL( lookup_widget( common->getWidget(), "position_label_total" ) );
00487 spin_in = GTK_SPIN_BUTTON( lookup_widget( common->getWidget(), "spinbutton_trim_in" ) );
00488 spin_out = GTK_SPIN_BUTTON( lookup_widget( common->getWidget(), "spinbutton_trim_out" ) );
00489 link_toggle = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(), "togglebutton_trim_link" ) );
00490 loop_toggle = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(), "togglebutton_trim_loop" ) );
00491
00492 this->g_copiedPlayList = new PlayList();
00493
00494
00495 trim_adj[ TRIM_ADJ_POS ] = GTK_ADJUSTMENT(
00496 gtk_adjustment_new( 0, 0, 0, 1, 10, 0 ) );
00497 trim_adj[ TRIM_ADJ_IN ] = GTK_ADJUSTMENT(
00498 gtk_adjustment_new( 0, 0, 0, 1, 10, 0 ) );
00499 trim_adj[ TRIM_ADJ_OUT ] = GTK_ADJUSTMENT(
00500 gtk_adjustment_new( 0, 0, 0, 1, 10, 0 ) );
00501 for ( int i = 0; i < 3; i++ )
00502 g_signal_connect ( G_OBJECT ( trim_adj[ i ] ), "value_changed",
00503 G_CALLBACK( on_trim_value_changed_event ), ( gpointer ) i );
00504 trim = gtk_enhanced_scale_new( ( GtkObject** ) trim_adj, 3 );
00505 gtk_widget_set_name ( trim, "trim" );
00506 gtk_widget_ref( trim );
00507 gtk_object_set_data_full ( GTK_OBJECT( common->getWidget() ), "trim", trim,
00508 ( GtkDestroyNotify ) gtk_widget_unref );
00509 GtkWidget *vbox_trim = lookup_widget( common->getWidget(), "vbox_trim_custom" );
00510 gtk_widget_show( trim );
00511 gtk_box_pack_start( GTK_BOX ( vbox_trim ), trim, FALSE, TRUE, 0 );
00512 g_signal_connect( G_OBJECT( trim ), "button_press_event",
00513 G_CALLBACK( on_trim_button_press_event ), NULL );
00514 g_signal_connect( G_OBJECT( trim ), "button_release_event",
00515 G_CALLBACK( on_trim_button_release_event ), NULL );
00516 }
00517
00521 PageTrim::~PageTrim( )
00522 {
00523 cerr << "> Destroying page trim" << endl;
00524 delete this->g_copiedPlayList;
00525 }
00526
00530 void PageTrim::newFile()
00531 {
00532 this->stopNavigator();
00533 }
00534
00538 void PageTrim::start()
00539 {
00540 cerr << ">> Starting Trimmer" << endl;
00541
00542 start_orig = update_start = end_orig = in = in_orig = out = out_orig = max = 0;
00543
00544 for ( int i = 0; i < PLAYBACK_FRAMES; i ++ )
00545 frameContent[ i ] = GetFramePool( ) ->GetFrame( );
00546
00547 this->displayer = new FrameDisplayer();
00548 if ( Preferences::getInstance().dv1394Preview )
00549 {
00550 #ifdef HAVE_IEC61883
00551 AVC avc;
00552 Preferences::getInstance( ).phyID = avc.getNodeId( Preferences::getInstance( ).avcGUID );
00553 Preferences::getInstance( ).phyID = avc.isPhyIDValid( Preferences::getInstance( ).phyID );
00554 if ( !writer1394 )
00555 writer1394 = new iec61883Writer(
00556 ( avc.getPort() < 0 ) ? 0 : avc.getPort(),
00557 Preferences::getInstance().channel,
00558 2 );
00559 #endif
00560 #ifdef HAVE_DV1394
00561 if ( Preferences::getInstance().dvExportDevice > 0 && !writer1394 )
00562 writer1394 = new dv1394Writer(
00563 Preferences::getInstance().dvExportDevice,
00564 Preferences::getInstance().channel,
00565 2,
00566 Preferences::getInstance().cip_n,
00567 Preferences::getInstance().cip_d,
00568 Preferences::getInstance().syt_offset );
00569 #endif
00570 }
00571
00572 if ( ! Preferences::getInstance().trimModeInsert && common->g_currentFrame > -1 )
00573 setMode( PAGE_TRIM_MODE_UPDATE );
00574 else
00575 setMode( PAGE_TRIM_MODE_INSERT );
00576
00577 if ( common->getPlayList() ->GetNumFrames() > 0 )
00578 {
00579
00580 loadScene( common->g_currentFrame );
00581 lastPos = pos = in + common->g_currentFrame - start_orig;
00582 movedToFrame( pos );
00583
00584
00585 GList *items = NULL;
00586 map<string, FileHandler*>::iterator n;
00587 for ( n = GetFileMap()->GetMap().begin(); n != GetFileMap()->GetMap().end(); ++n )
00588 items = g_list_append( items, ( void* ) n->first.c_str() );
00589 g_nav_ctl.escaped = TRUE;
00590 gtk_combo_set_popdown_strings( GTK_COMBO( lookup_widget( common->getWidget(), "combo_trim_clip" ) ), items);
00591 gtk_entry_set_text( GTK_ENTRY( lookup_widget( common->getWidget(), "entry_trim_clip" ) ), "" );
00592 g_nav_ctl.escaped = FALSE;
00593 }
00594
00595 gtk_widget_grab_focus( GTK_WIDGET( frameArea ) );
00596 common->packIt( "packer_trim", "packer_trim_outer" );
00597
00598 gtk_notebook_set_page( GTK_NOTEBOOK( lookup_widget( common->getWidget(), "notebook_keyhelp" ) ), 2 );
00599 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( lookup_widget( common->getWidget(), "menuitem_trim" ) ), TRUE );
00600 }
00601
00605 gulong PageTrim::activate()
00606 {
00607 return EDIT_MENU |
00608 SCENE_LIST |
00609 VIDEO_START_OF_MOVIE |
00610 VIDEO_START_OF_SCENE |
00611 VIDEO_REWIND |
00612 VIDEO_BACK |
00613 VIDEO_PLAY |
00614 VIDEO_PAUSE |
00615 VIDEO_STOP |
00616 VIDEO_FORWARD |
00617 VIDEO_FAST_FORWARD |
00618 VIDEO_NEXT_SCENE |
00619 VIDEO_END_OF_MOVIE |
00620 VIDEO_SHUTTLE |
00621 INFO_FRAME;
00622 }
00623
00627 void PageTrim::clean()
00628 {
00629 cerr << ">> Leaving Trimmer" << endl;
00630 stopNavigator();
00631 delete displayer;
00632 displayer = 0;
00633 delete writer1394;
00634 writer1394 = NULL;
00635 saveScene();
00636 for ( int i = 0; i < PLAYBACK_FRAMES; i ++ )
00637 GetFramePool( ) ->DoneWithFrame( frameContent[ i ] );
00638
00639 cerr << ">> Left Trimmer" << endl;
00640 }
00641
00642
00647 void PageTrim::loadScene( int newScene )
00648 {
00649 char value[ 20 ];
00650 PlayList newPlayList;
00651 playlist = newPlayList;
00652 PlayList *pl = common->getPlayList();
00653 FileHandler *media;
00654
00655 currentScene = newScene;
00656
00657
00658
00659 update_start = start_orig = pl->FindStartOfScene( currentScene );
00660 end_orig = pl->FindEndOfScene( currentScene );
00661
00662
00663
00664 pl->GetPlayList( start_orig, end_orig, playlist );
00665
00666
00667
00668 in = in_orig = lastPos = pos = pl->GetClipBegin( currentScene );
00669
00670
00671 playlist.SetClipBegin( 0, "0" );
00672
00673
00674 playlist.GetMediaObject( playlist.FindEndOfScene( 0 ), &media );
00675
00676
00677
00678
00679 int prevClipEnd = playlist.GetClipEnd( playlist.GetNumFrames() - 1 );
00680 int newClipEnd = media->GetTotalFrames() - 1;
00681 snprintf( value, 19, "%i", newClipEnd );
00682 playlist.SetClipEnd( playlist.GetNumFrames() - 1, value );
00683
00684
00685 max = playlist.GetNumFrames() - 1;
00686
00687
00688
00689 out = out_orig = max - ( newClipEnd - prevClipEnd );
00690
00691
00692 common->setCurrentScene( start_orig );
00693
00694
00695 trim_adj[ TRIM_ADJ_IN ] ->upper = max;
00696 trim_adj[ TRIM_ADJ_IN ] ->value = in;
00697 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_IN ], "changed" );
00698 trim_adj[ TRIM_ADJ_OUT ] ->upper = max;
00699 trim_adj[ TRIM_ADJ_OUT ] ->value = out;
00700 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_OUT ], "changed" );
00701 trim_adj[ TRIM_ADJ_POS ] ->upper = max;
00702 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_POS ], "changed" );
00703
00704
00705 GtkAdjustment *adjust = gtk_spin_button_get_adjustment( spin_in );
00706 adjust->lower = 0;
00707 adjust->upper = max;
00708 adjust->value = in;
00709 g_signal_emit_by_name( adjust, "changed" );
00710 gtk_spin_button_set_value( spin_in, ( gfloat ) in );
00711
00712 adjust = gtk_spin_button_get_adjustment( spin_out );
00713 adjust->lower = 0;
00714 adjust->upper = max;
00715 adjust->value = out;
00716 g_signal_emit_by_name( adjust, "changed" );
00717 gtk_spin_button_set_value( spin_out, ( gfloat ) out );
00718
00719 g_nav_ctl.escaped = TRUE;
00720 gtk_entry_set_text( GTK_ENTRY( lookup_widget( common->getWidget(), "entry_trim_clip" ) ), "" );
00721 g_nav_ctl.escaped = FALSE;
00722
00723 timeFormatChanged();
00724 }
00725
00726
00729 void PageTrim::saveScene()
00730 {
00731 if ( playlist.GetNumFrames() && ( in_orig != in || out_orig != out || changed ) )
00732 {
00733
00734 playlist.Delete( out + 1, max );
00735
00736 playlist.Delete( 0, in - 1 );
00737
00738 common->getPlayList() ->Delete( start_orig, end_orig );
00739
00740
00741 common->getPlayList() ->InsertPlayList( playlist, start_orig );
00742
00743 changed = false;
00744
00745
00746 GetEditorBackup() ->Store( common->getPlayList() );
00747
00748
00749 common->hasListChanged = TRUE;
00750 common->setWindowTitle( );
00751 common->getPageEditor()->DrawBar( common->g_currentFrame );
00752
00753
00754 GList *items = NULL;
00755 map<string, FileHandler*>::iterator n;
00756 for ( n = GetFileMap()->GetMap().begin(); n != GetFileMap()->GetMap().end(); ++n )
00757 items = g_list_append( items, ( void* ) n->first.c_str() );
00758 g_nav_ctl.escaped = TRUE;
00759 gtk_combo_set_popdown_strings( GTK_COMBO( lookup_widget( common->getWidget(), "combo_trim_clip" ) ), items);
00760 g_nav_ctl.escaped = FALSE;
00761 }
00762 }
00763
00764
00770 bool PageTrim::loadFile( const string& filename )
00771 {
00772 PlayList newList;
00773 bool result = true;
00774
00775 try
00776 {
00777 if ( newList.LoadMediaObject( const_cast< char* >( filename.c_str() ) ) )
00778 {
00779 playlist = newList;
00780 start_orig = common->getPlayList()->FindStartOfScene( currentScene );
00781 end_orig = common->getPlayList()->FindEndOfScene( currentScene );
00782 in = in_orig = lastPos = pos = 0;
00783 out = out_orig = max = playlist.GetNumFrames() - 1;
00784 changed = true;
00785
00786 trim_adj[ TRIM_ADJ_IN ] ->upper = max;
00787 trim_adj[ TRIM_ADJ_IN ] ->value = in;
00788 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_IN ], "changed" );
00789 trim_adj[ TRIM_ADJ_OUT ] ->upper = max;
00790 trim_adj[ TRIM_ADJ_OUT ] ->value = out;
00791 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_OUT ], "changed" );
00792 trim_adj[ TRIM_ADJ_POS ] ->upper = max;
00793 g_signal_emit_by_name( trim_adj[ TRIM_ADJ_POS ], "changed" );
00794
00795 GtkAdjustment *adjust = gtk_spin_button_get_adjustment( spin_in );
00796 adjust->lower = 0;
00797 adjust->upper = max;
00798 adjust->value = in;
00799 g_signal_emit_by_name( adjust, "changed" );
00800 gtk_spin_button_set_value( spin_in, ( gfloat ) in );
00801
00802 adjust = gtk_spin_button_get_adjustment( spin_out );
00803 adjust->lower = 0;
00804 adjust->upper = max;
00805 adjust->value = out;
00806 g_signal_emit_by_name( adjust, "changed" );
00807 gtk_spin_button_set_value( spin_out, ( gfloat ) out );
00808
00809 timeFormatChanged();
00810 }
00811 else
00812 {
00813
00814
00815 result = false;
00816 }
00817 }
00818 catch ( string s )
00819 {
00820 cerr << "Could not load file " << filename << ", because an exception has occurred: " << endl;
00821 cerr << s << endl;
00822 result = false;
00823 }
00824
00825 return result;
00826 }
00827
00828
00834 void PageTrim::insertScene( TrimInsertMode insertMode )
00835 {
00836 if ( playlist.GetNumFrames() > 0 )
00837 {
00838 int i = getSceneIndex();
00839
00840 if ( insertMode == TRIM_INSERT_MODE_BEFORE )
00841 {
00842 PlayList tmp;
00843 tmp = playlist;
00844 tmp.Delete( out + 1, max );
00845 tmp.Delete( 0, in - 1 );
00846 common->getPlayList()->InsertPlayList( tmp, start_orig );
00847 }
00848 else if ( insertMode == TRIM_INSERT_MODE_AFTER )
00849 {
00850 PlayList tmp;
00851 tmp = playlist;
00852 tmp.Delete( out + 1, max );
00853 tmp.Delete( 0, in - 1 );
00854 common->getPlayList()->InsertPlayList( tmp, end_orig + 1 );
00855 i++;
00856 }
00857 GetEditorBackup()->Store( common->getPlayList() );
00858 common->hasListChanged = TRUE;
00859 common->setWindowTitle( );
00860 common->getPageEditor()->DrawBar( common->g_currentFrame );
00861 selectScene( i );
00862 common->setCurrentScene( start_orig );
00863
00864
00865 GList *items = NULL;
00866 const char *filename = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( common->getWidget() ), "entry_trim_clip" ) ) );
00867 map<string, FileHandler*>::iterator n;
00868 items = g_list_append( items, ( void* ) filename );
00869 for ( n = GetFileMap()->GetMap().begin(); n != GetFileMap()->GetMap().end(); ++n )
00870 if ( strcmp( n->first.c_str(), filename ) )
00871 items = g_list_append( items, ( void* ) n->first.c_str() );
00872 g_nav_ctl.escaped = TRUE;
00873 gtk_combo_set_popdown_strings( GTK_COMBO( lookup_widget( common->getWidget(), "combo_trim_clip" ) ), items);
00874 g_nav_ctl.escaped = FALSE;
00875 }
00876 }
00877
00878
00879 void PageTrim::setMode( PageTrimMode newMode )
00880 {
00881 if ( newMode != mode )
00882 {
00883 if ( newMode == PAGE_TRIM_MODE_UPDATE && common->getPlayList()->GetNumFrames() > 0 )
00884 {
00885 mode = newMode;
00886 gtk_widget_show( lookup_widget( common->getWidget(), "hbox_trim_update" ) );
00887 gtk_widget_hide( lookup_widget( common->getWidget(), "hbox_trim_insert" ) );
00888
00889
00890 gfloat saved_in = in;
00891 gfloat saved_out = out;
00892 loadScene( update_start );
00893 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], saved_in );
00894 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], saved_out );
00895 }
00896 else if ( newMode == PAGE_TRIM_MODE_INSERT )
00897 {
00898 mode = newMode;
00899 gtk_widget_hide( lookup_widget( common->getWidget(), "hbox_trim_update" ) );
00900 gtk_widget_show( lookup_widget( common->getWidget(), "hbox_trim_insert" ) );
00901 }
00902
00903
00904 gtk_option_menu_set_history( GTK_OPTION_MENU( lookup_widget( common->getWidget(), "optionmenu_trim" ) ), static_cast< int >( mode ) );
00905 }
00906 }
00907
00911 void PageTrim::startNavigator()
00912 {
00913 stopNavigator( );
00914 g_nav_ctl.active = TRUE;
00915 resetThreads( );
00916 pthread_create( &readthreadTrim, NULL, readThread, &g_nav_ctl );
00917 pthread_create( &audiothreadTrim, NULL, audioThread, &g_nav_ctl );
00918 pthread_create( &videothreadTrim, NULL, videoThread, ( gpointer ) & g_nav_ctl );
00919 }
00920
00924 void PageTrim::stopNavigator()
00925 {
00926 if ( g_nav_ctl.active )
00927 {
00928 g_nav_ctl.active = FALSE;
00929 gdk_threads_leave();
00930 pthread_join( readthreadTrim, NULL );
00931 pthread_join( audiothreadTrim, NULL );
00932 pthread_join( videothreadTrim, NULL );
00933 gdk_threads_enter();
00934 getFrameDisplayer()->CloseSound();
00935 }
00936 }
00937
00944 void PageTrim::movedToFrame( int frame )
00945 {
00946 if ( common->hasListChanged == TRUE )
00947 {
00948 common->getPageEditor()->ResetBar();
00949 common->hasListChanged = FALSE;
00950
00951 if ( mode == PAGE_TRIM_MODE_UPDATE &&
00952 common->getPlayList() ->GetNumFrames() > 0 )
00953 {
00954 loadScene( frame );
00955 frame = in;
00956 }
00957 else if ( mode == PAGE_TRIM_MODE_INSERT )
00958 {
00959 const char *file = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( common->getWidget() ), "entry_trim_clip" ) ) );
00960 if ( file && strcmp( file, "" ) )
00961 {
00962 loadFile( file );
00963 frame = pos;
00964 }
00965 }
00966 }
00967 if ( max > 0 )
00968 {
00969 if ( frame > out && gtk_toggle_button_get_active( loop_toggle ) == TRUE )
00970 pos = in;
00971 else if ( frame < in && gtk_toggle_button_get_active( loop_toggle ) == TRUE )
00972 pos = out;
00973 else if ( frame >= 0 && frame <= max )
00974 pos = frame;
00975 else if ( frame >= max )
00976 pos = max;
00977 else if ( frame < 0 && max > 0 )
00978 pos = 0;
00979 else
00980 pos = -1;
00981
00982 if ( g_nav_ctl.active == FALSE )
00983 {
00984 skipPosUpdate = FALSE;
00985 showFrame( pos, ( pos == lastPos ) || ( Preferences::getInstance().audioScrub == FALSE ) );
00986 }
00987 else
00988 {
00989 lastFrame = newFrame = pos;
00990 startNavigator();
00991 }
00992 }
00993 }
00994
01001 void PageTrim::showFrame( int i, gboolean no_audio )
01002 {
01003 if ( max == 0 )
01004 {
01005 common->loadSplash( frameArea );
01006 common->showFrameInfo( -1 );
01007 return ;
01008 }
01009 else if ( i > -1 )
01010 {
01011 Frame & frame = *( GetFramePool( ) ->GetFrame( ) );
01012 if ( i > max )
01013 i = max;
01014 playlist.GetFrame( i, frame );
01015 common->showFrameInfo( i );
01016 if ( writer1394 != NULL )
01017 writer1394->SendFrame( frame, false );
01018 if ( getFrameDisplayer() )
01019 getFrameDisplayer() ->Put( frame, GTK_WIDGET( frameArea ), no_audio );
01020 lastPos = i;
01021 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_POS ], ( gfloat ) i );
01022 GetFramePool( ) ->DoneWithFrame( &frame );
01023 common->g_currentFrame = start_orig + (pos - in_orig);
01024 }
01025 }
01026
01027
01028 void PageTrim::showFrame( int position, Frame& frame )
01029 {
01030 if ( max == 0 )
01031 {
01032 common->loadSplash( frameArea );
01033 }
01034 else
01035 {
01036 getFrameDisplayer() ->Put( frame, GTK_WIDGET( frameArea ), TRUE );
01037 common->showFrameInfo( position );
01038 skipPosUpdate = TRUE;
01039 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_POS ], ( gfloat ) position );
01040 }
01041 }
01042
01043
01047 void PageTrim::videoStartOfMovie()
01048 {
01049 movedToFrame( 0 );
01050 common->toggleComponents( VIDEO_START_OF_MOVIE, false );
01051 }
01052
01056 void PageTrim::videoPreviousScene()
01057 {
01058 movedToFrame( in );
01059 common->toggleComponents( VIDEO_START_OF_SCENE, false );
01060 }
01061
01065 void PageTrim::videoStartOfScene()
01066 {
01067 movedToFrame( in );
01068 common->toggleComponents( VIDEO_START_OF_SCENE, false );
01069 }
01070
01074 void PageTrim::videoRewind()
01075 {
01076 common->toggleComponents( common->getComponentState(), false );
01077
01078
01079 if ( g_nav_ctl.step != -10 )
01080 {
01081 common->toggleComponents( VIDEO_REWIND, true );
01082 g_nav_ctl.step = -10;
01083 g_nav_ctl.rate = 0;
01084 startNavigator();
01085 }
01086 else
01087 {
01088 stopNavigator();
01089 g_nav_ctl.step = 1;
01090 g_nav_ctl.rate = 1;
01091 common->toggleComponents( VIDEO_REWIND, false );
01092 common->toggleComponents( VIDEO_STOP, true );
01093 }
01094 }
01095
01100 void PageTrim::videoBack(int step)
01101 {
01102 common->toggleComponents( common->getComponentState(), false );
01103 if ( g_nav_ctl.active )
01104 {
01105 if ( g_nav_ctl.step != -1 )
01106 {
01107 g_nav_ctl.step = -1;
01108 g_nav_ctl.rate = 1;
01109 common->toggleComponents( VIDEO_BACK, true );
01110 }
01111 else
01112 {
01113 stopNavigator();
01114 g_nav_ctl.step = 1;
01115 g_nav_ctl.rate = 0;
01116 common->toggleComponents( VIDEO_BACK, false );
01117 common->toggleComponents( VIDEO_STOP, true );
01118 }
01119 }
01120 else
01121 {
01122 common->moveByFrames( step );
01123 common->toggleComponents( VIDEO_BACK, false );
01124 common->toggleComponents( VIDEO_STOP, true );
01125 }
01126 }
01127
01131 void PageTrim::videoPlay()
01132 {
01133 common->toggleComponents( common->getComponentState(), false );
01134 if ( g_nav_ctl.active == FALSE || g_nav_ctl.step != 1 )
01135 {
01136 common->toggleComponents( VIDEO_PLAY, true );
01137 g_nav_ctl.step = 1;
01138 startNavigator();
01139 }
01140 else
01141 {
01142 stopNavigator();
01143 common->toggleComponents( VIDEO_PLAY, false );
01144 common->toggleComponents( VIDEO_STOP, true );
01145 }
01146 }
01147
01151 void PageTrim::videoPause()
01152 {
01153 common->toggleComponents( common->getComponentState(), false );
01154 common->toggleComponents( VIDEO_STOP, true );
01155 stopNavigator();
01156 }
01157
01161 void PageTrim::videoStop()
01162 {
01163 common->toggleComponents( common->getComponentState(), false );
01164 common->toggleComponents( VIDEO_STOP, true );
01165 stopNavigator();
01166 }
01167
01172 void PageTrim::videoForward(int step)
01173 {
01174 common->toggleComponents( common->getComponentState(), false );
01175 if ( g_nav_ctl.active && g_nav_ctl.step != 1 )
01176 {
01177 g_nav_ctl.step = 1;
01178 g_nav_ctl.rate = 1;
01179 common->toggleComponents( VIDEO_FORWARD, true );
01180 startNavigator();
01181 }
01182 else
01183 {
01184 stopNavigator();
01185 common->moveByFrames( step );
01186 common->toggleComponents( VIDEO_FORWARD, false );
01187 common->toggleComponents( VIDEO_STOP, true );
01188 }
01189 }
01190
01194 void PageTrim::videoFastForward()
01195 {
01196 common->toggleComponents( common->getComponentState(), false );
01197
01198 if ( g_nav_ctl.step != 10 )
01199 {
01200 common->toggleComponents( VIDEO_FAST_FORWARD, true );
01201 g_nav_ctl.step = 10;
01202 g_nav_ctl.rate = 0;
01203 startNavigator();
01204 }
01205 else
01206 {
01207 stopNavigator();
01208 g_nav_ctl.step = 1;
01209 g_nav_ctl.rate = 1;
01210 common->toggleComponents( VIDEO_FAST_FORWARD, false );
01211 common->toggleComponents( VIDEO_STOP, true );
01212 }
01213 }
01214
01222 void PageTrim::videoShuttle( int angle )
01223 {
01224 int frames_sec = _getOneSecond();
01225 int speedTable[] = {
01226 0,
01227 8, 10, 15, 20, 33, 50, 75,
01228 100,
01229 200, 300, 400, 500, 800, 1200,
01230 ( frames_sec * 100 ) };
01231 char s[ 64 ];
01232
01233 if ( angle < -15 )
01234 angle = -15;
01235 if ( angle > 15 )
01236 angle = 15;
01237
01238 int speed = speedTable[ ( angle < 0 ) ? -angle : angle ] * ( ( angle < 0 ) ? -1 : 1 );
01239 if ( speed == 0 || g_nav_ctl.step != speed / 100 || g_nav_ctl.rate != 100 / speed )
01240 {
01241 stopNavigator( );
01242 if ( speed == 0 )
01243 {
01244 common->keyboardFeedback( "", "" );
01245 common->toggleComponents( VIDEO_STOP, true );
01246 }
01247 else
01248 {
01249 g_nav_ctl.step = speed / 100;
01250 g_nav_ctl.rate = 100 / speed;
01251 g_nav_ctl.subframe = 0;
01252 startNavigator();
01253 snprintf( s, 63, _( "Shuttle %+.1f fps" ), ( float ) speed / 100.0 * frames_sec );
01254 common->keyboardFeedback( "", s );
01255 }
01256 }
01257 }
01258
01262 void PageTrim::videoNextScene()
01263 {
01264 movedToFrame( out );
01265 common->toggleComponents( VIDEO_NEXT_SCENE, false );
01266 }
01267
01271 void PageTrim::videoEndOfScene()
01272 {
01273 movedToFrame( out );
01274 common->toggleComponents( VIDEO_NEXT_SCENE, false );
01275 }
01276
01280 void PageTrim::videoEndOfMovie()
01281 {
01282 common->toggleComponents( common->getComponentState(), false );
01283 common->toggleComponents( VIDEO_END_OF_MOVIE, true );
01284 stopNavigator();
01285 movedToFrame( max );
01286 common->toggleComponents( VIDEO_END_OF_MOVIE, false );
01287 common->toggleComponents( VIDEO_STOP, true );
01288 }
01289
01295 void PageTrim::selectScene( int i )
01296 {
01297 bool restartNavigator = ( g_nav_ctl.active == TRUE );
01298
01299 stopNavigator();
01300
01301 if ( mode == PAGE_TRIM_MODE_UPDATE )
01302
01303 saveScene();
01304
01305
01306 vector <int> scene = common->getPageEditor() ->GetScene();
01307 if ( i >= ( int ) scene.size() )
01308 i = scene.size() - 1;
01309 currentScene = ( i <= 0 ) ? 0 : scene[ i - 1 ];
01310 common->g_currentFrame = currentScene;
01311
01312 if ( mode == PAGE_TRIM_MODE_UPDATE )
01313 {
01314 loadScene( currentScene );
01315 movedToFrame( in );
01316 }
01317 else if ( mode == PAGE_TRIM_MODE_INSERT )
01318 {
01319
01320 start_orig = common->getPlayList()->FindStartOfScene( currentScene );
01321 end_orig = common->getPlayList()->FindEndOfScene( currentScene );
01322
01323 common->setCurrentScene( start_orig );
01324 }
01325
01326 if ( restartNavigator )
01327 startNavigator();
01328 }
01329
01330 int PageTrim::getSceneIndex()
01331 {
01332 int i = 0;
01333 if ( common->getPlayList()->GetNumFrames() > 0 )
01334 {
01335 vector <int> scene = common->getPageEditor() ->GetScene();
01336 for ( i = 0; i < (int) scene.size() - 1; i++ )
01337 if ( currentScene < scene[ i ] )
01338 break;
01339 }
01340 else
01341 {
01342 i = -1;
01343 }
01344 return i;
01345 }
01346
01347 void PageTrim::resetInPoint()
01348 {
01349 in = in_orig;
01350 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], ( gfloat ) in );
01351 gtk_spin_button_set_value( spin_in, ( gfloat ) in );
01352 }
01353
01354
01355 void PageTrim::resetOutPoint()
01356 {
01357 out = out_orig;
01358 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], ( gfloat ) out );
01359 gtk_spin_button_set_value( spin_out, ( gfloat ) out );
01360 }
01361
01367 gboolean PageTrim::processKeyboard( GdkEventKey *event )
01368 {
01369 gboolean ret = FALSE;
01370
01371
01372 if ( g_nav_ctl.escaped == FALSE )
01373 {
01374 if ( strcmp( lastcmd, "alt" ) == 0 )
01375 {
01376 strcpy( lastcmd, "" );
01377 return ret;
01378 }
01379
01380
01381 switch ( event->keyval )
01382 {
01383 case GDK_Home:
01384 strcat( cmd, "gg");
01385 ret = TRUE;
01386 break;
01387 case GDK_End:
01388 strcat( cmd, "G");
01389 ret = TRUE;
01390 break;
01391 case GDK_BackSpace:
01392 case GDK_Left:
01393 strcat( cmd, "h" );
01394 ret = TRUE;
01395 break;
01396 case GDK_Up:
01397 strcat( cmd, "k" );
01398 ret = TRUE;
01399 break;
01400 case GDK_Right:
01401 strcat( cmd, "l" );
01402 ret = TRUE;
01403 break;
01404 case GDK_Return:
01405 if ( cmd[ 0 ] != 0 )
01406 {
01407
01408 strcpy( lastcmd, cmd );
01409
01410
01411 cmd[ 0 ] = 0;
01412 common->setStatusBar( "" );
01413 break;
01414 }
01415 else
01416 {
01417 strcat( cmd, "Enter" );
01418 ret = TRUE;
01419 break;
01420 }
01421 case GDK_Down:
01422 strcat( cmd, "j" );
01423 ret = TRUE;
01424 break;
01425 case GDK_Delete:
01426 strcat( cmd, "x" );
01427 ret = TRUE;
01428 break;
01429 case GDK_Escape:
01430 if ( common->getComponentState() & VIDEO_STOP )
01431 {
01432 common->changePageRequest( PAGE_EDITOR );
01433 return ret;
01434 }
01435 else
01436 {
01437 strcat( cmd, "Esc" );
01438 break;
01439 }
01440 case GDK_Alt_L:
01441 case GDK_Alt_R:
01442 strcpy( lastcmd, "alt" );
01443 return ret;
01444 case GDK_Insert:
01445 case GDK_KP_Insert:
01446 strcat( cmd, "Ins" );
01447 ret = TRUE;
01448 break;
01449 default:
01450 if ( strcmp( event->string, "." ) )
01451 strcat( cmd, event->string );
01452 break;
01453 }
01454
01455 if ( !strcmp( event->string, "." ) )
01456 strcpy( cmd, lastcmd );
01457 else if ( cmd[ 0