[nautilus-actions] Implements IconBrowse and PathBrowse buttons



commit 5e71acadaccfeae3cad817ecbe6def9d15a86dba
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Jun 29 22:58:27 2009 +0200

    Implements IconBrowse and PathBrowse buttons

 ChangeLog                                |   25 +-
 src/common/na-action-profile.c           |   36 ++
 src/common/na-action-profile.h           |    2 +
 src/common/na-action.c                   |   56 ++-
 src/common/na-action.h                   |    1 +
 src/common/na-gconf.c                    |   71 +++-
 src/common/na-utils.c                    |   55 ++
 src/common/na-utils.h                    |    3 +
 src/nact/Makefile.am                     |    4 -
 src/nact/nact-action-conditions-editor.c |   34 +-
 src/nact/nact-editor.c                   |  804 ------------------------------
 src/nact/nact-editor.h                   |   50 --
 src/nact/nact-imenu-item.c               |   15 +
 src/nact/nact-imenu-item.h               |    2 +
 src/nact/nact-iprofile-conditions.c      |   37 ++-
 src/nact/nact-profile-editor.c           |  774 ----------------------------
 src/nact/nact-profile-editor.h           |   63 ---
 17 files changed, 296 insertions(+), 1736 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5945bd7..292db11 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,13 +2,18 @@
 
 	* src/common/na-action.c:
 	* src/common/na-action.h (na_action_set_tooltip,
-	na_action_set_icon, na_action_are_equal): New functions.
+	na_action_set_icon, na_action_are_equal, na_action_get_profile):
+	New functions.
+
+	* src/common/na-action.c
 	(na_action_new_with_profile): Provides a default profile name.
 	(na_action_duplicate): Provides a pointer to the duplicated action.
+	(na_action_are_equal): Implements profiles comparison.
 
 	* src/common/na-action-profile.c:
 	* src/common/na-action-profile.h (na_action_profile_set_path,
-	na_action_profile_set_parameters, na_action_profile_set_basenames):
+	na_action_profile_set_parameters, na_action_profile_set_basenames,
+	na_action_profile_are_equal):
 	New functions.
 
 	* src/common/na-action-profile.c (na_action_profile_new):
@@ -18,9 +23,17 @@
 	* src/common/na-action-profile.h (na_action_profile_duplicate):
 	The duplicated profile points to the duplicated action.
 
+	* src/common/na-gconf.c:
+	Defines an association table between GConf keys and property
+	names.
+
 	* src/common/na-iio-provider.c:
 	Fist try to write to initial provider.
 
+	* src/common/na-utils.c:
+	* src/common/na-utils.h (na_utils_find_in_list,
+	na_utils_string_lists_are_equal): New functions.
+
 	* src/nact/base-application.c (display_dlg):
 	New mutualized function.
 
@@ -30,10 +43,16 @@
 
 	* src/nact/nact-action-conditions-editor.c:
 	Update the dialog title if action has been modified.
+	Have Close or Cancel/Save buttons depending on action status.
+	Only save an action which has a not empty label.
+	Implements PathBrowse button.
 
 	* src/nact/nact-imenu-item.c:
 	* src/nact/nact-imenu-item.h (get_edited_action,
-	update_dialog_title): New functions.
+	update_dialog_title, nact_imenu_item_has_label): New functions.
+
+	* src/nact/nact-imenu-item.c:
+	Implements IconBrowse button.
 
 2009-06-28 Pierre Wieser <pwieser trychlos org>
 
diff --git a/src/common/na-action-profile.c b/src/common/na-action-profile.c
index 1b0ced4..56990bc 100644
--- a/src/common/na-action-profile.c
+++ b/src/common/na-action-profile.c
@@ -793,6 +793,42 @@ na_action_profile_get_schemes( const NAActionProfile *profile )
 	return( schemes );
 }
 
+/**
+ * Returns TRUE if the profile are the same, excluding action pointer.
+ *
+ * @first: a NAActionProfile.
+ *
+ * @second: another NAActionProfile, to be compared with @first.
+ */
+gboolean
+na_action_profile_are_equal( NAActionProfile *first, NAActionProfile *second )
+{
+	gboolean equal =
+		( g_utf8_collate( first->private->name, second->private->name ) == 0 ) &&
+		( g_utf8_collate( first->private->label, second->private->label ) == 0 ) &&
+		( g_utf8_collate( first->private->path, second->private->path ) == 0 ) &&
+		( g_utf8_collate( first->private->parameters, second->private->parameters ) == 0 );
+
+	if( equal ){
+		equal = (( first->private->accept_multiple_files && second->private->accept_multiple_files ) ||
+				( !first->private->accept_multiple_files && !second->private->accept_multiple_files ));
+	}
+	if( equal ){
+		equal = (( first->private->is_dir && second->private->is_dir ) ||
+				( !first->private->is_dir && !second->private->is_dir ));
+	}
+	if( equal ){
+		equal = (( first->private->is_file && second->private->is_file ) ||
+				( !first->private->is_file && !second->private->is_file ));
+	}
+	if( equal ){
+		equal = na_utils_string_lists_are_equal( first->private->basenames, second->private->basenames ) &&
+				na_utils_string_lists_are_equal( first->private->mimetypes, second->private->mimetypes ) &&
+				na_utils_string_lists_are_equal( first->private->schemes, second->private->schemes );
+	}
+	return( equal );
+}
+
 static int
 validate_schemes( GSList* schemes2test, NautilusFileInfo* file )
 {
diff --git a/src/common/na-action-profile.h b/src/common/na-action-profile.h
index 968dd37..978ca24 100644
--- a/src/common/na-action-profile.h
+++ b/src/common/na-action-profile.h
@@ -102,6 +102,8 @@ gboolean         na_action_profile_get_is_file( const NAActionProfile *profile )
 gboolean         na_action_profile_get_multiple( const NAActionProfile *profile );
 GSList          *na_action_profile_get_schemes( const NAActionProfile *profile );
 
+gboolean         na_action_profile_are_equal( NAActionProfile *first, NAActionProfile *second );
+
 void             na_action_profile_set_path( NAActionProfile *profile, const gchar *path );
 void             na_action_profile_set_parameters( NAActionProfile *profile, const gchar *parameters );
 void             na_action_profile_set_basenames( NAActionProfile *profile, GSList *basenames );
diff --git a/src/common/na-action.c b/src/common/na-action.c
index 0d69519..b83532a 100644
--- a/src/common/na-action.c
+++ b/src/common/na-action.c
@@ -710,12 +710,66 @@ na_action_are_equal( NAAction *first, NAAction *second )
 		equal = ( g_slist_length( first->private->profiles ) == g_slist_length( second->private->profiles ));
 	}
 	if( equal ){
-		/* TODO: compare profiles */
+		GSList *ip;
+		for( ip = first->private->profiles ; ip && equal ; ip = ip->next ){
+			NAActionProfile *first_profile = NA_ACTION_PROFILE( ip->data );
+			gchar *first_name = na_action_profile_get_name( first_profile );
+			NAActionProfile *second_profile = NA_ACTION_PROFILE( na_action_get_profile( second, first_name ));
+			if( second_profile ){
+				equal = na_action_profile_are_equal( first_profile, second_profile );
+			} else {
+				equal = FALSE;
+			}
+			g_free( first_name );
+		}
+	}
+	if( equal ){
+		GSList *ip;
+		for( ip = second->private->profiles ; ip && equal ; ip = ip->next ){
+			NAActionProfile *second_profile = NA_ACTION_PROFILE( ip->data );
+			gchar *second_name = na_action_profile_get_name( second_profile );
+			NAActionProfile *first_profile = NA_ACTION_PROFILE( na_action_get_profile( first, second_name ));
+			if( first_profile ){
+				equal = na_action_profile_are_equal( first_profile, second_profile );
+			} else {
+				equal = FALSE;
+			}
+			g_free( second_name );
+		}
 	}
 	return( equal );
 }
 
 /**
+ * Returns the profile with the required name.
+ *
+ * @action: the action whose profiles has to be retrieved.
+ *
+ * @name: name of the required profile.
+ *
+ * The returned pointer is owned by the @action object ; the caller
+ * should not try to free or unref it.
+ */
+GObject *
+na_action_get_profile( const NAAction *action, const gchar *name )
+{
+	g_assert( NA_IS_ACTION( action ));
+	GObject *found = NULL;
+	GSList *ip;
+
+	for( ip = action->private->profiles ; ip && !found ; ip = ip->next ){
+		NAActionProfile *iprofile = NA_ACTION_PROFILE( ip->data );
+		gchar *iname = na_action_profile_get_name( iprofile );
+		if( !g_ascii_strcasecmp( name, iname )){
+			found = G_OBJECT( iprofile );
+		}
+		g_free( iname );
+	}
+
+	return( found );
+}
+
+/**
  * Returns the list of profiles of the actions as a GSList of
  * NAActionProfile GObjects.
  *
diff --git a/src/common/na-action.h b/src/common/na-action.h
index fac3c3c..18d5dcf 100644
--- a/src/common/na-action.h
+++ b/src/common/na-action.h
@@ -99,6 +99,7 @@ void      na_action_set_icon( NAAction *action, const gchar *icon_name );
 
 gboolean  na_action_are_equal( NAAction *first, NAAction *second );
 
+GObject  *na_action_get_profile( const NAAction *action, const gchar *name );
 GSList   *na_action_get_profiles( const NAAction *action );
 void      na_action_set_profiles( NAAction *action, GSList *list );
 void      na_action_free_profiles( GSList *list );
diff --git a/src/common/na-gconf.c b/src/common/na-gconf.c
index ccd6a98..7029d2a 100644
--- a/src/common/na-gconf.c
+++ b/src/common/na-gconf.c
@@ -70,6 +70,29 @@ enum {
 
 #define PROP_NOTIFIED_STR				"to-be-notified"
 
+/* correspondance table for association of GConf entry keys to action
+ * and profile properties
+ */
+typedef struct {
+	gchar *gconfkey;
+	gchar *property;
+}
+	KeyToPropertyStruct;
+
+static KeyToPropertyStruct st_key_property[] = {
+	{ ACTION_PROFILE_LABEL_ENTRY, PROP_PROFILE_LABEL_STR           },
+	{ ACTION_PATH_ENTRY         , PROP_PROFILE_PATH_STR            },
+	{ ACTION_PARAMETERS_ENTRY   , PROP_PROFILE_PARAMETERS_STR      },
+	{ ACTION_BASENAMES_ENTRY    , PROP_PROFILE_BASENAMES_STR       },
+	{ ACTION_MATCHCASE_ENTRY    , PROP_PROFILE_MATCHCASE_STR       },
+	{ ACTION_MIMETYPES_ENTRY    , PROP_PROFILE_MIMETYPES_STR       },
+	{ ACTION_ISFILE_ENTRY       , PROP_PROFILE_ISFILE_STR          },
+	{ ACTION_ISDIR_ENTRY        , PROP_PROFILE_ISDIR_STR           },
+	{ ACTION_MULTIPLE_ENTRY     , PROP_PROFILE_ACCEPT_MULTIPLE_STR },
+	{ ACTION_SCHEMES_ENTRY      , PROP_PROFILE_SCHEMES_STR         },
+	{                       NULL, NULL }
+};
+
 static GObjectClass *st_parent_class = NULL;
 
 static GType          register_type( void );
@@ -91,6 +114,7 @@ static GSList        *load_keys_values( const NAGConf *gconf, const gchar *path
 static void           free_keys_values( GSList *entries );
 static gchar         *path_to_key( const gchar *path );
 static void           set_item_properties( NAObject *object, GSList *properties );
+static const gchar   *key_to_property( const gchar *key );
 static gboolean       set_action_properties( NAGConf *gconf, NAAction *action, GSList *properties );
 static void           load_v1_properties( NAAction *action, const gchar *version, GSList *properties );
 static gchar         *search_for_str( GSList *properties, const gchar *profile, const gchar *key );
@@ -558,19 +582,24 @@ set_item_properties( NAObject *object, GSList *properties )
 		GConfEntry *entry = ( GConfEntry * ) item->data;
 		NAPivotNotify *npn = entry_to_notify( entry );
 		if( npn->type ){
-
-			switch( npn->type ){
-				case NA_PIVOT_STR:
-				case NA_PIVOT_BOOL:
-				case NA_PIVOT_STRLIST:
-					g_object_set( G_OBJECT( object ), npn->parm, npn->data, NULL );
-					break;
-
-				default:
-					g_debug( "%s: uuid='%s', profile='%s', parm='%s', type=%d, data=%p",
-							thisfn, npn->uuid, npn->profile, npn->parm, npn->type, npn->data );
-					g_assert_not_reached();
-					break;
+			const gchar *property_str = key_to_property( npn->parm );
+
+			if( property_str ){
+				switch( npn->type ){
+					case NA_PIVOT_STR:
+					case NA_PIVOT_BOOL:
+					case NA_PIVOT_STRLIST:
+						g_object_set( G_OBJECT( object ), property_str, npn->data, NULL );
+						break;
+
+					default:
+						g_debug( "%s: uuid='%s', profile='%s', parm='%s', type=%d, data=%p",
+								thisfn, npn->uuid, npn->profile, npn->parm, npn->type, npn->data );
+						g_assert_not_reached();
+						break;
+				}
+			} else {
+				g_warning( "%s: no property found for %s GConf key", thisfn, npn->parm );
 			}
 		}
 
@@ -578,6 +607,22 @@ set_item_properties( NAObject *object, GSList *properties )
 	}
 }
 
+static const gchar *
+key_to_property( const gchar *key )
+{
+	int i;
+	gchar *property = NULL;
+
+	for( i=0 ; st_key_property[i].gconfkey && !property ; ++i ){
+		if( !g_ascii_strcasecmp( st_key_property[i].gconfkey, key )){
+			property = st_key_property[i].property;
+			break;
+		}
+	}
+
+	return( property );
+}
+
 /*
  * set the item properties into the action, dealing with successive
  * versions
diff --git a/src/common/na-utils.c b/src/common/na-utils.c
index 5606b68..99d0d32 100644
--- a/src/common/na-utils.c
+++ b/src/common/na-utils.c
@@ -35,6 +35,61 @@
 #include "na-utils.h"
 
 /**
+ * Search for a string in a string list.
+ *
+ * @list: the GSList of strings to be searched.
+ *
+ * @str: the searched string.
+ *
+ * Returns TRUE if the string has been found in list.
+ */
+gboolean
+na_utils_find_in_list( GSList *list, const gchar *str )
+{
+	GSList *il;
+
+	for( il = list ; il ; il = il->next ){
+		const gchar *istr = ( const gchar * ) il->data;
+		if( !g_utf8_collate( str, istr )){
+			return( TRUE );
+		}
+	}
+
+	return( FALSE );
+}
+
+/**
+ * Compare two string lists.
+ *
+ * @first: a GSList of strings.
+ *
+ * @second: another GSList of strings to be compared with @first.
+ *
+ * Returns TRUE if the two lists have same content.
+ */
+gboolean
+na_utils_string_lists_are_equal( GSList *first, GSList *second )
+{
+	GSList *il;
+
+	for( il = first ; il ; il = il->next ){
+		const gchar *str = ( const gchar * ) il->data;
+		if( !na_utils_find_in_list( second, str )){
+			return( FALSE );
+		}
+	}
+
+	for( il = second ; il ; il = il->next ){
+		const gchar *str = ( const gchar * ) il->data;
+		if( !na_utils_find_in_list( first, str )){
+			return( FALSE );
+		}
+	}
+
+	return( TRUE );
+}
+
+/**
  * Duplicates a GSList of strings.
  *
  * @list: the GSList to be duplicated.
diff --git a/src/common/na-utils.h b/src/common/na-utils.h
index 4edf8ca..d14792a 100644
--- a/src/common/na-utils.h
+++ b/src/common/na-utils.h
@@ -38,6 +38,9 @@ G_BEGIN_DECLS
 /*
  * Some functions to ease the GSList list manipulations.
  */
+gboolean na_utils_find_in_list( GSList *list, const gchar *str );
+
+gboolean na_utils_string_lists_are_equal( GSList *first, GSList *second );
 
 GSList  *na_utils_duplicate_string_list( GSList *list );
 
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index f5da17d..5b3ba58 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -67,10 +67,6 @@ nautilus_actions_config_SOURCES = \
 	nact-prefs.h										\
 	nact-import-export.c								\
 	nact-import-export.h								\
-	nact-profile-editor.c								\
-	nact-profile-editor.h								\
-	nact-editor.c										\
-	nact-editor.h										\
 	nact-window.c										\
 	nact-window.h										\
 	$(NULL)
diff --git a/src/nact/nact-action-conditions-editor.c b/src/nact/nact-action-conditions-editor.c
index 620a99f..11c7268 100644
--- a/src/nact/nact-action-conditions-editor.c
+++ b/src/nact/nact-action-conditions-editor.c
@@ -73,9 +73,8 @@ static void     on_initial_load_dialog( BaseWindow *dialog );
 static void     on_runtime_init_dialog( BaseWindow *dialog );
 static void     on_all_widgets_showed( BaseWindow *dialog );
 static void     setup_dialog_title( NactActionConditionsEditor *dialog, gboolean is_modified );
-static void     setup_buttons( NactActionConditionsEditor *dialog, gboolean is_modified );
+static void     setup_buttons( NactActionConditionsEditor *dialog, gboolean can_save );
 static void     on_modified_field( NactWindow *dialog );
-/*static void     on_save_button_clicked( GtkButton *button, gpointer user_data );*/
 static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
 
 static GObject *get_edited_action( NactWindow *window );
@@ -325,11 +324,9 @@ on_runtime_init_dialog( BaseWindow *dialog )
 
 	nact_imenu_item_runtime_init( NACT_WINDOW( window ), window->private->edited );
 
+	/*na_object_dump( NA_OBJECT( window->private->edited ));*/
 	NAActionProfile *profile = NA_ACTION_PROFILE( na_action_get_profiles( window->private->edited )->data );
 	nact_iprofile_conditions_runtime_init( NACT_WINDOW( window ), profile );
-
-	/*GtkWidget *button = base_window_get_widget( dialog, "SaveButton" );
-	nact_window_signal_connect( NACT_WINDOW( dialog ), G_OBJECT( button ), "clicked", G_CALLBACK( on_save_button_clicked ));*/
 }
 
 static void
@@ -361,35 +358,37 @@ setup_dialog_title( NactActionConditionsEditor *dialog, gboolean is_modified )
  * rationale:
  * while the action is not modified, only the cancel button is activated
  * when the action has been modified, we have a save and a cancel buttons
+ * + a label is mandatory to enable the save button
  */
 static void
-setup_buttons( NactActionConditionsEditor *dialog, gboolean is_modified )
+setup_buttons( NactActionConditionsEditor *dialog, gboolean can_save )
 {
 	GtkWidget *cancel_button = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
 	GtkWidget *close_button = gtk_button_new_from_stock( GTK_STOCK_CLOSE );
 	GtkWidget *button = base_window_get_widget( BASE_WINDOW( dialog ), "CancelButton" );
-	gtk_button_set_label( GTK_BUTTON( button ), is_modified ? _( "_Cancel" ) : _( "_Close" ));
-	gtk_button_set_image( GTK_BUTTON( button ), is_modified ? gtk_button_get_image( GTK_BUTTON( cancel_button )) : gtk_button_get_image( GTK_BUTTON( close_button )));
+	gtk_button_set_label( GTK_BUTTON( button ), can_save ? _( "_Cancel" ) : _( "_Close" ));
+	gtk_button_set_image( GTK_BUTTON( button ), can_save ? gtk_button_get_image( GTK_BUTTON( cancel_button )) : gtk_button_get_image( GTK_BUTTON( close_button )));
 	gtk_widget_destroy( cancel_button );
 	gtk_widget_destroy( close_button );
 
 	button = base_window_get_widget( BASE_WINDOW( dialog ), "SaveButton" );
-	gtk_widget_set_sensitive( button, is_modified );
+	gtk_widget_set_sensitive( button, can_save );
 }
 
 static void
 on_modified_field( NactWindow *window )
 {
-	static const gchar *thisfn = "nact_action_conditions_editor_on_modified_field";
+	/*static const gchar *thisfn = "nact_action_conditions_editor_on_modified_field";*/
 
 	g_assert( NACT_IS_ACTION_CONDITIONS_EDITOR( window ));
 	NactActionConditionsEditor *dialog = ( NACT_ACTION_CONDITIONS_EDITOR( window ));
 
 	gboolean is_modified = is_edited_modified( dialog );
-	g_debug( "%s: is_modified=%s", thisfn, is_modified ? "True":"False" );
-
+	/*g_debug( "%s: is_modified=%s", thisfn, is_modified ? "True":"False" );*/
 	setup_dialog_title( dialog, is_modified );
-	setup_buttons( dialog, is_modified );
+
+	gboolean can_save = is_modified && nact_imenu_item_has_label( window );
+	setup_buttons( dialog, can_save );
 }
 
 static void
@@ -404,15 +403,6 @@ on_all_widgets_showed( BaseWindow *dialog )
 	nact_imenu_item_all_widgets_showed( NACT_WINDOW( dialog ));
 }
 
-/*static void
-on_save_button_clicked( GtkButton *button, gpointer user_data )
-{
-	static const gchar *thisfn = "nact_action_conditions_editor_on_save_button_clicked";
-	g_debug( "%s: button=%p, user_data=%p", thisfn, button, user_data );
-
-	g_signal_stop_emission_by_name( user_data, "clicked" );
-}*/
-
 static gboolean
 on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
 {
diff --git a/src/nact/nact-imenu-item.c b/src/nact/nact-imenu-item.c
index bc3848b..1325117 100644
--- a/src/nact/nact-imenu-item.c
+++ b/src/nact/nact-imenu-item.c
@@ -182,6 +182,9 @@ nact_imenu_item_runtime_init( NactWindow *dialog, NAAction *action )
 	nact_window_signal_connect( dialog, G_OBJECT( button ), "clicked", G_CALLBACK( on_icon_browse ));
 }
 
+/**
+ * A good place to set focus to the first visible field.
+ */
 void
 nact_imenu_item_all_widgets_showed( NactWindow *dialog )
 {
@@ -189,6 +192,18 @@ nact_imenu_item_all_widgets_showed( NactWindow *dialog )
 	gtk_widget_grab_focus( label_widget );
 }
 
+/**
+ * An action can only be written if it has at least a label.
+ * Returns TRUE if the label of the action is not empty.
+ */
+gboolean
+nact_imenu_item_has_label( NactWindow *window )
+{
+	GtkWidget *label_widget = base_window_get_widget( BASE_WINDOW( window ), "MenuLabelEntry" );
+	const gchar *label = gtk_entry_get_text( GTK_ENTRY( label_widget ));
+	return( g_utf8_strlen( label, -1 ) > 0 );
+}
+
 static GObject *
 v_get_edited_action( NactWindow *window )
 {
diff --git a/src/nact/nact-imenu-item.h b/src/nact/nact-imenu-item.h
index b7f9c87..7f8f136 100644
--- a/src/nact/nact-imenu-item.h
+++ b/src/nact/nact-imenu-item.h
@@ -68,6 +68,8 @@ void     nact_imenu_item_initial_load( NactWindow *dialog, NAAction *action );
 void     nact_imenu_item_runtime_init( NactWindow *dialog, NAAction *action );
 void     nact_imenu_item_all_widgets_showed( NactWindow *dialog );
 
+gboolean nact_imenu_item_has_label( NactWindow *window );
+
 G_END_DECLS
 
 #endif /* __NACT_IMENU_ITEM_H__ */
diff --git a/src/nact/nact-iprofile-conditions.c b/src/nact/nact-iprofile-conditions.c
index ca3ae0b..118761a 100644
--- a/src/nact/nact-iprofile-conditions.c
+++ b/src/nact/nact-iprofile-conditions.c
@@ -70,6 +70,7 @@ static void          create_schemes_selection_list( NactWindow *window );
 static GSList       *get_schemes_default_list( NactWindow *window );
 
 static void          on_path_changed( GtkEntry *entry, gpointer user_data );
+static void          on_path_browse( GtkButton *button, gpointer user_data );
 static void          on_parameters_changed( GtkEntry *entry, gpointer user_data );
 static void          on_basenames_changed( GtkEntry *entry, gpointer user_data );
 static void          on_scheme_selection_toggled( GtkCellRendererToggle *renderer, gchar *path, gpointer user_data );
@@ -162,12 +163,12 @@ nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAActionProfile *prof
 	GtkWidget *path_widget = base_window_get_widget( BASE_WINDOW( dialog ), "CommandPathEntry" );
 	nact_window_signal_connect( dialog, G_OBJECT( path_widget ), "changed", G_CALLBACK( on_path_changed ));
 	gchar *path = na_action_profile_get_path( profile );
+	g_debug( "%s: path=%s", thisfn, path );
 	gtk_entry_set_text( GTK_ENTRY( path_widget ), path );
 	g_free( path );
 
 	GtkWidget *button = base_window_get_widget( BASE_WINDOW( dialog ), "PathBrowseButton" );
-	/* TODO: implement path browse button */
-	gtk_widget_set_sensitive( button, FALSE );
+	nact_window_signal_connect( dialog, G_OBJECT( button ), "clicked", G_CALLBACK( on_path_browse ));
 
 	GtkWidget *parameters_widget = base_window_get_widget( BASE_WINDOW( dialog ), "CommandParamsEntry" );
 	nact_window_signal_connect( dialog, G_OBJECT( parameters_widget ), "changed", G_CALLBACK( on_parameters_changed ));
@@ -375,6 +376,7 @@ get_schemes_default_list( NactWindow *window )
 	return( list );
 }
 
+/* TODO: update label example when path or parameters changed */
 static void
 on_path_changed( GtkEntry *entry, gpointer user_data )
 {
@@ -387,6 +389,37 @@ on_path_changed( GtkEntry *entry, gpointer user_data )
 	v_field_modified( dialog );
 }
 
+/* TODO: keep trace of last browsed dir */
+static void
+on_path_browse( GtkButton *button, gpointer user_data )
+{
+	g_assert( NACT_IS_IPROFILE_CONDITIONS( user_data ));
+	gboolean set_current_location = FALSE;
+
+	GtkWidget *dialog = gtk_file_chooser_dialog_new(
+			_( "Choosing a command" ),
+			NULL,
+			GTK_FILE_CHOOSER_ACTION_OPEN,
+			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+			GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+			NULL
+			);
+
+	GtkWidget *path_widget = base_window_get_widget( BASE_WINDOW( user_data ), "CommandPathEntry" );
+	const gchar *path = gtk_entry_get_text( GTK_ENTRY( path_widget ));
+	if( path && strlen( path )){
+		set_current_location = gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( dialog ), path );
+	}
+
+	if( gtk_dialog_run( GTK_DIALOG( dialog )) == GTK_RESPONSE_ACCEPT ){
+		gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ));
+		gtk_entry_set_text( GTK_ENTRY( path_widget ), filename );
+	    g_free (filename);
+	  }
+
+	gtk_widget_destroy( dialog );
+}
+
 static void
 on_parameters_changed( GtkEntry *entry, gpointer user_data )
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]