checkbox with image arrow for playing item display
[rugen] / src / dv1394app.c
index b90ac6e..6de7d91 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * dv1394app.c -- GTK+ 2 dv1394d client demo
  * Copyright (C) 2002-2003 Charles Yates <charles.yates@pandora.be>
+ * Copyright (C) 2010 Dan Dennedy <dan@dennedy.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "interface.h"
 #include "support.h"
 #include "dv1394app.h"
-#include "util.h"
 #include "page.h"
 #include "gtkenhancedscale.h"
-#include <valerie/valerie_remote.h>
-#include <miracle/miracle_local.h>
+#include <mvcp/mvcp_remote.h>
+#include <melted/melted_local.h>
 
 
 /** Window close event.
@@ -51,16 +51,16 @@ static gboolean instance_connect( dv1394app this, char *server, char *port )
        if ( this->parser == NULL )
        {
                if ( strstr( server, ".conf" ) == NULL )
-                       this->parser = valerie_parser_init_remote( server, atoi( port ) );
+                       this->parser = mvcp_parser_init_remote( server, atoi( port ) );
                else
-                       this->parser = miracle_parser_init_local( );
+                       this->parser = melted_parser_init_local( );
 
-               this->command = valerie_init( this->parser );
+               this->command = mvcp_init( this->parser );
 
                if ( strstr( server, ".conf" ) != NULL )
-                       valerie_run( this->command, server );
+                       mvcp_run( this->command, server );
 
-               if ( valerie_connect( this->command ) == valerie_ok )
+               if ( mvcp_connect( this->command ) == mvcp_ok )
                {
                        struct timespec t = { 1, 0 };
                        nanosleep( &t, NULL );
@@ -70,10 +70,10 @@ static gboolean instance_connect( dv1394app this, char *server, char *port )
                }
                else
                {
-                       valerie_close( this->command );
-                       valerie_parser_close( this->parser );
+                       mvcp_close( this->command );
+                       mvcp_parser_close( this->parser );
                        this->parser = NULL;
-                       beep( );
+//                     beep( );
                }
        }
 
@@ -99,6 +99,10 @@ static gboolean on_connect_pressed( GtkWidget *button, gpointer user_data )
                instance_connect( this, server, port );
        }
        gtk_widget_destroy( this->connect );
+       this->guard = 1;
+       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_connect" ) ), TRUE );     
+       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_disconnect" ) ), FALSE ); 
+       this->guard = 0;
 
        return FALSE;
 }
@@ -109,6 +113,7 @@ static gboolean on_connect_pressed( GtkWidget *button, gpointer user_data )
 static gboolean on_cancel_pressed( GtkWidget *button, gpointer user_data )
 {
        dv1394app this = user_data;
+       if ( this->guard ) return FALSE;
        gtk_widget_destroy( this->connect );
        return FALSE;
 }
@@ -121,6 +126,7 @@ void on_item_connect_activate( GtkMenuItem *menuitem, gpointer user_data )
        dv1394app this = user_data;
        GtkWidget *widget;
        
+       if ( this->guard ) return;
        this->connect = create_window_connection( );
        
        /* Connection set up handling */
@@ -138,7 +144,14 @@ void on_item_connect_activate( GtkMenuItem *menuitem, gpointer user_data )
 void on_item_disconnect_activate( GtkMenuItem *menuitem, gpointer user_data )
 {
        dv1394app this = user_data;
+       
+       if ( this->guard ) return;
        dv1394app_disconnect( this );
+       
+       this->guard = 1;
+       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_connect" ) ), FALSE );    
+       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_disconnect" ) ), TRUE );  
+       this->guard = 0;
 }
 
 /** Main window - quit menu item selected.
@@ -149,19 +162,166 @@ void on_item_quit_activate( GtkMenuItem *menuitem, gpointer user_data )
        gtk_main_quit( );
 }
 
+static void playlist_open(dv1394app this, char* filename)
+{
+       FILE* f;
+
+       if( this->selected_unit >= 0 && this->command)
+       {
+               f = fopen(filename, "rt");
+               if (f)
+               {
+                       while( !feof(f) )
+                       {
+                               char* s;
+                               char l[PATH_MAX];
+
+                               /* load string */
+                               fgets(l, sizeof(l), f);
+
+                               /* remove newlines */
+                               if( (s = strchr(l, '\n')) ) *s = 0;
+                               if( (s = strchr(l, '\r')) ) *s = 0;
+                               if( (s = strchr(l, '\t')) ) *s = 0;
+
+                               /* check for empty line */
+                               if(l[0])
+                                       mvcp_unit_append( this->command, this->selected_unit, l, -1, -1 );
+                       }
+
+                       fclose(f);
+               }
+       }
+
+}
+
+static void playlist_save(dv1394app this, char* filename)
+{
+       int index;
+       mvcp_list_entry_t entry;
+       mvcp_list list;
+       FILE* f;
+
+       if( this->selected_unit >= 0 && this->command)
+       {
+               f = fopen(filename, "wt");
+               if (f)
+               {
+                       list = mvcp_list_init( this->command, this->selected_unit);
+
+                       if ( list )
+                       {
+                               for ( index = 0; list && index < mvcp_list_count( list ); index ++ )
+                               {
+                                       mvcp_list_get( list, index, &entry );
+                                       fprintf(f, "%s\n", entry.full);
+                               }
+                               mvcp_list_close( list );
+                       }
+
+                       fclose(f);
+               }
+       }
+}
+
+/** Main window - playlist open menu item selected.
+*/
+
+static void on_item_open_playlist_activate( GtkMenuItem *menuitem, gpointer user_data )
+{
+       dv1394app this = user_data;
+       GtkWidget *dialog;
+
+       dialog = gtk_file_chooser_dialog_new ("Open File",
+               GTK_WINDOW (this->window),
+               GTK_FILE_CHOOSER_ACTION_OPEN,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+               NULL);
+
+       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
+               (this->playlist_folder)?this->playlist_folder:getenv("HOME"));
+
+       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+       {
+               char *filename;
+
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+               playlist_open(this, filename);
+
+               if ( this->playlist_folder )
+                       g_free (this->playlist_folder);
+               this->playlist_folder = filename;
+               if ( this->playlist_folder )
+               {
+                       char* e = strrchr(this->playlist_folder, '/');
+                       if(e) *e = 0;
+               }
+       }
+
+       gtk_widget_destroy (dialog);
+}
+
+/** Main window - playlist save menu item selected.
+*/
+
+static void on_item_save_playlist_activate( GtkMenuItem *menuitem, gpointer user_data )
+{
+       dv1394app this = user_data;
+       GtkWidget *dialog;
+
+       dialog = gtk_file_chooser_dialog_new ("Save File",
+               GTK_WINDOW (this->window),
+               GTK_FILE_CHOOSER_ACTION_SAVE,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+               NULL);
+
+       gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+
+       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
+               (this->playlist_folder)?this->playlist_folder:getenv("HOME"));
+       gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "Untitled document");
+
+       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+       {
+               char *filename;
+
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+               playlist_save(this, filename);
+
+               if ( this->playlist_folder )
+                       g_free (this->playlist_folder);
+               this->playlist_folder = filename;
+               if ( this->playlist_folder )
+               {
+                       char* e = strrchr(this->playlist_folder, '/');
+                       if(e) *e = 0;
+               }
+       }
+
+       gtk_widget_destroy (dialog);
+}
+
 static gboolean on_page_switch_pressed( GtkWidget *button, gpointer user_data )
 {
        dv1394app this = user_data;
        int index = 0;
        GtkWidget *notebook = lookup_widget( button, "notebook1" );
-       
+
+       if ( this->guard ) return TRUE;
+       this->guard = 1;
+       for ( index = 0; index < this->page_count; index ++ )
+               gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( this->page_buttons[ index ] ), FALSE );                
        for ( index = 0; index < this->page_count; index ++ )
        {
+               gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( this->page_buttons[ index ] ), FALSE );                
                if ( this->page_buttons[ index ] == button )
                        break;
        }
-       
+       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( this->page_buttons[ index ] ), TRUE );
        gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook ), index );
+       this->guard = 0;
        
        return TRUE;
 }
@@ -170,59 +330,69 @@ static gboolean on_transport_pressed( GtkWidget *button, gpointer data )
 {
        int index = 0;
        dv1394app this = ( dv1394app )data;
-       valerie dv = dv1394app_get_command( this );
+       mvcp dv = dv1394app_get_command( this );
        int unit = dv1394app_get_selected_unit( this );
        
-       for ( index = 0; index < 11; index ++ )
+       for ( index = 0; index < TRANSPORT_BUTTONS_COUNT; index ++ )
                if ( this->buttons[ index ] == button )
                        break;
        
        switch( index )
        {
                case 0:
-                       valerie_unit_clip_goto( dv, unit, valerie_absolute, 0, 0 );
+                       mvcp_unit_clip_goto( dv, unit, mvcp_absolute, 0, 0 );
                        break;
                
                case 1:
-                       valerie_unit_goto( dv, unit, 0 );
+                       mvcp_unit_goto( dv, unit, 0 );
                        break;
                
                case 2:
-                       valerie_unit_rewind( dv, unit );
+                       mvcp_unit_rewind( dv, unit );
                        break;
                
                case 3:
-                       valerie_unit_step( dv, unit, -1 );
+                       mvcp_unit_step( dv, unit, -1 );
                        break;
                
                case 4:
-                       valerie_unit_pause( dv, unit );
+                       mvcp_unit_pause( dv, unit );
                        break;
                
                case 5:
-                       valerie_unit_play( dv, unit );
+                       mvcp_unit_play( dv, unit );
                        break;
                
                case 6:
-                       valerie_unit_stop( dv, unit );
+                       mvcp_unit_stop( dv, unit );
                        break;
                
                case 7:
-                       valerie_unit_step( dv, unit, 1 );
+                       mvcp_unit_step( dv, unit, 1 );
                        break;
                
                case 8:
-                       valerie_unit_fast_forward( dv, unit );
+                       mvcp_unit_fast_forward( dv, unit );
                        break;
                
                case 9:
-                       valerie_unit_clip_goto( dv, unit, valerie_relative, 1, 0 );
+                       mvcp_unit_clip_goto( dv, unit, mvcp_relative, 1, 0 );
                        break;
                
                case 10:
-                       valerie_unit_clip_goto( dv, unit, valerie_absolute, 9999, -1 );
+                       mvcp_unit_clip_goto( dv, unit, mvcp_absolute, 9999, -1 );
                        break;
                
+               case 11:
+                       mvcp_unit_set( dv, unit, "eof", "loop");
+                       this->eof[this->selected_unit] = 0;
+                       break;
+
+               case 12:
+                       mvcp_unit_set( dv, unit, "eof", "pause");
+                       this->eof[this->selected_unit] = 0;
+                       break;
+
                default:
                        break;
        }
@@ -232,7 +402,7 @@ static gboolean on_transport_pressed( GtkWidget *button, gpointer data )
 
 static void dv1394app_register_page( dv1394app this, page item )
 {
-       GtkWidget *toolbar = lookup_widget( this->window, "toolbar2" );
+       GtkWidget *toolbar = lookup_widget( this->window, "toolbar1" );
        GtkIconSize size = gtk_toolbar_get_icon_size( GTK_TOOLBAR( toolbar ) );
        GtkWidget *widget = lookup_widget( this->window, "notebook1" );
        GtkWidget *bin = gtk_frame_new( NULL );
@@ -246,7 +416,7 @@ static void dv1394app_register_page( dv1394app this, page item )
        gtk_widget_show( bin );
        
        page_get_toolbar_info( item, size, &widget, &label );
-       this->page_buttons[ this->page_count ] = gtk_toolbar_append_element( GTK_TOOLBAR ( toolbar ), GTK_TOOLBAR_CHILD_BUTTON, NULL, label, NULL, NULL, widget, NULL, NULL);
+       this->page_buttons[ this->page_count ] = gtk_toolbar_append_element( GTK_TOOLBAR ( toolbar ), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, label, NULL, NULL, widget, NULL, NULL);
        gtk_label_set_use_underline( GTK_LABEL(((GtkToolbarChild*)(g_list_last( GTK_TOOLBAR( toolbar )->children)->data))->label), TRUE);
        gtk_widget_show( widget );
        gtk_signal_connect( GTK_OBJECT( this->page_buttons[ this->page_count ] ), "clicked", GTK_SIGNAL_FUNC( on_page_switch_pressed ), this );
@@ -260,7 +430,7 @@ static GtkAdjustment *trim_adj[3];
 #define TRIM_ADJ_IN 1
 #define TRIM_ADJ_OUT 2
 
-void dv1394app_show_status( dv1394app this, valerie_status status )
+void dv1394app_show_status( dv1394app this, mvcp_status status )
 {
        int index = 0;
        for ( index = 0; index < this->page_count; index ++ )
@@ -286,12 +456,17 @@ void dv1394app_show_status( dv1394app this, valerie_status status )
                trim_adj[TRIM_ADJ_POS]->value = status->position;
                gtk_signal_emit_by_name( GTK_OBJECT(trim_adj[TRIM_ADJ_POS]), "value_changed" );
        }
+
+       gtk_widget_set_sensitive( lookup_widget( dv1394app_get_widget( this ), "transport_11" ),
+               this->eof[this->selected_unit] == 'p' );
+       gtk_widget_set_sensitive( lookup_widget( dv1394app_get_widget( this ), "transport_12" ),
+               this->eof[this->selected_unit] == 'l' );
 }
 
 static gboolean trim_pressed( GtkWidget *button, GdkEventButton *event, gpointer user_data )
 {
        dv1394app this = (dv1394app)user_data;
-       valerie_unit_pause( dv1394app_get_command( this ), this->selected_unit );
+       mvcp_unit_pause( dv1394app_get_command( this ), this->selected_unit );
        this->trim_in = -1;
        this->trim_out = -1;
        this->trim_in_use = 1;
@@ -303,9 +478,9 @@ static gboolean trim_released( GtkWidget *button, GdkEventButton *event, gpointe
        dv1394app this = (dv1394app)user_data;
        this->trim_in_use = 0;
        if ( this->trim_in != -1 )
-               valerie_unit_set_in( dv1394app_get_command( this ), this->selected_unit, this->trim_in );
+               mvcp_unit_set_in( dv1394app_get_command( this ), this->selected_unit, this->trim_in );
        if ( this->trim_out != -1 )
-               valerie_unit_set_out( dv1394app_get_command( this ), this->selected_unit, this->trim_out );
+               mvcp_unit_set_out( dv1394app_get_command( this ), this->selected_unit, this->trim_out );
        return TRUE;
 }
 
@@ -319,17 +494,17 @@ static gboolean on_trim_value_changed_event( GtkWidget *button, gpointer user_da
                
                if ( !strcmp( value, "position" ) )
                {
-                       valerie_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_POS]->value );
+                       mvcp_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_POS]->value );
                }
                else if ( !strcmp( value, "in" ) )
                {
                        this->trim_in = trim_adj[TRIM_ADJ_IN]->value;
-                       valerie_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_IN]->value );
+                       mvcp_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_IN]->value );
                }
                else if ( !strcmp( value, "out" ) )
                {
                        this->trim_out = trim_adj[TRIM_ADJ_OUT]->value;
-                       valerie_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_OUT]->value );
+                       mvcp_unit_goto( dv1394app_get_command( this ), this->selected_unit, trim_adj[TRIM_ADJ_OUT]->value );
                }
                
                gtk_widget_queue_draw (lookup_widget(this->window, "vbox_trim") );
@@ -355,23 +530,30 @@ dv1394app dv1394app_init( GtkWidget *window, char *instance )
                gtk_signal_connect( GTK_OBJECT( this->window ), "destroy", GTK_SIGNAL_FUNC( on_main_window_delete_event ), this );
 
                /* Menu item signal handling */
-               widget = lookup_widget( this->window, "item_connect" );
-               gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_connect_activate ), this );
+//             widget = lookup_widget( this->window, "item_connect" );
+//             gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_connect_activate ), this );
                widget = lookup_widget( this->window, "button_connect" );
                gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_connect_activate ), this );
-               widget = lookup_widget( this->window, "item_disconnect" );
-               gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_disconnect_activate ), this );
+//             widget = lookup_widget( this->window, "item_disconnect" );
+//             gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_disconnect_activate ), this );
                widget = lookup_widget( this->window, "button_disconnect" );
                gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_disconnect_activate ), this );
-               widget = lookup_widget( this->window, "item_quit" );
-               gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_quit_activate ), this );
-               widget = lookup_widget( this->window, "button_quit" );
-               gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_quit_activate ), this );
+//             widget = lookup_widget( this->window, "item_quit" );
+//             gtk_signal_connect( GTK_OBJECT( widget ), "activate", GTK_SIGNAL_FUNC( on_item_quit_activate ), this );
+//             widget = lookup_widget( this->window, "button_quit" );
+//             gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_quit_activate ), this );
+               widget = lookup_widget( this->window, "button_open_playlist" );
+               gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_open_playlist_activate ), this );
+               widget = lookup_widget( this->window, "button_save_playlist" );
+               gtk_signal_connect( GTK_OBJECT( widget ), "clicked", GTK_SIGNAL_FUNC( on_item_save_playlist_activate ), this );
+
 
                /* Initialise the pages. */
-               dv1394app_register_page( this, page_status_init( this ) );
-               dv1394app_register_page( this, page_clips_init( this ) );
+               dv1394app_register_page( this, page_operate_init( this ) );
                dv1394app_register_page( this, page_command_init( this ) );
+               this->guard = 1;
+               gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( this->page_buttons[ 0 ] ), TRUE );
+               this->guard = 0;
 
                /* Remove the empty page */
                widget = lookup_widget( this->window, "notebook1" );
@@ -381,7 +563,7 @@ dv1394app dv1394app_init( GtkWidget *window, char *instance )
                int index;
                GtkAccelGroup *accel_group = gtk_accel_group_new( );
                
-               for ( index = 0; index < 11; index ++ )
+               for ( index = 0; index < TRANSPORT_BUTTONS_COUNT; index ++ )
                {
                        char name[ 256 ];
                        sprintf( name, "transport_%d", index );
@@ -417,6 +599,9 @@ dv1394app dv1394app_init( GtkWidget *window, char *instance )
                        gtk_signal_connect( GTK_OBJECT( trim ), "button_release_event", GTK_SIGNAL_FUNC (trim_released), this );
                }
                this->seek_flag = 1;
+
+               this->playing[0] = create_pixbuf("empty_16x16.png");
+               this->playing[1] = create_pixbuf("item_playing_16x16_(Axialis_Team).png");
        }
 
        if ( instance != NULL )
@@ -427,7 +612,12 @@ dv1394app dv1394app_init( GtkWidget *window, char *instance )
                        *port ++ = '\0';
                else
                        port = "5250";
-               instance_connect( this, server, port );
+               this->guard = 1;
+               if ( instance_connect( this, server, port ) )
+                       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_connect" ) ), TRUE );
+               else
+                       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( lookup_widget( this->window, "button_disconnect" ) ), TRUE );
+               this->guard = 0;
                free( server );
        }
 
@@ -446,7 +636,7 @@ GtkWidget *dv1394app_get_widget( dv1394app this )
 /** Get the applications parser.
 */
 
-valerie_parser dv1394app_get_parser( dv1394app this )
+mvcp_parser dv1394app_get_parser( dv1394app this )
 {
        return this->parser;
 }
@@ -454,7 +644,7 @@ valerie_parser dv1394app_get_parser( dv1394app this )
 /** Return the command parser.
 */
 
-valerie dv1394app_get_command( dv1394app this )
+mvcp dv1394app_get_command( dv1394app this )
 {
        return this->command;
 }
@@ -498,9 +688,9 @@ void dv1394app_disconnect( dv1394app this )
        {
                for ( index = 0; index < this->page_count; index ++ )
                        page_on_disconnect( this->pages[ index ] );
-               valerie_close( this->command );
+               mvcp_close( this->command );
                this->command = NULL;
-               valerie_parser_close( this->parser );
+               mvcp_parser_close( this->parser );
                this->parser = NULL;
        }
 }
@@ -515,3 +705,25 @@ void dv1394app_close( dv1394app this )
                page_close( this->pages[ -- this->page_count ] );
        free( this );
 }
+
+char* frames2tc( int f, float fps, char* buf )
+{
+       int tc[4] = { 0, 0, 0, 0 };
+       float d;
+       int t;
+
+       if ( fps && f >= 0)
+       {
+               d = f / fps;
+               t = d;
+
+               tc[0] = (d - t) * fps;
+               tc[1] = t % 60; t /= 60;
+               tc[2] = t % 60; t /= 60;
+               tc[3] = t % 24;
+       }
+
+       sprintf(buf, "%.2d:%.2d:%.2d:%.2d", tc[3], tc[2], tc[1], tc[0]);
+
+       return buf;
+}