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 #include <vector>
00026 #include <string>
00027
00028 #include <pthread.h>
00029
00030 #include "storyboard.h"
00031 #include "frame.h"
00032 #include "preferences.h"
00033 #include "error.h"
00034 #include "page_editor.h"
00035 #include "commands.h"
00036 #include "stringutils.h"
00037
00038 extern "C"
00039 {
00040 #include "support.h"
00041 #include "cell-renderers/mg-popup-entry.h"
00042 #include "cell-renderers/mg-cell-renderer-popup.h"
00043 #include "cell-renderers/mg-cell-renderer-list.h"
00044
00045 extern KinoCommon *common;
00046 extern struct navigate_control g_nav_ctl;
00047 }
00048
00049 enum SceneStatus {
00050 SCENE_INIT,
00051 SCENE_IDLE,
00052 SCENE_STARTING,
00053 SCENE_RUNNING,
00054 SCENE_RESTART
00055 };
00056
00057 enum
00058 {
00059 COLUMN_THUMBNAIL = 0,
00060 COLUMN_NAME,
00061 COLUMN_NAME_MODE,
00062 COLUMN_VALUE,
00063 COLUMN_VALUE_MODE,
00064 N_COLUMNS
00065 };
00066
00067 enum SceneStatus showScenesRunning = SCENE_INIT;
00068
00069 static std::vector< GdkPixbuf * > *backup = NULL;
00070 static pthread_mutex_t scene_mutex = PTHREAD_MUTEX_INITIALIZER;
00071
00072
00073 static int getSceneFromPath( gchar *path )
00074 {
00075 std::vector< int > scenes = common->getPageEditor() ->GetScene();
00076 int i = atoi( path );
00077 if ( i > ( int ) scenes.size() )
00078 i = scenes.size() - 1;
00079 return ( i <= 0 ) ? 0 : scenes[ i - 1 ];
00080 }
00081
00082 static void removeImages( std::vector< GdkPixbuf * >** list )
00083 {
00084 if ( *list != NULL )
00085 {
00086 std::vector< GdkPixbuf * >::iterator iter;
00087 for ( iter = ( *list ) ->begin(); iter != ( *list ) ->end(); iter++ )
00088 {
00089 if ( *iter != NULL )
00090 g_object_unref( *iter );
00091 }
00092 ( *list ) ->erase( ( *list ) ->begin(), ( *list ) ->end() );
00093 delete ( *list );
00094 *list = NULL;
00095 }
00096 }
00097
00098 static void tree_model_row_inserted_cb( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data )
00099 {
00100 Storyboard * storyboard = ( Storyboard* ) ( data );
00101
00102 if ( ! storyboard->getSkip() )
00103 {
00104 gchar * row = gtk_tree_path_to_string( path );
00105 int row_num = atoi( row );
00106
00107 if ( strchr( row, ':' ) != NULL )
00108 row_num++;
00109 storyboard->setSkip();
00110 storyboard->moveScene( row_num );
00111 g_free( row );
00112 }
00113 }
00114
00115 static gboolean tree_view_row_select( GtkWidget *widget, GdkEventButton *event, gpointer data )
00116 {
00117 GtkTreeView * treeview = GTK_TREE_VIEW( widget );
00118 GtkTreeSelection *selection = gtk_tree_view_get_selection( treeview );
00119
00120 GtkTreeIter iter;
00121 GtkTreeModel *model;
00122
00123 if ( gtk_tree_selection_get_selected ( selection, &model, &iter ) )
00124 {
00125 gchar * row = gtk_tree_model_get_string_from_iter( model, &iter );
00126 if ( strchr( row, ':' ) )
00127 {
00128 GtkTreeViewColumn* column;
00129 GtkTreePath *path;
00130 gtk_tree_view_get_cursor( treeview, &path, &column );
00131 if ( path && column )
00132 gtk_tree_view_set_cursor( treeview, path, column, TRUE);
00133 }
00134 else
00135 {
00136 common->selectScene( atoi( row ) );
00137 }
00138 g_free( row );
00139 }
00140
00141 return FALSE;
00142 }
00143
00144
00145 static void tree_view_row_activated( GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data )
00146 {
00147
00148 #if 0
00149 if ( gtk_tree_view_row_expanded( treeview, path ) )
00150 gtk_tree_view_collapse_row( treeview, path );
00151 else
00152 gtk_tree_view_expand_row( treeview, path, FALSE );
00153 #endif
00154 }
00155
00156
00157 static void
00158 on_name_start_editing( MgCellRendererPopup *cell )
00159 {
00160 g_nav_ctl.escaped = TRUE;
00161 }
00162
00163 static void
00164 on_name_show_popup( MgCellRendererList *cell,
00165 const gchar *path_string,
00166 gint x1,
00167 gint y1,
00168 gint x2,
00169 gint y2,
00170 GtkTreeModel *model)
00171 {
00172 GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
00173 GtkTreeIter iter;
00174 vector< std::string > metaNames;
00175 vector< std::string >::iterator metaNamesIter;
00176 GList *list = NULL;
00177 int currentScene = getSceneFromPath( const_cast< char* >( path_string ) );
00178
00179 gtk_tree_model_get_iter (model, &iter, path);
00180 StringUtils::split( Preferences::getInstance().metaNames, ",", metaNames );
00181
00182 for ( metaNamesIter = metaNames.begin(); metaNamesIter != metaNames.end(); ++metaNamesIter )
00183 {
00184 std::string metaname = *metaNamesIter;
00185 if ( metaname.at( 0 ) != '*' )
00186 {
00187
00188 if ( common->getPlayList()->GetSeqAttribute( currentScene, metaname.c_str() ) == "" )
00189 list = g_list_append( list, strdup( metaname.c_str() ) );
00190 }
00191 }
00192 cell->list = list;
00193 cell->selected_index = 0;
00194
00195 gtk_tree_path_free( path );
00196 }
00197
00198 static void
00199 on_name_edited( MgCellRendererList *cell,
00200 gchar *path_string,
00201 gchar *new_text,
00202 GtkTreeStore *model )
00203 {
00204 GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
00205 GtkTreeIter iter;
00206 gchar *parentPathString = path_string;
00207 GtkTreePath *parentPath = NULL;
00208 GtkTreeIter parent;
00209 vector< std::string > metaNames;
00210 vector< std::string >::iterator metaNamesIter;
00211 int currentScene = getSceneFromPath( const_cast< char* >( path_string ) );
00212 int i = 0;
00213
00214 path_string = strrchr( path_string, ':' );
00215 if ( path_string )
00216 {
00217 *path_string = 0;
00218 parentPath = gtk_tree_path_new_from_string( parentPathString );
00219 gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &parent, parentPath );
00220 }
00221 gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path );
00222
00223 StringUtils::split( Preferences::getInstance().metaNames, ",", metaNames );
00224
00225
00226 for ( GList *l = cell->list; l; l = l->next )
00227 {
00228 if ( cell->selected_index == i++ )
00229 {
00230
00231 const char *name = mg_popup_entry_get_text( MG_POPUP_ENTRY( cell->parent.editable ) );
00232
00233
00234 gtk_tree_store_set( model, &iter, COLUMN_NAME, (gchar*) l->data, COLUMN_VALUE, "-", -1 );
00235
00236
00237 gtk_tree_model_row_changed( GTK_TREE_MODEL( model ), path, &iter );
00238
00239 if ( name[0] != '(' )
00240 {
00241
00242 common->getPlayList()->SetSeqAttribute( currentScene, name, "" );
00243 }
00244 else
00245 {
00246
00247 common->getPlayList()->SetSeqAttribute( currentScene, (char*) l->data, "-" );
00248
00249
00250 for ( metaNamesIter = metaNames.begin(); metaNamesIter != metaNames.end(); ++metaNamesIter )
00251 {
00252 std::string metaname = *metaNamesIter;
00253 if ( metaname.at( 0 ) == '*' )
00254 metaname.erase( 0,1 );
00255
00256
00257 if ( common->getPlayList()->GetSeqAttribute( currentScene, metaname.c_str() ) == "" )
00258 {
00259 GetStoryboard()->setSkip();
00260
00261 gtk_tree_store_append( model, &iter, &parent );
00262 gtk_tree_store_set( model, &iter,
00263 COLUMN_NAME, _("(new)"),
00264 COLUMN_NAME_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00265 COLUMN_VALUE, "",
00266 COLUMN_VALUE_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00267 -1 );
00268 GetStoryboard()->clearSkip();
00269 break;
00270 }
00271 }
00272 }
00273
00274 break;
00275 }
00276 }
00277
00278 g_nav_ctl.escaped = FALSE;
00279
00280 if ( path )
00281 gtk_tree_path_free( path );
00282 if ( parentPath )
00283 gtk_tree_path_free( parentPath );
00284 }
00285
00286 static void
00287 on_value_start_editing( MgCellRendererPopup *cell )
00288 {
00289 g_nav_ctl.escaped = TRUE;
00290 }
00291
00292 static void
00293 on_value_show_popup( MgCellRendererList *cell,
00294 const gchar *path_string,
00295 gint x1,
00296 gint y1,
00297 gint x2,
00298 gint y2,
00299 GtkTreeStore *model)
00300 {
00301 GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
00302 GtkTreeIter iter;
00303 GValue name;
00304 gchar *name_string;
00305 vector< std::pair< std::string, std::string > > metaValues;
00306 vector< std::pair< std::string, std::string > >::iterator metaValuesIter;
00307 GList *list = NULL;
00308
00309
00310 gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path );
00311 memset( &name, 0, sizeof( name ) );
00312 gtk_tree_model_get_value( GTK_TREE_MODEL( model ), &iter, COLUMN_NAME, &name );
00313 name_string = const_cast< char* >( g_value_get_string( &name ) );
00314
00315
00316 metaValues = Preferences::getInstance().metaValues[ name_string ];
00317 for ( metaValuesIter = metaValues.begin(); metaValuesIter != metaValues.end(); ++metaValuesIter )
00318 {
00319 if ( metaValuesIter->first != "*" )
00320 list = g_list_append( list, strdup( metaValuesIter->first.c_str() ) );
00321 }
00322 cell->list = list;
00323 cell->selected_index = 0;
00324
00325 if ( path )
00326 gtk_tree_path_free( path );
00327 g_value_unset( &name );
00328 }
00329
00330 static void
00331 on_value_edited( MgCellRendererList *cell,
00332 gchar *path_string,
00333 gchar *new_text,
00334 GtkTreeStore *model )
00335 {
00336 GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
00337 GtkTreeIter iter;
00338 GValue name;
00339 gchar *name_string;
00340
00341
00342 gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path );
00343 memset( &name, 0, sizeof( name ) );
00344 gtk_tree_model_get_value( GTK_TREE_MODEL( model ), &iter, COLUMN_NAME, &name );
00345 name_string = const_cast< char* >( g_value_get_string( &name ) );
00346
00347 if ( name_string && name_string[0] != '(' )
00348 {
00349 if ( Preferences::getInstance().metaValues.find( name_string ) != Preferences::getInstance().metaValues.end() )
00350 {
00351 vector< std::pair< std::string, std::string > >& metaValues = Preferences::getInstance().metaValues[ name_string ];
00352 vector< std::pair< std::string, std::string > >::iterator metaValuesIter;
00353 char *value = NULL;
00354 char *label = NULL;
00355
00356
00357 for ( metaValuesIter = metaValues.begin(); metaValuesIter != metaValues.end() && metaValuesIter->first != "*"; ++metaValuesIter );
00358
00359 if ( metaValuesIter != metaValues.end() && MG_CELL_RENDERER_POPUP( cell )->shown == FALSE )
00360 {
00361
00362 label = value = const_cast< char* >( mg_popup_entry_get_text( MG_POPUP_ENTRY( cell->parent.editable ) ) );
00363
00364
00365 for ( metaValuesIter = metaValues.begin(); metaValuesIter != metaValues.end(); ++metaValuesIter )
00366 {
00367 if ( metaValuesIter->first == label )
00368 {
00369 value = const_cast< char* >( metaValuesIter->second.c_str() );
00370 break;
00371 }
00372 }
00373 }
00374 else if ( MG_CELL_RENDERER_POPUP( cell )->shown == TRUE )
00375 {
00376 int i = 0;
00377
00378
00379 for ( GList *l = cell->list; l; l = l->next )
00380 {
00381 if ( cell->selected_index == i++ )
00382 {
00383 label = (char*) l->data;
00384 break;
00385 }
00386 }
00387
00388
00389 for ( metaValuesIter = metaValues.begin(); metaValuesIter != metaValues.end(); ++metaValuesIter )
00390 {
00391 if ( metaValuesIter->first == label )
00392 {
00393 value = const_cast< char* >( metaValuesIter->second.c_str() );
00394 break;
00395 }
00396 }
00397 }
00398
00399 if ( value )
00400 {
00401
00402 gtk_tree_store_set( model, &iter, COLUMN_VALUE, label, -1 );
00403
00404
00405 gtk_tree_model_row_changed( GTK_TREE_MODEL( model ), path, &iter );
00406
00407
00408 common->getPlayList()->SetSeqAttribute( getSceneFromPath( const_cast< char* >( path_string ) ), name_string, value );
00409 }
00410 }
00411 }
00412
00413 g_nav_ctl.escaped = FALSE;
00414
00415 if ( path )
00416 gtk_tree_path_free( path );
00417 g_value_unset( &name );
00418 }
00419
00420 static gboolean scroll_handler( gpointer data )
00421 {
00422 GtkTreeView* view = GTK_TREE_VIEW( data );
00423 GtkTreeSelection* selection = gtk_tree_view_get_selection( view );
00424 GtkTreeIter iter;
00425 GtkTreeModel* model;
00426 if ( gtk_tree_selection_get_selected( selection, &model, &iter ) == TRUE )
00427 {
00428 GtkTreePath* path = gtk_tree_model_get_path( model, &iter );
00429 gtk_tree_view_scroll_to_cell( view, path, NULL, TRUE, 0.5, 0.0 );
00430 gtk_tree_path_free( path );
00431 }
00432 return FALSE;
00433 }
00434
00435 static gboolean expansion_handler( gpointer data )
00436 {
00437 GtkTreeView* view = GTK_TREE_VIEW( data );
00438 gtk_tree_view_expand_all( view );
00439
00440 GdkWindow* win = gtk_tree_view_get_bin_window( view );
00441 GdkRectangle rect;
00442 gtk_tree_view_get_visible_rect( view, &rect );
00443 gtk_tree_view_tree_to_widget_coords( view, rect.x, rect.y, &rect.x, &rect.y );
00444 gdk_window_invalidate_rect( win, &rect, TRUE );
00445
00446 g_idle_add( scroll_handler, data );
00447
00448 return FALSE;
00449 }
00450
00451 Storyboard::Storyboard( KinoCommon *common ) :
00452 common( common ), skipSelect( false ), skip( false )
00453 {
00454 GtkCellRenderer* renderer;
00455 GtkTreeViewColumn* column;
00456 GtkTreeSelection* select;
00457
00458 gdk_threads_enter();
00459
00460
00461 view = GTK_TREE_VIEW( lookup_widget( common->getWidget(), "treeview_storyboard" ) );
00462 g_signal_connect( G_OBJECT( view ), "button-release-event", G_CALLBACK( tree_view_row_select ), this );
00463 g_signal_connect( G_OBJECT( view ), "row-activated", G_CALLBACK( tree_view_row_activated ), this );
00464 gtk_tree_view_set_enable_search( view, FALSE );
00465
00466
00467 selection = common->getCurrentScene();
00468
00469
00470 model = gtk_tree_store_new( N_COLUMNS, G_TYPE_OBJECT, G_TYPE_STRING,
00471 G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT );
00472 gtk_tree_view_set_model( view, GTK_TREE_MODEL( model ) );
00473 g_signal_connect( G_OBJECT( model ), "row-inserted",
00474 G_CALLBACK( tree_model_row_inserted_cb ), static_cast<gpointer>( this ) );
00475
00476
00477 renderer = gtk_cell_renderer_pixbuf_new();
00478 column = gtk_tree_view_column_new_with_attributes(
00479 _( "Storyboard" ), renderer, "pixbuf", COLUMN_THUMBNAIL, NULL );
00480 gtk_tree_view_column_set_fixed_width( column, 100 );
00481 gtk_tree_view_column_set_min_width( column, 100 );
00482 gtk_tree_view_column_set_max_width( column, 100 );
00483 gtk_tree_view_append_column( view, column );
00484 gtk_tree_view_set_expander_column( view, column );
00485
00486
00487 column = gtk_tree_view_column_new();
00488 gtk_tree_view_column_set_title( column, _("Property") );
00489 gtk_tree_view_column_set_resizable( column, TRUE );
00490 gtk_tree_view_append_column( view, column );
00491
00492 renderer = mg_cell_renderer_list_new();
00493 g_object_set( G_OBJECT( renderer ), "editable", TRUE, NULL );
00494 gtk_tree_view_column_pack_start( column, renderer, TRUE );
00495 gtk_tree_view_column_set_attributes( column, renderer,
00496 "text", COLUMN_NAME,
00497 "mode", COLUMN_NAME_MODE,
00498 NULL );
00499
00500 g_signal_connect( G_OBJECT( renderer ),
00501 "start-editing",
00502 G_CALLBACK( on_name_start_editing ),
00503 NULL );
00504 g_signal_connect( G_OBJECT( renderer ),
00505 "show_popup",
00506 G_CALLBACK( on_name_show_popup ),
00507 model );
00508 g_signal_connect( G_OBJECT( renderer ),
00509 "edited",
00510 G_CALLBACK( on_name_edited ),
00511 model );
00512
00513
00514 column = gtk_tree_view_column_new();
00515 gtk_tree_view_column_set_title( column, _("Value") );
00516 gtk_tree_view_column_set_resizable( column, FALSE );
00517 gtk_tree_view_append_column( view, column );
00518
00519 renderer = mg_cell_renderer_list_new();
00520 g_object_set( G_OBJECT( renderer ), "editable", TRUE, NULL );
00521
00522 gtk_tree_view_column_pack_start( column, renderer, TRUE );
00523 gtk_tree_view_column_set_attributes( column, renderer,
00524 "text", COLUMN_VALUE,
00525 "mode", COLUMN_VALUE_MODE,
00526 NULL );
00527
00528 g_signal_connect( G_OBJECT( renderer ),
00529 "start-editing",
00530 G_CALLBACK( on_value_start_editing ),
00531 NULL );
00532 g_signal_connect( G_OBJECT( renderer ),
00533 "show_popup",
00534 G_CALLBACK( on_value_show_popup ),
00535 model );
00536 g_signal_connect( G_OBJECT( renderer ),
00537 "edited",
00538 G_CALLBACK( on_value_edited ),
00539 model );
00540
00541 select = gtk_tree_view_get_selection( view );
00542 gtk_tree_selection_set_mode( select, GTK_SELECTION_SINGLE );
00543
00544 gdk_threads_leave();
00545 g_object_unref( G_OBJECT( model ) );
00546 }
00547
00548 Storyboard::~Storyboard()
00549 {}
00550
00551 void *showScenesThread( void *arg )
00552 {
00553 Frame & frame = *( GetFramePool( ) ->GetFrame( ) );
00554 GdkPixbuf *image = NULL;
00555 GdkPixbuf *thumbnail = NULL;
00556 static std::vector< GdkPixbuf * > *icons = NULL;
00557 std::vector< int > scene;
00558 int frameNum = 0;
00559 Storyboard *storyboard = static_cast<Storyboard *>( arg );
00560 GtkTreeIter iter, child;
00561 unsigned char *pixels = new unsigned char[ FRAME_MAX_WIDTH * FRAME_MAX_HEIGHT * 4 ];
00562
00563 frame.decoder->quality = DV_QUALITY_DC;
00564 if ( Preferences::getInstance().displayQuality < 4 )
00565 frame.decoder->quality |= DV_QUALITY_COLOR;
00566
00567
00568 while ( showScenesRunning != SCENE_IDLE )
00569 {
00570
00571
00572
00573
00574
00575
00576 icons = new std::vector< GdkPixbuf *>;
00577
00578
00579 showScenesRunning = SCENE_RUNNING;
00580
00581
00582 scene = common->getPageEditor() ->GetScene();
00583
00584
00585 for ( unsigned int i = 0; showScenesRunning == SCENE_RUNNING && i < scene.size(); ++i )
00586 {
00587
00588 frameNum = i == 0 ? 0 : scene[ i - 1 ];
00589
00590 fail_neg( common->getPlayList() ->GetFrame( frameNum, frame ) );
00591
00592 frame.ExtractHeader();
00593 frame.ExtractRGB( pixels );
00594
00595
00596 image = gdk_pixbuf_new_from_data( pixels, GDK_COLORSPACE_RGB, FALSE, 8,
00597 frame.GetWidth(), frame.GetHeight(), frame.GetWidth() * 3,
00598 NULL, NULL );
00599
00600
00601 thumbnail = gdk_pixbuf_scale_simple( image, 80, frame.IsWide() ? 45 : 60, GDK_INTERP_NEAREST );
00602 icons->push_back( thumbnail );
00603 g_object_unref( image );
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 if ( showScenesRunning == SCENE_RUNNING )
00613 {
00614 pthread_mutex_lock( &scene_mutex );
00615 storyboard->setSkip();
00616 gdk_threads_enter();
00617 gtk_tree_store_clear( storyboard->getModel() );
00618 for ( unsigned int i = 0; showScenesRunning == SCENE_RUNNING && i < scene.size(); ++i )
00619 {
00620 char start[ 1024 ] = "";
00621 vector< std::string > metaNames;
00622 vector< std::string >::iterator metaNamesIter;
00623 StringUtils::split( Preferences::getInstance().metaNames, ",", metaNames );
00624
00625
00626 frameNum = ( i == 0 ) ? 0 : scene[ i - 1 ];
00627 fail_neg( common->getPlayList() ->GetFrame( frameNum, frame ) );
00628 frame.ExtractHeader();
00629 storyboard->getTime().setFramerate( frame.GetFrameRate() );
00630 char* fileName = common->getPlayList() ->GetFileNameOfFrame( frameNum );
00631 snprintf( start, 1024, "%s\n%s\n%s",
00632 g_path_get_basename( fileName ),
00633 storyboard->getTime().parseFramesToString( frameNum, common->getTimeFormat() ).c_str(),
00634 storyboard->getTime().parseFramesToString( scene[ i ] - frameNum, common->getTimeFormat() ).c_str()
00635 );
00636 free( fileName );
00637
00638
00639 gtk_tree_store_append( storyboard->getModel(), &iter, NULL );
00640 gtk_tree_store_set( storyboard->getModel(), &iter,
00641 COLUMN_THUMBNAIL, ( *icons ) [ i ],
00642 COLUMN_NAME, _("File:\nBegin:\nDuration:"),
00643 COLUMN_NAME_MODE, GTK_CELL_RENDERER_MODE_ACTIVATABLE,
00644 COLUMN_VALUE, start,
00645 COLUMN_VALUE_MODE, GTK_CELL_RENDERER_MODE_ACTIVATABLE,
00646 -1 );
00647
00648 for ( metaNamesIter = metaNames.begin(); metaNamesIter != metaNames.end(); ++metaNamesIter )
00649 {
00650 std::string metaname = *metaNamesIter;
00651 if ( metaname.at(0) == '*' )
00652 metaname.erase(0,1);
00653
00654
00655 if ( metaNamesIter->at( 0 ) == '*' || common->getPlayList()->GetSeqAttribute( frameNum, metaname.c_str() ) != "" )
00656 {
00657 vector< std::pair< std::string, std::string > >& metaValues = Preferences::getInstance().metaValues[ metaname ];
00658 vector< std::pair< std::string, std::string > >::iterator metaValuesIter;
00659 std::string labelString = common->getPlayList()->GetSeqAttribute( frameNum, metaname.c_str() );
00660 char *label = const_cast< char* >( labelString.c_str() );
00661
00662
00663 for ( metaValuesIter = metaValues.begin(); metaValuesIter != metaValues.end(); ++metaValuesIter )
00664 {
00665 if ( metaValuesIter->second == label )
00666 {
00667 label = const_cast< char* >( metaValuesIter->first.c_str() );
00668 break;
00669 }
00670 }
00671
00672 gtk_tree_store_append( storyboard->getModel(), &child, &iter );
00673 gtk_tree_store_set( storyboard->getModel(), &child,
00674 COLUMN_NAME, metaname.c_str(),
00675 COLUMN_NAME_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00676 COLUMN_VALUE, label,
00677 COLUMN_VALUE_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00678 -1 );
00679 }
00680 }
00681
00682 for ( metaNamesIter = metaNames.begin(); metaNamesIter != metaNames.end(); ++metaNamesIter )
00683 {
00684 std::string metaname = *metaNamesIter;
00685 if ( metaname.at( 0 ) == '*' )
00686 metaname.erase( 0, 1 );
00687
00688 if ( common->getPlayList()->GetSeqAttribute( frameNum, metaname.c_str() ) == "" )
00689 {
00690
00691 gtk_tree_store_append( storyboard->getModel(), &child, &iter );
00692 gtk_tree_store_set( storyboard->getModel(), &child,
00693 COLUMN_NAME, _("(new)"),
00694 COLUMN_NAME_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00695 COLUMN_VALUE, "",
00696 COLUMN_VALUE_MODE, GTK_CELL_RENDERER_MODE_EDITABLE,
00697 -1 );
00698 break;
00699 }
00700 }
00701 }
00702 if ( scene.size() )
00703 storyboard->select( common->getCurrentScene() );
00704
00705 gdk_threads_leave();
00706 storyboard->clearSkip();
00707 pthread_mutex_unlock( &scene_mutex );
00708
00709 if ( scene.size() && Preferences::getInstance().expandStoryboard )
00710 g_idle_add( expansion_handler, storyboard->getView() );
00711
00712
00713 removeImages( &backup );
00714
00715 backup = icons;
00716 }
00717 else
00718 {
00719
00720 removeImages( &icons );
00721 }
00722
00723 if ( showScenesRunning == SCENE_RUNNING )
00724 showScenesRunning = SCENE_IDLE;
00725
00726 }
00727 GetFramePool( ) ->DoneWithFrame( &frame );
00728
00729 delete[] pixels;
00730 return NULL;
00731 }
00732
00733 void Storyboard::redraw( )
00734 {
00735 static pthread_t scenes_thread;
00736 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00737
00738 pthread_mutex_lock( &mutex );
00739 selection = -1;
00740
00741
00742
00743 if ( showScenesRunning == SCENE_RUNNING )
00744 {
00745 showScenesRunning = SCENE_RESTART;
00746 }
00747 else if ( showScenesRunning == SCENE_INIT )
00748 {
00749 showScenesRunning = SCENE_STARTING;
00750 pthread_create( &scenes_thread, NULL, showScenesThread, this );
00751 }
00752 else if ( showScenesRunning == SCENE_IDLE )
00753 {
00754 pthread_join( scenes_thread, NULL );
00755 showScenesRunning = SCENE_STARTING;
00756 pthread_create( &scenes_thread, NULL, showScenesThread, this );
00757 }
00758
00759 pthread_mutex_unlock( &mutex );
00760 }
00761
00762 void Storyboard::select( int scene )
00763 {
00764 if ( scene > -1 && scene < gtk_tree_model_iter_n_children( GTK_TREE_MODEL( model ), NULL ) )
00765 {
00766 GtkTreeIter iter;
00767 GtkTreeSelection* selection = gtk_tree_view_get_selection( view );
00768 if ( gtk_tree_model_iter_nth_child( GTK_TREE_MODEL( model ), &iter, NULL, scene ) )
00769 {
00770 GtkTreePath * path = gtk_tree_model_get_path( GTK_TREE_MODEL( model ), &iter );
00771 skipSelect = true;
00772 gtk_tree_selection_select_iter( selection, &iter );
00773 gtk_tree_view_scroll_to_cell( view, path, NULL, TRUE, 0.5, 0.0 );
00774 gtk_tree_path_free( path );
00775 skipSelect = false;
00776 }
00777 this->selection = scene;
00778 }
00779 }
00780
00781 void Storyboard::setSensitive( bool sensitive )
00782 {
00783 gtk_widget_set_sensitive( GTK_WIDGET( view ), sensitive ? TRUE : FALSE );
00784 }
00785
00786 void Storyboard::moveScene( unsigned int destScene )
00787 {
00788 std::cerr << "moving scene " << selection << " to scene " << destScene << std::endl;
00789 std::vector <int> scenes = common->getPageEditor() ->GetScene();
00790 int start = ( selection == 0 ) ? 0 : scenes[ selection - 1 ];
00791 int end = common->getPlayList() ->FindEndOfScene( start );
00792 int destFrame = 0;
00793
00794 common->getPageEditor() ->CopyFrames( start, end );
00795 common->getPlayList() ->Delete( start, end );
00796
00797 if ( destScene >= scenes.size() )
00798 {
00799 destFrame = common->getPlayList() ->GetNumFrames();
00800 }
00801 else if ( ( int ) destScene > selection )
00802 {
00803 common->getPageEditor() ->ResetBar();
00804 scenes = common->getPageEditor() ->GetScene();
00805 destFrame = scenes[ destScene - 2 ];
00806 }
00807 else if ( destScene > 0 )
00808 {
00809 common->getPageEditor() ->ResetBar();
00810 scenes = common->getPageEditor() ->GetScene();
00811 destFrame = scenes[ destScene - 1 ];
00812 }
00813
00814 common->getPageEditor() ->PasteFrames( destFrame );
00815 common->moveToFrame( destFrame );
00816
00817 redraw( );
00818 }
00819
00820 Storyboard *GetStoryboard( )
00821 {
00822 static Storyboard * singleton = new Storyboard( common );
00823 return singleton;
00824 }