[nautilus-actions] Implement selection count in NACT



commit a0e8ff809206d0f0989f22c55a1a099a992b07ed
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sun Jun 13 18:17:11 2010 +0200

    Implement selection count in NACT

 ChangeLog                                |   10 ++
 po/POTFILES.in                           |    5 +-
 src/api/na-core-utils.h                  |    4 +
 src/core/na-core-utils.c                 |   37 +++++
 src/nact/nact-icapabilities-tab.c        |  236 +++++++++++++++++++++++++++++-
 src/nact/nautilus-actions-config-tool.ui |   32 ++--
 6 files changed, 301 insertions(+), 23 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index dad42b5..5867b1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,16 @@
 	* src/nact/nact-iaction-tab.c:
 	Use gtk_bin_get_child() function instead of GTK_BIN()->child.
 
+	* po/POTFILES.in:
+	Add src/nact/nact-icapabilities-tab.c, src/nact/nact-ischemes-tab.c.
+	Remove src/nact/nact-iconditions-tab.c.
+
+	* src/api/na-core-utils.h:
+	* src/core/na-core-utils.c (na_core_utils_selcount_get_ope_int):
+	New function.
+
+	* src/nact/nact-icapabilities-tab.c: Implement selection count.
+
 2010-06-11 Pierre Wieser <pwieser trychlos org>
 
 	* src/api/na-icontext.h:
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 444dbb7..c5c9744 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -31,11 +31,12 @@ src/nact/nact-export-ask.c
 src/nact/nact-export-format.c
 src/nact/nact-iaction-tab.c
 src/nact/nact-ibasenames-tab.c
-src/nact/nact-imimetypes-tab.c
+src/nact/nact-icapabilities-tab.c
 src/nact/nact-icommand-tab.c
-src/nact/nact-iconditions-tab.c
 src/nact/nact-ifolders-tab.c
+src/nact/nact-imimetypes-tab.c
 src/nact/nact-iproperties-tab.c
+src/nact/nact-ischemes-tab.c
 src/nact/nact-main-menubar.c
 src/nact/nact-main-menubar-edit.c
 src/nact/nact-main-menubar-file.c
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index b438481..edeaa08 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -73,6 +73,10 @@ void     na_core_utils_slist_free( GSList *slist );
  */
 gchar   *na_core_utils_gstring_joinv( const gchar *start, const gchar *separator, gchar **list );
 
+/* selection count
+ */
+void     na_core_utils_selcount_get_ope_int( const gchar *selection_count, gchar **ope, gchar **uint );
+
 /* directory management
  */
 gboolean na_core_utils_dir_is_writable_path( const gchar *path );
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index 7755df2..8cdbcd3 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include <gio/gio.h>
@@ -607,6 +608,42 @@ text_to_string_list( const gchar *text, const gchar *separator, const gchar *def
 	return( strlist );
 }
 
+/***
+ * na_core_utils_selcount_get_ope:
+ * @selcount: the selection count condition string.
+ * @ope: a pointer to a newly allocated string which will contains the
+ *  operation code.
+ * @uint: a pointer to a newly allocated string which will contains the
+ *  relevant integer.
+ *
+ * Parses a selection count string, and extract the operation code and the
+ * relevant integer.
+ *
+ * The two returned strings must be g_free() by the caller.
+ */
+void
+na_core_utils_selcount_get_ope_int( const gchar *selcount, gchar **ope, gchar **uint )
+{
+	gchar *dup, *dup2;
+	guint uint_int;
+
+	g_return_if_fail( ope && uint );
+
+	*ope = NULL;
+	*uint = NULL;
+
+	dup = g_strstrip( g_strdup( selcount ));
+	*ope = g_strdup( " " );
+	*ope[0] = dup[0];
+
+	dup2 = g_strstrip( g_strdup( dup+1 ));
+	uint_int = abs( atoi( dup2 ));
+	*uint = g_strdup_printf( "%d", uint_int );
+
+	g_free( dup2 );
+	g_free( dup );
+}
+
 /**
  * na_core_utils_dir_is_writable_path:
  * @path: the path of the directory to be tested.
diff --git a/src/nact/nact-icapabilities-tab.c b/src/nact/nact-icapabilities-tab.c
index 7b42e88..13be5a5 100644
--- a/src/nact/nact-icapabilities-tab.c
+++ b/src/nact/nact-icapabilities-tab.c
@@ -32,8 +32,13 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
+#include <stdlib.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-icapabilities-tab.h"
 
@@ -43,6 +48,28 @@ struct NactICapabilitiesTabInterfacePrivate {
 	void *empty;						/* so that gcc -pedantic is happy */
 };
 
+/* 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 }
+};
+
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
 
@@ -53,8 +80,14 @@ static void         interface_base_finalize( NactICapabilitiesTabInterface *klas
 static void         runtime_init_connect_signals( NactICapabilitiesTab *instance, GtkTreeView *listview );
 static void         on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_selected );
 static void         on_tab_updatable_enable_tab( NactICapabilitiesTab *instance, NAObjectItem *item );
+static void         on_selcount_ope_changed( GtkComboBox *combo, NactICapabilitiesTab *instance );
+static void         on_selcount_int_changed( GtkEntry *entry, NactICapabilitiesTab *instance );
 static gboolean     tab_set_sensitive( NactICapabilitiesTab *instance );
 static GtkTreeView *get_capabilities_tree_view( NactICapabilitiesTab *instance );
+static void         init_count_combobox( NactICapabilitiesTab *instance );
+static void         set_selection_count_selection( NactICapabilitiesTab *instance, const gchar *ope, const gchar *uint );
+static gchar       *get_selection_count_selection( NactICapabilitiesTab *instance );
+static void         dispose_count_combobox( NactICapabilitiesTab *instance );
 
 GType
 nact_icapabilities_tab_get_type( void )
@@ -130,10 +163,13 @@ nact_icapabilities_tab_initial_load_toplevel( NactICapabilitiesTab *instance )
 {
 	static const gchar *thisfn = "nact_icapabilities_tab_initial_load_toplevel";
 
+	g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
 	if( st_initialized && !st_finalized ){
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-		g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
+		init_count_combobox( instance );
 	}
 }
 
@@ -143,10 +179,11 @@ nact_icapabilities_tab_runtime_init_toplevel( NactICapabilitiesTab *instance )
 	static const gchar *thisfn = "nact_icapabilities_tab_runtime_init_toplevel";
 	GtkTreeView *listview;
 
+	g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
 	if( st_initialized && !st_finalized ){
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-		g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
 
 		listview = get_capabilities_tree_view( instance );
 		runtime_init_connect_signals( instance, listview );
@@ -157,6 +194,7 @@ static void
 runtime_init_connect_signals( NactICapabilitiesTab *instance, GtkTreeView *listview )
 {
 	static const gchar *thisfn = "nact_icapabilities_tab_runtime_init_connect_signals";
+	GtkWidget *selcount_ope, *selcount_int;
 
 	if( st_initialized && !st_finalized ){
 
@@ -174,6 +212,20 @@ runtime_init_connect_signals( NactICapabilitiesTab *instance, GtkTreeView *listv
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_SIGNAL_ENABLE_TAB,
 				G_CALLBACK( on_tab_updatable_enable_tab ));
+
+		selcount_ope = base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountSigneCombobox" );
+		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 ), "ConditionsCountNumberEntry" );
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( selcount_int ),
+				"changed",
+				G_CALLBACK( on_selcount_int_changed ));
 	}
 }
 
@@ -182,10 +234,11 @@ nact_icapabilities_tab_all_widgets_showed( NactICapabilitiesTab *instance )
 {
 	static const gchar *thisfn = "nact_icapabilities_tab_all_widgets_showed";
 
+	g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
 	if( st_initialized && !st_finalized ){
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-		g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
 	}
 }
 
@@ -194,10 +247,13 @@ nact_icapabilities_tab_dispose( NactICapabilitiesTab *instance )
 {
 	static const gchar *thisfn = "nact_icapabilities_tab_dispose";
 
+	g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
 	if( st_initialized && !st_finalized ){
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-		g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
+		dispose_count_combobox( instance );
 	}
 }
 
@@ -207,8 +263,12 @@ on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_s
 	static const gchar *thisfn = "nact_icapabilities_tab_on_tab_updatable_selection_changed";
 	NAObjectItem *item;
 	NAObjectProfile *profile;
+	NAIContext *context;
 	GSList *capabilities;
 	gboolean editable;
+	gchar *sel_count;
+	gchar *selcount_ope, *selcount_int;
+	GtkWidget *combo, *entry;
 
 	capabilities = NULL;
 	if( st_initialized && !st_finalized ){
@@ -223,6 +283,23 @@ on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_s
 				TAB_UPDATABLE_PROP_EDITABLE, &editable,
 				NULL );
 
+		context = ( profile ? NA_ICONTEXT( profile ) : ( NAIContext * ) item );
+
+		sel_count = context ? na_object_get_selection_count( context ) : g_strdup( ">0" );
+		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 );
+
+		combo = base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountSigneCombobox" );
+		gtk_widget_set_sensitive( combo, context != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( combo ), editable );
+
+		entry = base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountNumberEntry" );
+		gtk_widget_set_sensitive( entry, context != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( entry ), editable );
+
 		tab_set_sensitive( instance );
 	}
 }
@@ -232,15 +309,68 @@ on_tab_updatable_enable_tab( NactICapabilitiesTab *instance, NAObjectItem *item
 {
 	static const gchar *thisfn = "nact_icapabilities_tab_on_tab_updatable_enable_tab";
 
+	g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
+
 	if( st_initialized && !st_finalized ){
 
 		g_debug( "%s: instance=%p, item=%p", thisfn, ( void * ) instance, ( void * ) item );
-		g_return_if_fail( NACT_IS_ICAPABILITIES_TAB( instance ));
 
 		tab_set_sensitive( instance );
 	}
 }
 
+static void
+on_selcount_ope_changed( GtkComboBox *combo, NactICapabilitiesTab *instance )
+{
+	NAObjectItem *edited;
+	NAObjectProfile *profile;
+	NAIContext *context;
+	gboolean editable;
+	gchar *selcount;
+
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
+			TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+			TAB_UPDATABLE_PROP_EDITABLE, &editable,
+			NULL );
+
+	context = ( profile ? NA_ICONTEXT( profile ) : ( NAIContext * ) edited );
+
+	if( context && editable ){
+		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, edited, FALSE );
+	}
+}
+
+static void
+on_selcount_int_changed( GtkEntry *entry, NactICapabilitiesTab *instance )
+{
+	NAObjectItem *edited;
+	NAObjectProfile *profile;
+	NAIContext *context;
+	gboolean editable;
+	gchar *selcount;
+
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
+			TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+			TAB_UPDATABLE_PROP_EDITABLE, &editable,
+			NULL );
+
+	context = ( profile ? NA_ICONTEXT( profile ) : ( NAIContext * ) edited );
+
+	if( context && editable ){
+		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, edited, FALSE );
+	}
+}
+
 static gboolean
 tab_set_sensitive( NactICapabilitiesTab *instance )
 {
@@ -254,7 +384,7 @@ tab_set_sensitive( NactICapabilitiesTab *instance )
 			TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
 			NULL );
 
-	enable_tab = ( profile != NULL && na_object_is_target_selection( NA_OBJECT_ACTION( item )));
+	enable_tab = ( item != NULL );
 	nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_CAPABILITIES, enable_tab );
 
 	return( enable_tab );
@@ -270,3 +400,97 @@ get_capabilities_tree_view( NactICapabilitiesTab *instance )
 
 	return( GTK_TREE_VIEW( treeview ));
 }
+
+static void
+init_count_combobox( NactICapabilitiesTab *instance )
+{
+	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 ), "ConditionsCountSigneCombobox" ));
+	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 void
+set_selection_count_selection( NactICapabilitiesTab *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 ), "ConditionsCountSigneCombobox" ));
+
+	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 ), "ConditionsCountNumberEntry" ));
+	gtk_entry_set_text( entry, uint );
+}
+
+static gchar *
+get_selection_count_selection( NactICapabilitiesTab *instance )
+{
+	GtkComboBox *combo;
+	GtkEntry *entry;
+	gint index;
+	gchar *uints, *selcount;
+	guint uinti;
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountSigneCombobox" ));
+	index = gtk_combo_box_get_active( combo );
+	if( index == -1 ){
+		return( NULL );
+	}
+
+	entry = GTK_ENTRY( base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountNumberEntry" ));
+	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
+dispose_count_combobox( NactICapabilitiesTab *instance )
+{
+	GtkComboBox *combo;
+	GtkTreeModel *model;
+
+	combo = GTK_COMBO_BOX( base_window_get_widget( BASE_WINDOW( instance ), "ConditionsCountSigneCombobox" ));
+	model = gtk_combo_box_get_model( combo );
+	gtk_list_store_clear( GTK_LIST_STORE( model ));
+}
diff --git a/src/nact/nautilus-actions-config-tool.ui b/src/nact/nautilus-actions-config-tool.ui
index 602d162..7f4aae5 100644
--- a/src/nact/nautilus-actions-config-tool.ui
+++ b/src/nact/nautilus-actions-config-tool.ui
@@ -1452,8 +1452,7 @@ Defining several profiles lets you have several commands, each applying with a d
                                         <property name="visible">True</property>
                                       </object>
                                       <packing>
-                                        <property name="expand">False</property>
-                                        <property name="position">3</property>
+                                        <property name="position">2</property>
                                       </packing>
                                     </child>
                                     <child>
@@ -2604,6 +2603,9 @@ Defining several profiles lets you have several commands, each applying with a d
       <placeholder/>
     </child>
     <child>
+      <placeholder/>
+    </child>
+    <child>
       <object class="GtkLabel" id="label3">
         <property name="visible">True</property>
         <property name="label" translatable="yes">This assistant will guide you through the process of importing items, actions or menus.</property>
@@ -2619,9 +2621,9 @@ Defining several profiles lets you have several commands, each applying with a d
         <child>
           <object class="GtkFileChooserWidget" id="ImportFileChooser">
             <property name="visible">True</property>
+            <property name="preview_widget_active">False</property>
             <property name="use_preview_label">False</property>
             <property name="local_only">False</property>
-            <property name="preview_widget_active">False</property>
             <property name="select_multiple">True</property>
           </object>
           <packing>
@@ -3592,39 +3594,39 @@ Be warned: this mode may be dangerous. You will not be prompted another time.</p
   </object>
   <object class="GtkSizeGroup" id="CommandLabelSizeGroup">
     <widgets>
-      <widget name="label4"/>
-      <widget name="CommandParametersLabel"/>
-      <widget name="CommandPathLabel"/>
       <widget name="ProfileLabelLabel"/>
+      <widget name="CommandPathLabel"/>
+      <widget name="CommandParametersLabel"/>
+      <widget name="label4"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="CommandButtonSizeGroup">
     <widgets>
-      <widget name="CommandLegendButton"/>
       <widget name="CommandPathButton"/>
+      <widget name="CommandLegendButton"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="ActionLabelSizeGroup">
     <widgets>
-      <widget name="ActionMenuLabelLabel"/>
-      <widget name="ActionToolbarLabelLabel"/>
-      <widget name="ActionTooltipLabel"/>
       <widget name="ActionIconLabel"/>
+      <widget name="ActionTooltipLabel"/>
+      <widget name="ActionToolbarLabelLabel"/>
+      <widget name="ActionMenuLabelLabel"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="ExecutionModeSizeGroup">
     <widgets>
-      <widget name="label43"/>
-      <widget name="label44"/>
       <widget name="label45"/>
+      <widget name="label44"/>
+      <widget name="label43"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="PropertiesLabelSizeGroup">
     <widgets>
-      <widget name="label18"/>
-      <widget name="label39"/>
-      <widget name="label49"/>
       <widget name="label19"/>
+      <widget name="label49"/>
+      <widget name="label39"/>
+      <widget name="label18"/>
     </widgets>
   </object>
 </interface>



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