[nautilus-actions] Implement third tab of action conditions



commit 7548ab8c16b8742200f6a443c46ebef76abcb2b2
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Jun 30 18:22:33 2009 +0200

    Implement third tab of action conditions

 ChangeLog                           |   10 +-
 src/common/na-action-profile.c      |   25 +++++
 src/common/na-action-profile.h      |    1 +
 src/common/na-utils.c               |   21 ++++
 src/common/na-utils.h               |    1 +
 src/nact/nact-iprofile-conditions.c |  197 +++++++++++++++++++++++++++++++----
 src/nact/nautilus-actions-config.ui |    4 +-
 7 files changed, 231 insertions(+), 28 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d90eef8..38119fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,13 +3,13 @@
 	* src/common/na-action-profile.c:
 	* src/common/na-action-profile.h
 	(na_action_profile_set_matchcase, na_action_profile_set_mimetypes,
-	na_action_profile_set_isfiledir, na_action_profile_set_multiple):
-	New functions.
+	na_action_profile_set_isfiledir, na_action_profile_set_multiple,
+	na_action_profile_set_scheme): New functions.
 
 	* src/common/na-utils.c:
 	* src/common/na-utils.h (na_utils_gstring_joinv,
-	na_utils_string_list_to_text, na_utils_text_to_string_list):
-	New functions.
+	na_utils_string_list_to_text, na_utils_text_to_string_list,
+	na_utils_remove_ascii_from_string_list): New functions.
 
 	* src/nact/nact-action-conditions-editor.c:
 	Call _dispose functions when closing the window.
@@ -23,7 +23,7 @@
 	(nact_iprofile_conditions_dispose): New function.
 
 	* src/nact/nact-iprofile-conditions.c:
-	All first and second tabs are now implemented.
+	All three tabs are now implemented.
 
 	* src/nact/nact-utils.c:
 	* src/nact/nact-utils.h: Removed files.
diff --git a/src/common/na-action-profile.c b/src/common/na-action-profile.c
index 9af352d..0a75ff5 100644
--- a/src/common/na-action-profile.c
+++ b/src/common/na-action-profile.c
@@ -949,6 +949,31 @@ na_action_profile_set_multiple( NAActionProfile *profile, gboolean multiple )
 }
 
 /**
+ * Set the status of a scheme relative to this profile.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * @scheme: nae of the scheme.
+ *
+ * @selected: whether this scheme is candidate to this profile.
+ */
+void
+na_action_profile_set_scheme( NAActionProfile *profile, const gchar *scheme, gboolean selected )
+{
+	/*static const gchar *thisfn = "na_action_profile_set_scheme";*/
+
+	gboolean exist = na_utils_find_in_list( profile->private->schemes, scheme );
+	/*g_debug( "%s: scheme=%s exist=%s", thisfn, scheme, exist ? "True":"False" );*/
+
+	if( selected && !exist ){
+		profile->private->schemes = g_slist_prepend( profile->private->schemes, g_strdup( scheme ));
+	}
+	if( !selected && exist ){
+		profile->private->schemes = na_utils_remove_ascii_from_string_list( profile->private->schemes, scheme );
+	}
+}
+
+/**
  * Determines if the given profile is candidate to be displayed in the
  * Nautilus context menu, regarding the list of currently selected
  * items.
diff --git a/src/common/na-action-profile.h b/src/common/na-action-profile.h
index 35f75fa..b489530 100644
--- a/src/common/na-action-profile.h
+++ b/src/common/na-action-profile.h
@@ -111,6 +111,7 @@ void             na_action_profile_set_matchcase( NAActionProfile *profile, gboo
 void             na_action_profile_set_mimetypes( NAActionProfile *profile, GSList *mimetypes );
 void             na_action_profile_set_isfiledir( NAActionProfile *profile, gboolean isfile, gboolean isdir );
 void             na_action_profile_set_multiple( NAActionProfile *profile, gboolean multiple );
+void             na_action_profile_set_scheme( NAActionProfile *profile, const gchar *scheme, gboolean selected );
 
 gboolean         na_action_profile_is_candidate( const NAActionProfile *profile, GList *files );
 gchar           *na_action_profile_parse_parameters( const NAActionProfile *profile, GList *files );
diff --git a/src/common/na-utils.c b/src/common/na-utils.c
index 6aedb22..5f5128c 100644
--- a/src/common/na-utils.c
+++ b/src/common/na-utils.c
@@ -125,6 +125,27 @@ na_utils_free_string_list( GSList *list )
 }
 
 /**
+ * Removes a string from a GSList of strings.
+ *
+ * @list: the GSList to be updated.
+ *
+ * @text: string to remove.
+ */
+GSList *
+na_utils_remove_ascii_from_string_list( GSList *list, const gchar *text )
+{
+	GSList *il;
+	for( il = list ; il ; il = il->next ){
+		const gchar *istr = ( const gchar * ) il->data;
+		if( !g_ascii_strcasecmp( text, istr )){
+			list = g_slist_remove( list, ( gconstpointer ) istr );
+			return( list );
+		}
+	}
+	return( list );
+}
+
+/**
  * Concatenates a string list to a semi-colon-separated text.
  */
 gchar *
diff --git a/src/common/na-utils.h b/src/common/na-utils.h
index ac4fd3d..d852ce3 100644
--- a/src/common/na-utils.h
+++ b/src/common/na-utils.h
@@ -41,6 +41,7 @@ G_BEGIN_DECLS
 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 );
+GSList  *na_utils_remove_ascii_from_string_list( GSList *list, const gchar *text );
 void     na_utils_free_string_list( GSList *list );
 gchar   *na_utils_string_list_to_text( GSList *list );
 GSList  *na_utils_text_to_string_list( const gchar *text );
diff --git a/src/nact/nact-iprofile-conditions.c b/src/nact/nact-iprofile-conditions.c
index f3b78c4..9bc9b74 100644
--- a/src/nact/nact-iprofile-conditions.c
+++ b/src/nact/nact-iprofile-conditions.c
@@ -94,12 +94,17 @@ static void          on_scheme_selection_toggled( GtkCellRendererToggle *rendere
 static void          on_scheme_keyword_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, gpointer user_data );
 static void          on_scheme_desc_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, gpointer user_data );
 static void          on_scheme_list_selection_changed( GtkTreeSelection *selection, gpointer user_data );
-
+static void          on_add_scheme_clicked( GtkButton *button, gpointer user_data );
+static void          on_remove_scheme_clicked( GtkButton *button, gpointer user_data );
+static void          scheme_cell_edited( NactWindow *window, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text );
 static GtkTreeView  *get_schemes_tree_view( NactWindow *window );
 static GtkTreeModel *get_schemes_tree_model( NactWindow *window );
 static void          create_schemes_selection_list( NactWindow *window );
 static gboolean      get_action_schemes_list( GtkTreeModel* scheme_model, GtkTreePath *path, GtkTreeIter* iter, gpointer data );
 static GSList       *get_schemes_default_list( NactWindow *window );
+static gboolean      reset_schemes_list( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data );
+static void          set_action_schemes( gchar *scheme, GtkTreeModel *model );
+static GtkButton    *get_remove_button( NactWindow *window );
 
 GType
 nact_iprofile_conditions_get_type( void )
@@ -239,7 +244,6 @@ nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAActionProfile *prof
 
 	GtkTreeView *scheme_widget = get_schemes_tree_view( dialog );
 
-	/* TODO: set schemes */
 	GtkTreeViewColumn *column = gtk_tree_view_get_column( scheme_widget, SCHEMES_CHECKBOX_COLUMN );
 	GList *renderers = gtk_tree_view_column_get_cell_renderers( column );
 	nact_window_signal_connect( dialog, G_OBJECT( renderers->data ), "toggled", G_CALLBACK( on_scheme_selection_toggled ));
@@ -252,10 +256,17 @@ nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAActionProfile *prof
 	renderers = gtk_tree_view_column_get_cell_renderers( column );
 	nact_window_signal_connect( dialog, G_OBJECT( renderers->data ), "edited", G_CALLBACK( on_scheme_desc_edited ));
 
+	button = base_window_get_widget( BASE_WINDOW( dialog ), "AddSchemeButton" );
+	nact_window_signal_connect( dialog, G_OBJECT( button ), "clicked", G_CALLBACK( on_add_scheme_clicked ));
+	GtkButton *remove_button = get_remove_button( dialog );
+	nact_window_signal_connect( dialog, G_OBJECT( remove_button ), "clicked", G_CALLBACK( on_remove_scheme_clicked ));
+
 	nact_window_signal_connect( dialog, G_OBJECT( gtk_tree_view_get_selection( scheme_widget )), "changed", G_CALLBACK( on_scheme_list_selection_changed ));
 
-	/* TODO: add scheme */
-	/* TODO: remove scheme */
+	GtkTreeModel *scheme_model = get_schemes_tree_model( dialog );
+	gtk_tree_model_foreach( scheme_model, ( GtkTreeModelForeachFunc ) reset_schemes_list, NULL );
+	GSList *schemes = na_action_profile_get_schemes( profile );
+	g_slist_foreach( schemes, ( GFunc ) set_action_schemes, scheme_model );
 }
 
 void
@@ -743,23 +754,31 @@ get_multiple_button( NactWindow *window )
 static void
 on_scheme_selection_toggled( GtkCellRendererToggle *renderer, gchar *path, gpointer user_data )
 {
-	/*static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_selection_changed";
-	g_debug( "%s: renderer=%p, path=%s, user_data=%p", thisfn, renderer, path, user_data );*/
+	/*static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_selection_toggled";*/
+	/*g_debug( "%s: renderer=%p, path=%s, user_data=%p", thisfn, renderer, path, user_data );*/
 	g_assert( NACT_IS_WINDOW( user_data ));
 	NactWindow *dialog = NACT_WINDOW( user_data );
 
 	GtkTreeModel *model = get_schemes_tree_model( dialog );
-	GtkTreePath *tree_path = gtk_tree_path_new_from_string( path );
 	GtkTreeIter iter;
-	gboolean state;
+
+	GtkTreePath *tree_path = gtk_tree_path_new_from_string( path );
 	gtk_tree_model_get_iter( model, &iter, tree_path );
-	gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, &state, -1 );
-	gtk_list_store_set( GTK_LIST_STORE( model ), &iter, SCHEMES_CHECKBOX_COLUMN, !state, -1 );
 	gtk_tree_path_free( tree_path );
 
-	/* TODO set profile scheme selection */
-	/*NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));*/
-	/*na_action_set_label( edited, gtk_entry_get_text( entry ));*/
+	gboolean state;
+	gchar *scheme;
+	gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, &state, SCHEMES_KEYWORD_COLUMN, &scheme, -1 );
+
+	/* gtk_tree_model_get: returns the previous state
+	g_debug( "%s: gtk_tree_model_get returns keyword=%s state=%s", thisfn, scheme, state ? "True":"False" );*/
+
+	gtk_list_store_set( GTK_LIST_STORE( model ), &iter, SCHEMES_CHECKBOX_COLUMN, !state, -1 );
+
+	NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+	na_action_profile_set_scheme( edited, scheme, !state );
+
+	g_free( scheme );
 
 	v_field_modified( dialog );
 }
@@ -767,39 +786,129 @@ on_scheme_selection_toggled( GtkCellRendererToggle *renderer, gchar *path, gpoin
 static void
 on_scheme_keyword_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_keyword_edited";
-	g_debug( "%s: renderer=%p, path=%s, text=%s, user_data=%p", thisfn, renderer, path, text, user_data );
+	/*static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_keyword_edited";*/
+	/*g_debug( "%s: renderer=%p, path=%s, text=%s, user_data=%p", thisfn, renderer, path, text, user_data );*/
 
 	g_assert( NACT_IS_WINDOW( user_data ));
 	NactWindow *dialog = NACT_WINDOW( user_data );
 
+	gboolean state = FALSE;
+	gchar *old_text = NULL;
+	scheme_cell_edited( dialog, path, text, SCHEMES_KEYWORD_COLUMN, &state, &old_text );
+
+	if( state ){
+		/*g_debug( "%s: old_scheme=%s", thisfn, old_text );*/
+		NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+		na_action_profile_set_scheme( edited, old_text, FALSE );
+		na_action_profile_set_scheme( edited, text, TRUE );
+	}
+
+	g_free( old_text );
 	v_field_modified( dialog );
 }
 
 static void
 on_scheme_desc_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_desc_edited";
-	g_debug( "%s: renderer=%p, path=%s, text=%s, user_data=%p", thisfn, renderer, path, text, user_data );
+	/*static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_desc_edited";
+	g_debug( "%s: renderer=%p, path=%s, text=%s, user_data=%p", thisfn, renderer, path, text, user_data );*/
 
 	g_assert( NACT_IS_WINDOW( user_data ));
 	NactWindow *dialog = NACT_WINDOW( user_data );
 
-	v_field_modified( dialog );
+	scheme_cell_edited( dialog, path, text, SCHEMES_DESC_COLUMN, NULL, NULL );
 }
 
 static void
 on_scheme_list_selection_changed( GtkTreeSelection *selection, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_list_selection_changed";
-	g_debug( "%s: selection=%p, user_data=%p", thisfn, selection, user_data );
+	/*static const gchar *thisfn = "nact_iprofile_conditions_on_scheme_list_selection_changed";
+	g_debug( "%s: selection=%p, user_data=%p", thisfn, selection, user_data );*/
 
 	g_assert( NACT_IS_WINDOW( user_data ));
 	NactWindow *dialog = NACT_WINDOW( user_data );
 
+	GtkWidget *button = GTK_WIDGET( get_remove_button( dialog ));
+
+	if( gtk_tree_selection_count_selected_rows( selection )){
+		gtk_widget_set_sensitive( button, TRUE );
+	} else {
+		gtk_widget_set_sensitive( button, FALSE );
+	}
+}
+
+/* TODO: set the selection on the newly created scheme */
+static void
+on_add_scheme_clicked( GtkButton *button, gpointer user_data )
+{
+	GtkTreeModel *model = get_schemes_tree_model( NACT_WINDOW( user_data ));
+	GtkTreeIter row;
+	gtk_list_store_append( GTK_LIST_STORE( model ), &row );
+	gtk_list_store_set(
+			GTK_LIST_STORE( model ),
+			&row,
+			SCHEMES_CHECKBOX_COLUMN, FALSE,
+			/* i18n notes : scheme name set for a new entry in the scheme list */
+			SCHEMES_KEYWORD_COLUMN, _( "new-scheme" ),
+			SCHEMES_DESC_COLUMN, _( "New scheme description" ),
+			-1 );
+}
+
+static void
+on_remove_scheme_clicked( GtkButton *button, gpointer user_data )
+{
+	g_assert( NACT_IS_WINDOW( user_data ));
+	NactWindow *dialog = NACT_WINDOW( user_data );
+
+	GtkTreeView *listview = get_schemes_tree_view( dialog );
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( listview );
+	GtkTreeModel *model = get_schemes_tree_model( dialog );
+
+	GList *selected_values_path = NULL;
+	GtkTreeIter iter;
+	GtkTreePath *path;
+	GList *il;
+	gboolean toggle_state;
+	gchar *scheme;
+
+	selected_values_path = gtk_tree_selection_get_selected_rows( selection, &model );
+
+	for( il = selected_values_path ; il ; il = il->next ){
+		path = ( GtkTreePath * ) il->data;
+		gtk_tree_model_get_iter( model, &iter, path );
+		gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, &toggle_state, SCHEMES_KEYWORD_COLUMN, &scheme, -1 );
+		gtk_list_store_remove( GTK_LIST_STORE( model ), &iter );
+
+		if( toggle_state ){
+			NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+			na_action_profile_set_scheme( edited, scheme, FALSE );
+		}
+	}
+
+	g_list_foreach( selected_values_path, ( GFunc ) gtk_tree_path_free, NULL );
+	g_list_free( selected_values_path );
+
 	v_field_modified( dialog );
 }
 
+static void
+scheme_cell_edited( NactWindow *window, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text )
+{
+	GtkTreeModel *model = get_schemes_tree_model( window );
+	GtkTreeIter iter;
+
+	GtkTreePath *path = gtk_tree_path_new_from_string( path_string );
+	gtk_tree_model_get_iter( model, &iter, path );
+	gtk_tree_path_free( path );
+
+	if( state && old_text ){
+		gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, state, SCHEMES_KEYWORD_COLUMN, old_text, -1 );
+	}
+
+	gtk_list_store_set( GTK_LIST_STORE( model ), &iter, column, g_strdup( text ), -1 );
+
+}
+
 static GtkTreeView *
 get_schemes_tree_view( NactWindow *window )
 {
@@ -913,3 +1022,51 @@ get_schemes_default_list( NactWindow *window )
 
 	return( list );
 }
+
+static gboolean
+reset_schemes_list( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data )
+{
+	gtk_list_store_set( GTK_LIST_STORE( model ), iter, SCHEMES_CHECKBOX_COLUMN, FALSE, -1 );
+
+	return( FALSE ); /* don't stop looping */
+}
+
+static void
+set_action_schemes( gchar *scheme, GtkTreeModel *model )
+{
+	GtkTreeIter iter;
+	gboolean iter_ok = FALSE;
+	gboolean found = FALSE;
+	gchar *i_scheme;
+
+	iter_ok = gtk_tree_model_get_iter_first( model, &iter );
+
+	while( iter_ok && !found ){
+		gtk_tree_model_get( model, &iter, SCHEMES_KEYWORD_COLUMN, &i_scheme, -1 );
+
+		if( g_ascii_strcasecmp( scheme, i_scheme) == 0 ){
+			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, SCHEMES_CHECKBOX_COLUMN, TRUE, -1 );
+			found = TRUE;
+		}
+
+		g_free( i_scheme );
+		iter_ok = gtk_tree_model_iter_next( model, &iter );
+	}
+
+	if( !found ){
+		gtk_list_store_append( GTK_LIST_STORE( model ), &iter );
+		gtk_list_store_set(
+				GTK_LIST_STORE( model ),
+				&iter,
+				SCHEMES_CHECKBOX_COLUMN, TRUE,
+				SCHEMES_KEYWORD_COLUMN, scheme,
+				SCHEMES_DESC_COLUMN, "",
+				-1 );
+	}
+}
+
+static GtkButton *
+get_remove_button( NactWindow *window )
+{
+	return( GTK_BUTTON( base_window_get_widget( BASE_WINDOW( window ), "RemoveSchemeButton" )));
+}
diff --git a/src/nact/nautilus-actions-config.ui b/src/nact/nautilus-actions-config.ui
index dd71c27..51ab7f0 100644
--- a/src/nact/nautilus-actions-config.ui
+++ b/src/nact/nautilus-actions-config.ui
@@ -901,12 +901,11 @@
                         <property name="visible">True</property>
                         <property name="spacing">6</property>
                         <child>
-                          <object class="GtkButton" id="button7">
+                          <object class="GtkButton" id="AddSchemeButton">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="tooltip_text" translatable="yes">Click to add a new scheme.</property>
-                            <signal name="clicked" handler="action_add_scheme_clicked"/>
                             <child>
                               <object class="GtkImage" id="image16">
                                 <property name="visible">True</property>
@@ -928,7 +927,6 @@
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="tooltip_text" translatable="yes">Click to remove the selected scheme.</property>
-                            <signal name="clicked" handler="action_remove_scheme_clicked"/>
                             <child>
                               <object class="GtkImage" id="image17">
                                 <property name="visible">True</property>



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