[nautilus-actions] Implement desktop choice



commit f213e7de7ac20098ad9efd82f3bab1d74946fd57
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Jun 17 00:05:33 2010 +0200

    Implement desktop choice

 ChangeLog                        |   12 +
 src/api/na-core-utils.h          |    1 +
 src/api/na-icontext.h            |    2 +
 src/api/na-object-api.h          |    2 +
 src/core/na-core-utils.c         |   28 ++
 src/core/na-icontext.c           |   66 +++-
 src/nact/nact-ienvironment-tab.c |  605 ++++++++++++++++++++++++++++----------
 7 files changed, 544 insertions(+), 172 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3d3b69e..7fe953b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2010-06-16 Pierre Wieser <pwieser trychlos org>
 
+	* src/api/na-core-utils.h:
+	* src/core/na-core-utils.c (na_core_utils_slist_setup_element): New function.
+
+	* src/api/na-icontext.h:
+	* src/core/na-icontext.c (na_icontext_set_only_desktop,	na_icontext_set_not_desktop):
+	New functions.
+
+	* src/api/na-object-api.h (na_object_set_only_desktop, na_object_set_not_desktop):
+	New macros.
+
+	* src/nact/nact-ienvironment-tab.c: Implement desktop choice.
+
 	* src/nact/nact-icapabilities-tab.c:
 	* src/nact/nautilus-actions-config-tool.ui: Review NactICapabilitiesTab page.
 
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index edeaa08..e23c110 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -64,6 +64,7 @@ GSList  *na_core_utils_slist_remove_ascii( GSList *list, const gchar *text );
 GSList  *na_core_utils_slist_remove_utf8( GSList *list, const gchar *string );
 gchar  **na_core_utils_slist_to_array( GSList *slist );
 gchar   *na_core_utils_slist_to_text( GSList *list );
+GSList  *na_core_utils_slist_setup_element( GSList *list, const gchar *element, gboolean set );
 gboolean na_core_utils_slist_find( GSList *list, const gchar *str );
 gboolean na_core_utils_slist_find_negated( GSList *list, const gchar *str );
 gboolean na_core_utils_slist_are_equal( GSList *a, GSList *b );
diff --git a/src/api/na-icontext.h b/src/api/na-icontext.h
index a22971b..05e4f50 100644
--- a/src/api/na-icontext.h
+++ b/src/api/na-icontext.h
@@ -90,6 +90,8 @@ gboolean na_icontext_is_all_mimetypes( const NAIContext *object );
 void     na_icontext_read_done       ( NAIContext *object );
 
 void     na_icontext_set_scheme      ( NAIContext *object, const gchar *scheme, gboolean selected );
+void     na_icontext_set_only_desktop( NAIContext *object, const gchar *desktop, gboolean selected );
+void     na_icontext_set_not_desktop ( NAIContext *object, const gchar *desktop, gboolean selected );
 void     na_icontext_replace_folder  ( NAIContext *object, const gchar *old, const gchar *new );
 
 G_END_DECLS
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index fd07f50..01a489c 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -194,7 +194,9 @@ G_BEGIN_DECLS
 #define na_object_set_scheme( obj, scheme, add )		na_icontext_set_scheme( NA_ICONTEXT( obj ), ( const gchar * )( scheme ), ( add ))
 #define na_object_set_schemes( obj, schemes )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SCHEMES, ( const void * )( schemes ))
 #define na_object_set_only_show_in( obj, list )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ONLY_SHOW, ( const void * )( list ))
+#define na_object_set_only_desktop( obj, desktop, add )	na_icontext_set_only_desktop( NA_ICONTEXT( obj ), ( const gchar * )( desktop ), ( add ))
 #define na_object_set_not_show_in( obj, list )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_NOT_SHOW, ( const void * )( list ))
+#define na_object_set_not_desktop( obj, desktop, add )	na_icontext_set_not_desktop( NA_ICONTEXT( obj ), ( const gchar * )( desktop ), ( add ))
 #define na_object_set_try_exec( obj, exec )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TRY_EXEC, ( const void * )( exec ))
 #define na_object_set_show_if_registered( obj, name )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SHOW_IF_REGISTERED, ( const void * )( name ))
 #define na_object_set_show_if_true( obj, exec )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SHOW_IF_TRUE, ( const void * )( exec ))
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index 8cdbcd3..a0e92bb 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -447,6 +447,34 @@ na_core_utils_slist_to_text( GSList *strlist )
 }
 
 /**
+ * na_core_utils_slist_setup_element:
+ * @list: the GSList of strings to be setup.
+ * @element: the string to add to or remove of the list.
+ * @set: whether the @element should be set or removed.
+ *
+ * Setup the @list so that the @element is once in the @list if @set is %TRUE,
+ * or not if @set is %FALSE.
+ *
+ * Returns: the updated @list.
+ */
+GSList *
+na_core_utils_slist_setup_element( GSList *list, const gchar *element, gboolean set )
+{
+	gboolean exist;
+
+	exist = na_core_utils_slist_find( list, element );
+
+	if( set && !exist ){
+		list = g_slist_prepend( list, g_strdup( element ));
+	}
+	if( !set && exist ){
+		list = na_core_utils_slist_remove_ascii( list, element );
+	}
+
+	return( list );
+}
+
+/**
  * na_core_utils_slist_find:
  * @list: the GSList of strings to be searched.
  * @str: the searched string.
diff --git a/src/core/na-icontext.c b/src/core/na-icontext.c
index 20baa0a..4a26da5 100644
--- a/src/core/na-icontext.c
+++ b/src/core/na-icontext.c
@@ -312,34 +312,66 @@ na_icontext_read_done( NAIContext *context )
  * na_icontext_set_scheme:
  * @profile: the #NAIContext to be updated.
  * @scheme: name of the scheme.
- * @selected: whether this scheme is candidate to this profile.
+ * @selected: whether this scheme is candidate to this context.
  *
- * Sets the status of a scheme relative to this profile.
+ * Sets the status of a scheme relative to this context.
  */
 void
-na_icontext_set_scheme( NAIContext *profile, const gchar *scheme, gboolean selected )
+na_icontext_set_scheme( NAIContext *context, const gchar *scheme, gboolean selected )
 {
-	/*static const gchar *thisfn = "na_icontext_set_scheme";*/
-	gboolean exist;
 	GSList *schemes;
 
-	g_return_if_fail( NA_IS_ICONTEXT( profile ));
-
-	schemes = na_object_get_schemes( profile );
-	exist = na_core_utils_slist_find( schemes, scheme );
-	/*g_debug( "%s: scheme=%s exist=%s", thisfn, scheme, exist ? "True":"False" );*/
+	g_return_if_fail( NA_IS_ICONTEXT( context ));
 
-	if( selected && !exist ){
-		schemes = g_slist_prepend( schemes, g_strdup( scheme ));
-	}
-	if( !selected && exist ){
-		schemes = na_core_utils_slist_remove_ascii( schemes, scheme );
-	}
-	na_object_set_schemes( profile, schemes );
+	schemes = na_object_get_schemes( context );
+	schemes = na_core_utils_slist_setup_element( schemes, scheme, selected );
+	na_object_set_schemes( context, schemes );
 	na_core_utils_slist_free( schemes );
 }
 
 /**
+ * na_icontext_set_only_desktop:
+ * @profile: the #NAIContext to be updated.
+ * @desktop: name of the desktop environment.
+ * @selected: whether this desktop is candidate to this context.
+ *
+ * Sets the status of the desktop relative to this context for the OnlyShowIn list.
+ */
+void
+na_icontext_set_only_desktop( NAIContext *context, const gchar *desktop, gboolean selected )
+{
+	GSList *desktops;
+
+	g_return_if_fail( NA_IS_ICONTEXT( context ));
+
+	desktops = na_object_get_only_show_in( context );
+	desktops = na_core_utils_slist_setup_element( desktops, desktop, selected );
+	na_object_set_only_show_in( context, desktops );
+	na_core_utils_slist_free( desktops );
+}
+
+/**
+ * na_icontext_set_only_desktop:
+ * @profile: the #NAIContext to be updated.
+ * @desktop: name of the desktop environment.
+ * @selected: whether this desktop is candidate to this context.
+ *
+ * Sets the status of the desktop relative to this context for the NotShowIn list.
+ */
+void
+na_icontext_set_not_desktop( NAIContext *context, const gchar *desktop, gboolean selected )
+{
+	GSList *desktops;
+
+	g_return_if_fail( NA_IS_ICONTEXT( context ));
+
+	desktops = na_object_get_not_show_in( context );
+	desktops = na_core_utils_slist_setup_element( desktops, desktop, selected );
+	na_object_set_not_show_in( context, desktops );
+	na_core_utils_slist_free( desktops );
+}
+
+/**
  * na_icontext_replace_folder:
  * @profile: the #NAIContext to be updated.
  * @old: the old uri.
diff --git a/src/nact/nact-ienvironment-tab.c b/src/nact/nact-ienvironment-tab.c
index 4dc4ff5..e945bc4 100644
--- a/src/nact/nact-ienvironment-tab.c
+++ b/src/nact/nact-ienvironment-tab.c
@@ -33,10 +33,13 @@
 #endif
 
 #include <glib/gi18n.h>
+#include <stdlib.h>
 #include <string.h>
 
+#include <api/na-core-utils.h>
 #include <api/na-object-api.h>
 
+#include "nact-gtk-utils.h"
 #include "nact-main-tab.h"
 #include "nact-ienvironment-tab.h"
 
@@ -46,7 +49,29 @@ struct NactIEnvironmentTabInterfacePrivate {
 	void *empty;						/* so that gcc -pedantic is happy */
 };
 
-/* column ordering
+/* columns in the selection count combobox
+ */
+enum {
+	COUNT_SIGN_COLUMN = 0,
+	COUNT_LABEL_COLUMN,
+	COUNT_N_COLUMN
+};
+
+typedef struct {
+	gchar *sign;
+	gchar *label;
+}
+	SelectionCountStruct;
+
+/* i18n notes: selection count symbol, respectively 'less than', 'equal to' and 'greater than' */
+static SelectionCountStruct st_counts[] = {
+		{ "<", N_( "(strictly lesser than)" ) },
+		{ "=", N_( "(equal to)" ) },
+		{ ">", N_( "(strictly greater than)" ) },
+		{ NULL }
+};
+
+/* column ordering in the OnlyShowIn/NotShowIn listview
  */
 enum {
 	ENV_BOOL_COLUMN = 0,
@@ -80,6 +105,9 @@ static void     interface_base_finalize( NactIEnvironmentTabInterface *klass );
 
 static void     on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected );
 
+static void     on_selcount_ope_changed( GtkComboBox *combo, NactIEnvironmentTab *instance );
+static void     on_selcount_int_changed( GtkEntry *entry, NactIEnvironmentTab *instance );
+static void     on_selection_count_changed( NactIEnvironmentTab *instance );
 static void     on_show_always_toggled( GtkToggleButton *togglebutton, NactIEnvironmentTab *instance );
 static void     on_only_show_toggled( GtkToggleButton *togglebutton, NactIEnvironmentTab *instance );
 static void     on_do_not_show_toggled( GtkToggleButton *togglebutton, NactIEnvironmentTab *instance );
@@ -91,7 +119,15 @@ static void     on_show_if_true_changed( GtkEntry *entry, NactIEnvironmentTab *i
 static void     on_show_if_running_changed( GtkEntry *entry, NactIEnvironmentTab *instance );
 static void     on_show_if_running_browse( GtkButton *button, NactIEnvironmentTab *instance );
 
-static gboolean tab_set_sensitive( NactIEnvironmentTab *instance, NAIContext *context );
+static void     init_selection_count_combobox( NactIEnvironmentTab *instance );
+static gchar   *get_selection_count_selection( NactIEnvironmentTab *instance );
+static void     set_selection_count_selection( NactIEnvironmentTab *instance, const gchar *ope, const gchar *uint );
+static void     dispose_selection_count_combobox( NactIEnvironmentTab *instance );
+
+static void     init_desktop_listview( NactIEnvironmentTab *instance );
+static void     raz_desktop_listview( NactIEnvironmentTab *instance );
+static void     setup_desktop_listview( NactIEnvironmentTab *instance, GSList *show );
+static void     dispose_desktop_listview( NactIEnvironmentTab *instance );
 
 GType
 nact_ienvironment_tab_get_type( void )
@@ -172,11 +208,6 @@ void
 nact_ienvironment_tab_initial_load_toplevel( NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_initial_load_toplevel";
-	GtkTreeView *listview;
-	GtkListStore *model;
-	GtkCellRenderer *check_cell, *text_cell;
-	GtkTreeViewColumn *column;
-	GtkTreeSelection *selection;
 
 	g_return_if_fail( NACT_IS_IENVIRONMENT_TAB( instance ));
 
@@ -184,31 +215,8 @@ nact_ienvironment_tab_initial_load_toplevel( NactIEnvironmentTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsTreeView" ));
-		model = gtk_list_store_new( N_COLUMN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING );
-		gtk_tree_view_set_model( listview, GTK_TREE_MODEL( model ));
-		g_object_unref( model );
-
-		check_cell = gtk_cell_renderer_toggle_new();
-		column = gtk_tree_view_column_new_with_attributes(
-				"boolean",
-				check_cell,
-				"active", ENV_BOOL_COLUMN,
-				NULL );
-		gtk_tree_view_append_column( listview, column );
-
-		text_cell = gtk_cell_renderer_text_new();
-		column = gtk_tree_view_column_new_with_attributes(
-				"label",
-				text_cell,
-				"text", ENV_LABEL_COLUMN,
-				NULL );
-		gtk_tree_view_append_column( listview, column );
-
-		gtk_tree_view_set_headers_visible( listview, FALSE );
-
-		selection = gtk_tree_view_get_selection( listview );
-		gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
+		init_selection_count_combobox( instance );
+		init_desktop_listview( instance );
 	}
 }
 
@@ -223,6 +231,7 @@ void
 nact_ienvironment_tab_runtime_init_toplevel( NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_runtime_init_toplevel";
+	GtkWidget *selcount_ope, *selcount_int;
 	GtkWidget *button, *entry;
 	GtkTreeView *listview;
 	GtkTreeModel *model;
@@ -243,6 +252,20 @@ nact_ienvironment_tab_runtime_init_toplevel( NactIEnvironmentTab *instance )
 				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
 				G_CALLBACK( on_tab_updatable_selection_changed ));
 
+		selcount_ope = base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" );
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( selcount_ope ),
+				"changed",
+				G_CALLBACK( on_selcount_ope_changed ));
+
+		selcount_int = base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountNumberEntry" );
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( selcount_int ),
+				"changed",
+				G_CALLBACK( on_selcount_int_changed ));
+
 		button = base_window_get_widget( BASE_WINDOW( instance ), "ShowAlwaysButton" );
 		base_window_signal_connect(
 				BASE_WINDOW( instance ),
@@ -264,7 +287,7 @@ nact_ienvironment_tab_runtime_init_toplevel( NactIEnvironmentTab *instance )
 				"toggled",
 				G_CALLBACK( on_do_not_show_toggled ));
 
-		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsTreeView" ));
+		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
 		model = gtk_tree_view_get_model( listview );
 
 		for( i = 0 ; st_envs[i].keyword ; ++i ){
@@ -354,9 +377,6 @@ void
 nact_ienvironment_tab_dispose( NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_dispose";
-	GtkTreeView *listview;
-	GtkTreeModel *model;
-	GtkTreeSelection *selection;
 
 	g_return_if_fail( NACT_IS_IENVIRONMENT_TAB( instance ));
 
@@ -364,11 +384,10 @@ nact_ienvironment_tab_dispose( NactIEnvironmentTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsTreeView" ));
-		model = gtk_tree_view_get_model( listview );
-		selection = gtk_tree_view_get_selection( listview );
-		gtk_tree_selection_unselect_all( selection );
-		gtk_list_store_clear( GTK_LIST_STORE( model ));
+		st_on_selection_change = TRUE;
+
+		dispose_selection_count_combobox( instance );
+		dispose_desktop_listview( instance );
 	}
 }
 
@@ -376,19 +395,16 @@ static void
 on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_on_tab_updatable_selection_changed";
+	NAIContext *context;
+	gboolean editable;
+	gboolean enable_tab;
+	gchar *sel_count, *selcount_ope, *selcount_int;
+	GtkWidget *combo, *entry;
 	GtkTreeView *listview;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
 	GtkTreePath *path;
 	GtkTreeSelection *selection;
-	gboolean next_ok, found;
-	GtkWidget *appear_button;
-	NAObjectItem *item;
-	NAObjectProfile *profile;
-	NAIContext *context;
-	gboolean editable;
-	GSList *show, *notshow, *checked, *ic;
-	gchar *keyword;
+	GtkWidget *always_button, *show_button, *notshow_button;
+	GSList *desktops;
 
 	g_return_if_fail( NACT_IS_IENVIRONMENT_TAB( instance ));
 
@@ -396,82 +412,64 @@ on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_se
 
 		g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
 
-		st_on_selection_change = TRUE;
+		context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
 
-		/* reinitialize the list OnlyShowIn/NotShowIn
-		 */
-		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsTreeView" ));
-		model = gtk_tree_view_get_model( listview );
+		enable_tab = ( context != NULL );
+		nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_ENVIRONMENT, enable_tab );
 
-		if( gtk_tree_model_get_iter_first( model, &iter )){
-			next_ok = TRUE;
-			while( next_ok ){
-				gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, FALSE, -1 );
-				next_ok = gtk_tree_model_iter_next( model, &iter );
-			}
-		}
+		if( context ){
 
-		/* setup the tab for current context
-		 */
-		g_object_get(
-				G_OBJECT( instance ),
-				TAB_UPDATABLE_PROP_SELECTED_ITEM, &item,
-				TAB_UPDATABLE_PROP_SELECTED_PROFILE, &profile,
-				TAB_UPDATABLE_PROP_EDITABLE, &editable,
-				NULL );
+			st_on_selection_change = TRUE;
 
-		context = ( profile ? NA_ICONTEXT( profile ) : ( NAIContext * ) item );
+			sel_count = na_object_get_selection_count( context );
+			na_core_utils_selcount_get_ope_int( sel_count, &selcount_ope, &selcount_int );
+			set_selection_count_selection( instance, selcount_ope, selcount_int );
+			g_free( selcount_int );
+			g_free( selcount_ope );
+			g_free( sel_count );
 
-		tab_set_sensitive( instance, context );
+			combo = base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" );
+			nact_gtk_utils_set_editable( GTK_OBJECT( combo ), editable );
 
-		show = NULL;
-		notshow = NULL;
-		checked = NULL;
-		found = FALSE;
-		appear_button = base_window_get_widget( BASE_WINDOW( instance ), "ShowAlwaysButton" );
+			entry = base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountNumberEntry" );
+			nact_gtk_utils_set_editable( GTK_OBJECT( entry ), editable );
+
+			raz_desktop_listview( instance );
+
+			always_button = base_window_get_widget( BASE_WINDOW( instance ), "ShowAlwaysButton" );
+			nact_gtk_utils_set_editable( GTK_OBJECT( always_button ), editable );
+
+			show_button = base_window_get_widget( BASE_WINDOW( instance ), "OnlyShowButton" );
+			nact_gtk_utils_set_editable( GTK_OBJECT( show_button ), editable );
+
+			notshow_button = base_window_get_widget( BASE_WINDOW( instance ), "DoNotShowButton" );
+			nact_gtk_utils_set_editable( GTK_OBJECT( notshow_button ), editable );
+
+			desktops = na_object_get_only_show_in( context );
+			listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+
+			if( desktops && g_slist_length( desktops )){
+				gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show_button ), TRUE );
+				gtk_widget_set_sensitive( GTK_WIDGET( listview ), TRUE );
 
-		if( context ){
-			show = na_object_get_only_show_in( context );
-			if( show && g_slist_length( show )){
-				appear_button = base_window_get_widget( BASE_WINDOW( instance ), "OnlyShowButton" );
-				checked = show;
 			} else {
-				notshow = na_object_get_not_show_in( context );
-				if( notshow && g_slist_length( notshow )){
-					appear_button = base_window_get_widget( BASE_WINDOW( instance ), "DoNotShowButton" );
-					checked = notshow;
-				}
-			}
-		}
+				desktops = na_object_get_not_show_in( context );
 
-		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( appear_button ), TRUE );
-
-		for( ic = checked ; ic ; ic = ic->next ){
-			if( strlen( ic->data )){
-				if( gtk_tree_model_get_iter_first( model, &iter )){
-					next_ok = TRUE;
-					found = FALSE;
-					while( next_ok && !found ){
-						gtk_tree_model_get( model, &iter, ENV_KEYWORD_COLUMN, &keyword, -1 );
-						if( !strcmp( keyword, ic->data )){
-							gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, TRUE, -1 );
-							found = TRUE;
-						}
-						g_free( keyword );
-						if( !found ){
-							next_ok = gtk_tree_model_iter_next( model, &iter );
-						}
-					}
-				}
-				if( !found ){
-					g_warning( "%s: unable to set %s environment", thisfn, ( const gchar * ) ic->data );
+				if( desktops && g_slist_length( desktops )){
+					gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( notshow_button ), TRUE );
+					gtk_widget_set_sensitive( GTK_WIDGET( listview ), TRUE );
+
+				} else {
+					gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( always_button ), TRUE );
+					gtk_widget_set_sensitive( GTK_WIDGET( listview ), FALSE );
+					desktops = NULL;
 				}
 			}
-		}
 
-		st_on_selection_change = FALSE;
+			setup_desktop_listview( instance, desktops );
+
+			st_on_selection_change = FALSE;
 
-		if( context ){
 			path = gtk_tree_path_new_first();
 			if( path ){
 				selection = gtk_tree_view_get_selection( listview );
@@ -483,95 +481,201 @@ on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_se
 }
 
 static void
+on_selcount_ope_changed( GtkComboBox *combo, NactIEnvironmentTab *instance )
+{
+	on_selection_count_changed( instance );
+}
+
+static void
+on_selcount_int_changed( GtkEntry *entry, NactIEnvironmentTab *instance )
+{
+	on_selection_count_changed( instance );
+}
+
+static void
+on_selection_count_changed( NactIEnvironmentTab *instance )
+{
+	NAIContext *context;
+	gchar *selcount;
+
+	if( !st_on_selection_change ){
+
+		context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), NULL );
+		g_return_if_fail( context != NULL );
+
+		selcount = get_selection_count_selection( instance );
+		na_object_set_selection_count( context, selcount );
+		g_free( selcount );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+	}
+}
+
+/*
+ * the behavior coded here as one main drawback:
+ * - user will usually try to go through the radio buttons (always show,
+ *   only show in, not show in) just to see what are their effects
+ * - but each time we toggle one of these buttons, the list of desktop is raz :(
+ *
+ * this behavior is inherent because we have to save each modification in the
+ * context as soon as this modification is made in the UI, so that user do not
+ * have to save each modification before going to another tab/context/item
+ *
+ * as far as I know, this case is the only which has this drawback...
+ */
+static void
 on_show_always_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_on_show_always_toggled";
+	NAIContext *context;
+	gboolean editable;
+	gboolean active;
+	GtkTreeView *listview;
 
 	g_debug( "%s: toggle_button=%p (active=%s), instance=%p",
 			thisfn,
 			( void * ) toggle_button, gtk_toggle_button_get_active( toggle_button ) ? "True":"False",
 			( void * ) instance );
+
+	context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
+	active = gtk_toggle_button_get_active( toggle_button );
+
+	if( editable ){
+		listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+		gtk_widget_set_sensitive( GTK_WIDGET( listview ), !active );
+
+		if( active ){
+			raz_desktop_listview( instance );
+			na_object_set_only_show_in( context, NULL );
+			na_object_set_not_show_in( context, NULL );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		}
+
+	} else {
+		g_signal_handlers_block_by_func(( gpointer ) toggle_button, on_show_always_toggled, instance );
+		gtk_toggle_button_set_active( toggle_button, !active );
+		g_signal_handlers_unblock_by_func(( gpointer ) toggle_button, on_show_always_toggled, instance );
+	}
 }
 
 static void
 on_only_show_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_on_only_show_toggled";
+	NAIContext *context;
+	gboolean editable;
+	gboolean active;
+	GSList *show;
 
 	g_debug( "%s: toggle_button=%p (active=%s), instance=%p",
 			thisfn,
 			( void * ) toggle_button, gtk_toggle_button_get_active( toggle_button ) ? "True":"False",
 			( void * ) instance );
+
+	context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
+	active = gtk_toggle_button_get_active( toggle_button );
+
+	if( editable ){
+		if( active ){
+			raz_desktop_listview( instance );
+			show = na_object_get_only_show_in( context );
+			if( show && g_slist_length( show )){
+				setup_desktop_listview( instance, show );
+			}
+
+		} else {
+			na_object_set_only_show_in( context, NULL );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		}
+
+	} else {
+		g_signal_handlers_block_by_func(( gpointer ) toggle_button, on_only_show_toggled, instance );
+		gtk_toggle_button_set_active( toggle_button, !active );
+		g_signal_handlers_unblock_by_func(( gpointer ) toggle_button, on_only_show_toggled, instance );
+	}
 }
 
 static void
 on_do_not_show_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *instance )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_on_do_not_show_toggled";
+	NAIContext *context;
+	gboolean editable;
+	gboolean active;
+	GSList *show;
 
 	g_debug( "%s: toggle_button=%p (active=%s), instance=%p",
 			thisfn,
 			( void * ) toggle_button, gtk_toggle_button_get_active( toggle_button ) ? "True":"False",
 			( void * ) instance );
+
+	context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
+	active = gtk_toggle_button_get_active( toggle_button );
+
+	if( editable ){
+		if( active ){
+			raz_desktop_listview( instance );
+			show = na_object_get_not_show_in( context );
+			if( show && g_slist_length( show )){
+				setup_desktop_listview( instance, show );
+			}
+
+		} else {
+			na_object_set_not_show_in( context, NULL );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		}
+
+	} else {
+		g_signal_handlers_block_by_func(( gpointer ) toggle_button, on_do_not_show_toggled, instance );
+		gtk_toggle_button_set_active( toggle_button, !active );
+		g_signal_handlers_unblock_by_func(( gpointer ) toggle_button, on_do_not_show_toggled, instance );
+	}
 }
 
 static void
 on_desktop_toggled( GtkCellRendererToggle *renderer, gchar *path, BaseWindow *window )
 {
 	static const gchar *thisfn = "nact_ienvironment_tab_on_desktop_toggled";
-	GtkTreeView *listview;
-	gboolean editable;
-	NAObjectItem *item;
-	NAObjectProfile *profile;
 	NAIContext *context;
+	gboolean editable;
+	GtkTreeView *listview;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	GtkTreePath *tree_path;
 	gboolean state;
 	gchar *desktop;
+	GtkWidget *show_button;
 
 	g_debug( "%s: renderer=%p, path=%s, window=%p", thisfn, ( void * ) renderer, path, ( void * ) window );
 
 	if( !st_on_selection_change ){
 
-		listview = GTK_TREE_VIEW( base_window_get_widget( window, "EnvironmentsTreeView" ));
-		model = gtk_tree_view_get_model( listview );
-		tree_path = gtk_tree_path_new_from_string( path );
-		gtk_tree_model_get_iter( model, &iter, tree_path );
-		gtk_tree_path_free( tree_path );
-		gtk_tree_model_get( model, &iter, ENV_BOOL_COLUMN, &state, ENV_KEYWORD_COLUMN, &desktop, -1 );
+		context = nact_main_tab_get_context( NACT_MAIN_WINDOW( window ), &editable );
 
-		g_object_get(
-				G_OBJECT( window ),
-				TAB_UPDATABLE_PROP_SELECTED_ITEM, &item,
-				TAB_UPDATABLE_PROP_SELECTED_PROFILE, &profile,
-				TAB_UPDATABLE_PROP_EDITABLE, &editable,
-				NULL );
+		if( editable ){
+			listview = GTK_TREE_VIEW( base_window_get_widget( window, "EnvironmentsDesktopTreeView" ));
+			model = gtk_tree_view_get_model( listview );
+			tree_path = gtk_tree_path_new_from_string( path );
+			gtk_tree_model_get_iter( model, &iter, tree_path );
+			gtk_tree_path_free( tree_path );
+			gtk_tree_model_get( model, &iter, ENV_BOOL_COLUMN, &state, ENV_KEYWORD_COLUMN, &desktop, -1 );
+			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, !state, -1 );
+
+			show_button = base_window_get_widget( BASE_WINDOW( window ), "OnlyShowButton" );
+			if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( show_button ))){
+				na_object_set_only_desktop( context, desktop, !state );
+			} else {
+				na_object_set_not_desktop( context, desktop, !state );
+			}
 
-		context = ( profile ? NA_ICONTEXT( profile ) : ( NAIContext * ) item );
+			g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
 
-		if( !editable ){
+			g_free( desktop );
+
+		} else {
 			g_signal_handlers_block_by_func(( gpointer ) renderer, on_desktop_toggled, window );
 			gtk_cell_renderer_toggle_set_active( renderer, state );
 			g_signal_handlers_unblock_by_func(( gpointer ) renderer, on_desktop_toggled, window );
-
-		} else {
-			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, !state, -1 );
-			/*
-			if( g_object_class_find_property( G_OBJECT_GET_CLASS( window ), TAB_UPDATABLE_PROP_SELECTED_PROFILE )){
-				g_object_get(
-						G_OBJECT( window ),
-						TAB_UPDATABLE_PROP_SELECTED_PROFILE, &edited,
-						NULL );
-				if( edited ){
-					na_object_set_scheme( edited, scheme, !state );
-					g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
-				}
-			}
-			*/
 		}
-
-		g_free( desktop );
 	}
 }
 
@@ -605,13 +709,204 @@ on_show_if_running_browse( GtkButton *button, NactIEnvironmentTab *instance )
 {
 }
 
-static gboolean
-tab_set_sensitive( NactIEnvironmentTab *instance, NAIContext *context )
+static void
+init_selection_count_combobox( NactIEnvironmentTab *instance )
 {
-	gboolean enable_tab;
+	GtkTreeModel *model;
+	guint i;
+	GtkTreeIter row;
+	GtkComboBox *combo;
+	GtkCellRenderer *cell_renderer_text;
+
+	model = GTK_TREE_MODEL( gtk_list_store_new( COUNT_N_COLUMN, G_TYPE_STRING, G_TYPE_STRING ));
+	i = 0;
+	while( st_counts[i].sign ){
+		gtk_list_store_append( GTK_LIST_STORE( model ), &row );
+		gtk_list_store_set( GTK_LIST_STORE( model ), &row, COUNT_SIGN_COLUMN, st_counts[i].sign, -1 );
+		gtk_list_store_set( GTK_LIST_STORE( model ), &row, COUNT_LABEL_COLUMN, st_counts[i].label, -1 );
+		i += 1;
+	}
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" ));
+	gtk_combo_box_set_model( combo, model );
+	g_object_unref( model );
+
+	gtk_cell_layout_clear( GTK_CELL_LAYOUT( combo ));
+
+	cell_renderer_text = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( combo ), cell_renderer_text, FALSE );
+	gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT( combo ), cell_renderer_text, "text", COUNT_SIGN_COLUMN );
+
+	cell_renderer_text = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( combo ), cell_renderer_text, TRUE );
+	g_object_set( G_OBJECT( cell_renderer_text ), "xalign", ( gdouble ) 0.0, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
+	gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT( combo ), cell_renderer_text, "text", COUNT_LABEL_COLUMN );
+
+	gtk_combo_box_set_active( GTK_COMBO_BOX( combo ), 0 );
+}
+
+static gchar *
+get_selection_count_selection( NactIEnvironmentTab *instance )
+{
+	GtkComboBox *combo;
+	GtkEntry *entry;
+	gint index;
+	gchar *uints, *selcount;
+	guint uinti;
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" ));
+	index = gtk_combo_box_get_active( combo );
+	if( index == -1 ){
+		return( NULL );
+	}
+
+	entry = GTK_ENTRY( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountNumberEntry" ));
+	uinti = abs( atoi( gtk_entry_get_text( entry )));
+	uints = g_strdup_printf( "%d", uinti );
+	gtk_entry_set_text( entry, uints );
+	g_free( uints );
+
+	selcount = g_strdup_printf( "%s%d", st_counts[index].sign, uinti );
+
+	return( selcount );
+}
+
+static void
+set_selection_count_selection( NactIEnvironmentTab *instance, const gchar *ope, const gchar *uint )
+{
+	GtkComboBox *combo;
+	GtkEntry *entry;
+	gint i, index;
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" ));
+
+	index = -1;
+	for( i=0 ; st_counts[i].sign && index==-1 ; ++i ){
+		if( !strcmp( st_counts[i].sign, ope )){
+			index = i;
+		}
+	}
+	gtk_combo_box_set_active( combo, index );
+
+	entry = GTK_ENTRY( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountNumberEntry" ));
+	gtk_entry_set_text( entry, uint );
+}
+
+static void
+dispose_selection_count_combobox( NactIEnvironmentTab *instance )
+{
+	GtkComboBox *combo;
+	GtkTreeModel *model;
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "SelectionCountSigneCombobox" ));
+	model = gtk_combo_box_get_model( combo );
+	gtk_list_store_clear( GTK_LIST_STORE( model ));
+}
+
+static void
+init_desktop_listview( NactIEnvironmentTab *instance )
+{
+	GtkTreeView *listview;
+	GtkListStore *model;
+	GtkCellRenderer *check_cell, *text_cell;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *selection;
+
+	listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+	model = gtk_list_store_new( N_COLUMN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING );
+	gtk_tree_view_set_model( listview, GTK_TREE_MODEL( model ));
+	g_object_unref( model );
+
+	check_cell = gtk_cell_renderer_toggle_new();
+	column = gtk_tree_view_column_new_with_attributes(
+			"boolean",
+			check_cell,
+			"active", ENV_BOOL_COLUMN,
+			NULL );
+	gtk_tree_view_append_column( listview, column );
+
+	text_cell = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+			"label",
+			text_cell,
+			"text", ENV_LABEL_COLUMN,
+			NULL );
+	gtk_tree_view_append_column( listview, column );
+
+	gtk_tree_view_set_headers_visible( listview, FALSE );
+
+	selection = gtk_tree_view_get_selection( listview );
+	gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
+}
+
+static void
+raz_desktop_listview( NactIEnvironmentTab *instance )
+{
+	GtkTreeView *listview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean next_ok;
+
+	listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+	model = gtk_tree_view_get_model( listview );
 
-	enable_tab = ( context != NULL );
-	nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_ENVIRONMENT, enable_tab );
+	if( gtk_tree_model_get_iter_first( model, &iter )){
+		next_ok = TRUE;
+		while( next_ok ){
+			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, FALSE, -1 );
+			next_ok = gtk_tree_model_iter_next( model, &iter );
+		}
+	}
+}
+
+static void
+setup_desktop_listview( NactIEnvironmentTab *instance, GSList *show )
+{
+	static const gchar *thisfn = "nact_ienvironment_tab_setup_desktop_listview";
+	GtkTreeView *listview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean next_ok, found;
+	GSList *ic;
+	gchar *keyword;
+
+	listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+	model = gtk_tree_view_get_model( listview );
+
+	for( ic = show ; ic ; ic = ic->next ){
+		if( strlen( ic->data )){
+			found = FALSE;
+			if( gtk_tree_model_get_iter_first( model, &iter )){
+				next_ok = TRUE;
+				while( next_ok && !found ){
+					gtk_tree_model_get( model, &iter, ENV_KEYWORD_COLUMN, &keyword, -1 );
+					if( !strcmp( keyword, ic->data )){
+						gtk_list_store_set( GTK_LIST_STORE( model ), &iter, ENV_BOOL_COLUMN, TRUE, -1 );
+						found = TRUE;
+					}
+					g_free( keyword );
+					if( !found ){
+						next_ok = gtk_tree_model_iter_next( model, &iter );
+					}
+				}
+			}
+			if( !found ){
+				g_warning( "%s: unable to set %s environment", thisfn, ( const gchar * ) ic->data );
+			}
+		}
+	}
+}
+
+static void
+dispose_desktop_listview( NactIEnvironmentTab *instance )
+{
+	GtkTreeView *listview;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
 
-	return( enable_tab );
+	listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "EnvironmentsDesktopTreeView" ));
+	model = gtk_tree_view_get_model( listview );
+	selection = gtk_tree_view_get_selection( listview );
+	gtk_tree_selection_unselect_all( selection );
+	gtk_list_store_clear( GTK_LIST_STORE( model ));
 }



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