[nautilus-actions] Let the user refuse to close if the action has not been saved
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Subject: [nautilus-actions] Let the user refuse to close if the action has not been saved
- Date: Tue, 14 Jul 2009 18:47:55 +0000 (UTC)
commit d545cfbbca4cb2787dfc021bb0847799a511ed2a
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Jun 29 19:35:16 2009 +0200
Let the user refuse to close if the action has not been saved
ChangeLog | 30 ++-
src/common/na-action-profile.c | 61 ++++-
src/common/na-action-profile.h | 6 +-
src/common/na-action.c | 6 +-
src/common/na-action.h | 14 +-
src/nact/base-application.c | 37 ++--
src/nact/base-application.h | 2 +-
src/nact/base-window.c | 78 +++---
src/nact/base-window.h | 4 +-
src/nact/nact-action-conditions-editor.c | 116 +++++++-
src/nact/nact-action-editor.c | 415 -----------------------------
src/nact/nact-action-editor.h | 39 ---
src/nact/nact-action-profiles-editor.c | 28 +-
src/nact/nact-imenu-item.c | 65 +++--
src/nact/nact-imenu-item.h | 5 +-
src/nact/nact-iprofile-conditions.c | 364 ++++++++++++++++++++++++--
src/nact/nact-iprofile-conditions.h | 10 +-
src/nact/nact-main-window.c | 9 +-
src/nact/nact-profile-conditions-editor.c | 30 ++-
src/nact/nact-window.c | 69 +++++-
src/nact/nact-window.h | 7 +-
src/nact/nautilus-actions-config.ui | 10 +-
src/plugin/nautilus-actions.c | 2 +-
23 files changed, 758 insertions(+), 649 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 388732e..5945bd7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,19 +1,39 @@
2009-06-29 Pierre Wieser <pwieser trychlos org>
* src/common/na-action.c:
- * src/common/na-action.h:
- na_action_set_tooltip, na_action_set_icon, na_action_are_equal:
- new functions.
+ * src/common/na-action.h (na_action_set_tooltip,
+ na_action_set_icon, na_action_are_equal): New functions.
+ (na_action_new_with_profile): Provides a default profile name.
+ (na_action_duplicate): Provides a pointer to the duplicated action.
+
+ * 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):
+ New functions.
+
+ * src/common/na-action-profile.c (na_action_profile_new):
+ No more accept a NULL profile name.
+
+ * src/common/na-action-profile.c:
+ * src/common/na-action-profile.h (na_action_profile_duplicate):
+ The duplicated profile points to the duplicated action.
* src/common/na-iio-provider.c:
Fist try to write to initial provider.
+ * src/nact/base-application.c (display_dlg):
+ New mutualized function.
+
+ * src/nact/base-window.c:
+ * src/nact/base-window.h (dialog_response):
+ Returns a boolean to let the user refuse the closing.
+
* src/nact/nact-action-conditions-editor.c:
Update the dialog title if action has been modified.
* src/nact/nact-imenu-item.c:
- * src/nact/nact-imenu-item.h:
- get_edited_action, update_dialog_title: new functions.
+ * src/nact/nact-imenu-item.h (get_edited_action,
+ update_dialog_title): New functions.
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 8d6598c..1b0ced4 100644
--- a/src/common/na-action-profile.c
+++ b/src/common/na-action-profile.c
@@ -456,8 +456,6 @@ instance_finalize( GObject *object )
* @action: the action to which the profile must be attached.
*
* @name: the internal name (identifier) of the profile.
- * If NULL, the instance_init takes care of allocating a suitable
- * default value.
*
* Returns the newly allocated NAActionProfile object.
*/
@@ -465,14 +463,14 @@ NAActionProfile *
na_action_profile_new( const NAObject *action, const gchar *name )
{
g_assert( NA_IS_ACTION( action ));
+ g_assert( name && strlen( name ));
NAActionProfile *profile =
g_object_new(
- NA_ACTION_PROFILE_TYPE, PROP_PROFILE_ACTION_STR, action, NULL );
-
- if( name && strlen( name )){
- g_object_set( G_OBJECT( profile ), PROP_PROFILE_NAME_STR, name, NULL );
- }
+ NA_ACTION_PROFILE_TYPE,
+ PROP_PROFILE_ACTION_STR, action,
+ PROP_PROFILE_NAME_STR, name,
+ NULL );
return( profile );
}
@@ -488,12 +486,12 @@ na_action_profile_new( const NAObject *action, const gchar *name )
* as the initial one, and thus cannot be attached to the same action.
*/
NAActionProfile *
-na_action_profile_duplicate( const NAActionProfile *profile )
+na_action_profile_duplicate( const NAAction *action, const NAActionProfile *profile )
{
g_assert( NA_IS_ACTION_PROFILE( profile ));
NAActionProfile *new =
- na_action_profile_new( profile->private->action, profile->private->name );
+ na_action_profile_new( NA_OBJECT( action ), profile->private->name );
g_object_set( G_OBJECT( new ),
PROP_PROFILE_LABEL_STR, profile->private->label,
@@ -535,6 +533,7 @@ do_dump( const NAObject *object )
st_parent_class->dump( object );
}
+ g_debug( "%s: action=%p", thisfn, self->private->action );
g_debug( "%s: profile_name='%s'", thisfn, self->private->name );
g_debug( "%s: label='%s'", thisfn, self->private->label );
g_debug( "%s: path='%s'", thisfn, self->private->path );
@@ -820,6 +819,45 @@ validate_schemes( GSList* schemes2test, NautilusFileInfo* file )
}
/**
+ * Set the path of the command for this profile.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * @path: path to be set.
+ */
+void
+na_action_profile_set_path( NAActionProfile *profile, const gchar *path )
+{
+ g_object_set( G_OBJECT( profile ), PROP_PROFILE_PATH_STR, path, NULL );
+}
+
+/**
+ * Set the parameters of the command for this profile.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * @parameters: parameters to be set.
+ */
+void
+na_action_profile_set_parameters( NAActionProfile *profile, const gchar *parameters )
+{
+ g_object_set( G_OBJECT( profile ), PROP_PROFILE_PARAMETERS_STR, parameters, NULL );
+}
+
+/**
+ * Set the basenames on which this profile applies.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * @basenames: list of basenames to be matched.
+ */
+void
+na_action_profile_set_basenames( NAActionProfile *profile, GSList *basenames )
+{
+ g_object_set( G_OBJECT( profile ), PROP_PROFILE_BASENAMES_STR, basenames, NULL );
+}
+
+/**
* Determines if the given profile is candidate to be displayed in the
* Nautilus context menu, regarding the list of currently selected
* items.
@@ -1106,10 +1144,7 @@ na_action_profile_parse_parameters( const NAActionProfile *profile, GList* files
/*hostname = g_strdup( gnome_vfs_uri_get_host_name( gvfs_uri ));
username = g_strdup( gnome_vfs_uri_get_user_name( gvfs_uri ));*/
- /* TODO
- * pwi 2009-06-10
- * don't know how to get hostname or username from GFile uri
- */
+ /* TODO get hostname or username from GFile uri */
hostname = NULL;
username = NULL;
diff --git a/src/common/na-action-profile.h b/src/common/na-action-profile.h
index 265e093..168bff4 100644
--- a/src/common/na-action-profile.h
+++ b/src/common/na-action-profile.h
@@ -88,7 +88,7 @@ typedef struct {
GType na_action_profile_get_type( void );
NAActionProfile *na_action_profile_new( const NAObject *action, const gchar *name );
-NAActionProfile *na_action_profile_duplicate( const NAActionProfile *profile );
+NAActionProfile *na_action_profile_duplicate( const NAAction *action, const NAActionProfile *profile );
void na_action_profile_free( NAActionProfile *profile );
NAObject *na_action_profile_get_action( const NAActionProfile *profile );
@@ -104,6 +104,10 @@ 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 );
+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 );
+
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-action.c b/src/common/na-action.c
index bc85687..0d69519 100644
--- a/src/common/na-action.c
+++ b/src/common/na-action.c
@@ -393,7 +393,7 @@ na_action_new_with_profile( void )
{
NAAction *action = na_action_new( NULL );
- NAActionProfile *profile = na_action_profile_new( NA_OBJECT( action ), NULL );
+ NAActionProfile *profile = na_action_profile_new( NA_OBJECT( action ), "default-profile" );
action->private->profiles = g_slist_prepend( action->private->profiles, profile );
@@ -432,7 +432,7 @@ na_action_duplicate( const NAAction *action )
duplicate->private->profiles =
g_slist_prepend(
duplicate->private->profiles,
- na_action_profile_duplicate( NA_ACTION_PROFILE( ip->data )));
+ na_action_profile_duplicate( duplicate, NA_ACTION_PROFILE( ip->data )));
}
return( duplicate );
@@ -753,7 +753,7 @@ na_action_set_profiles( NAAction *action, GSList *list )
for( ip = list ; ip ; ip = ip->next ){
action->private->profiles = g_slist_prepend(
action->private->profiles,
- na_action_profile_duplicate( NA_ACTION_PROFILE( ip->data ))
+ na_action_profile_duplicate( action, NA_ACTION_PROFILE( ip->data ))
);
}
}
diff --git a/src/common/na-action.h b/src/common/na-action.h
index 4bc1de2..236bbad 100644
--- a/src/common/na-action.h
+++ b/src/common/na-action.h
@@ -71,13 +71,13 @@ typedef struct {
* please note that property names must have the same spelling as the
* NactIIOProvider parameters
*/
-#define PROP_ACTION_UUID_STR "action-uuid"
-#define PROP_ACTION_VERSION_STR "action-version"
-#define PROP_ACTION_LABEL_STR "action-label"
-#define PROP_ACTION_TOOLTIP_STR "action-tooltip"
-#define PROP_ACTION_ICON_STR "action-icon"
-#define PROP_ACTION_READONLY_STR "action-read-only"
-#define PROP_ACTION_PROVIDER_STR "action-provider"
+#define PROP_ACTION_UUID_STR "uuid"
+#define PROP_ACTION_VERSION_STR "version"
+#define PROP_ACTION_LABEL_STR "label"
+#define PROP_ACTION_TOOLTIP_STR "tooltip"
+#define PROP_ACTION_ICON_STR "icon"
+#define PROP_ACTION_READONLY_STR "read-only"
+#define PROP_ACTION_PROVIDER_STR "provider"
GType na_action_get_type( void );
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
index 4df9728..0fcb71e 100644
--- a/src/nact/base-application.c
+++ b/src/nact/base-application.c
@@ -121,6 +121,8 @@ static gchar *do_get_unique_name( BaseApplication *application );
static gchar *do_get_application_name( BaseApplication *application );
static gchar *do_get_icon_name( BaseApplication *application );
+static gint display_dlg( BaseApplication *application, GtkMessageType type_message, GtkButtonsType type_buttons, const gchar *first, const gchar *second );
+
/*static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );*/
GType
@@ -998,31 +1000,26 @@ void
base_application_error_dlg(
BaseApplication *application, GtkMessageType type, const gchar *primary, const gchar *secondary )
{
- g_assert( BASE_IS_APPLICATION( application ));
-
- GtkWidget *dialog = gtk_message_dialog_new(
- NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_OK, primary );
-
- if( secondary && strlen( secondary )){
- gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( dialog ), secondary );
- }
-
- const gchar *name = g_get_application_name();
-
- g_object_set( G_OBJECT( dialog ) , "title", name, NULL );
-
- gtk_dialog_run( GTK_DIALOG( dialog ));
-
- gtk_widget_destroy( dialog );
+ display_dlg( application, type, GTK_BUTTONS_OK, primary, secondary );
}
gboolean
-base_application_yesno_dlg( BaseApplication *application, GtkMessageType type, const gchar *msg )
+base_application_yesno_dlg( BaseApplication *application, GtkMessageType type, const gchar *first, const gchar *second )
+{
+ gint result = display_dlg( application, type, GTK_BUTTONS_YES_NO, first, second );
+ return( result == GTK_RESPONSE_YES );
+}
+
+static gint
+display_dlg( BaseApplication *application, GtkMessageType type_message, GtkButtonsType type_buttons, const gchar *first, const gchar *second )
{
g_assert( BASE_IS_APPLICATION( application ));
- GtkWidget *dialog = gtk_message_dialog_new(
- NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_YES_NO, msg );
+ GtkWidget *dialog = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, type_message, type_buttons, first );
+
+ if( second && strlen( second )){
+ gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( dialog ), second );
+ }
const gchar *name = g_get_application_name();
@@ -1032,5 +1029,5 @@ base_application_yesno_dlg( BaseApplication *application, GtkMessageType type, c
gtk_widget_destroy( dialog );
- return( result == GTK_RESPONSE_YES );
+ return( result );
}
diff --git a/src/nact/base-application.h b/src/nact/base-application.h
index dd97dd2..16a96e2 100644
--- a/src/nact/base-application.h
+++ b/src/nact/base-application.h
@@ -108,7 +108,7 @@ GObject *base_application_get_main_window( BaseApplication *application );
GtkWidget *base_application_get_widget( BaseApplication *application, const gchar *name );
void base_application_error_dlg( BaseApplication *application, GtkMessageType type, const gchar *primary, const gchar *secondary );
-gboolean base_application_yesno_dlg( BaseApplication *application, GtkMessageType type, const gchar *msg );
+gboolean base_application_yesno_dlg( BaseApplication *application, GtkMessageType type, const gchar *first, const gchar *second );
G_END_DECLS
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index 1ddbd39..9b41e54 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -66,33 +66,33 @@ enum {
static GObjectClass *st_parent_class = NULL;
-static GType register_type( void );
-static void class_init( BaseWindowClass *klass );
-static void instance_init( GTypeInstance *instance, gpointer klass );
-static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void instance_dispose( GObject *application );
-static void instance_finalize( GObject *application );
-
-static gchar *v_get_toplevel_name( BaseWindow *window );
-static void v_initial_load_toplevel( BaseWindow *window );
-static void v_runtime_init_toplevel( BaseWindow *window );
-static void v_all_widgets_showed( BaseWindow *window );
-static void v_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
-
-static void do_init_window( BaseWindow *window );
-static void do_initial_load_toplevel( BaseWindow *window );
-static void do_runtime_init_toplevel( BaseWindow *window );
-static void do_all_widgets_showed( BaseWindow *window );
-static void do_run_window( BaseWindow *window );
-static void do_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
-static GObject *do_get_application( BaseWindow *window );
-static GtkWindow *do_get_toplevel_widget( BaseWindow *window );
-static GtkWidget *do_get_widget( BaseWindow *window, const gchar *name );
-
-static gboolean is_toplevel_initialized( BaseWindow *window );
-static void set_toplevel_initialized( BaseWindow *window );
-static gboolean is_main_window( BaseWindow *window );
+static GType register_type( void );
+static void class_init( BaseWindowClass *klass );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void instance_dispose( GObject *application );
+static void instance_finalize( GObject *application );
+
+static gchar *v_get_toplevel_name( BaseWindow *window );
+static void v_initial_load_toplevel( BaseWindow *window );
+static void v_runtime_init_toplevel( BaseWindow *window );
+static void v_all_widgets_showed( BaseWindow *window );
+static gboolean v_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
+
+static void do_init_window( BaseWindow *window );
+static void do_initial_load_toplevel( BaseWindow *window );
+static void do_runtime_init_toplevel( BaseWindow *window );
+static void do_all_widgets_showed( BaseWindow *window );
+static void do_run_window( BaseWindow *window );
+static gboolean do_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
+static GObject *do_get_application( BaseWindow *window );
+static GtkWindow *do_get_toplevel_widget( BaseWindow *window );
+static GtkWidget *do_get_widget( BaseWindow *window, const gchar *name );
+
+static gboolean is_toplevel_initialized( BaseWindow *window );
+static void set_toplevel_initialized( BaseWindow *window );
+static gboolean is_main_window( BaseWindow *window );
GType
base_window_get_type( void )
@@ -443,14 +443,19 @@ v_all_widgets_showed( BaseWindow *window )
}
}
-static void
+/*
+ * return TRUE to quit the dialog loop
+ */
+static gboolean
v_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
{
g_assert( BASE_IS_WINDOW( window ));
if( BASE_WINDOW_GET_CLASS( window )->dialog_response ){
- BASE_WINDOW_GET_CLASS( window )->dialog_response( dialog, code, window );
+ return( BASE_WINDOW_GET_CLASS( window )->dialog_response( dialog, code, window ));
}
+
+ return( TRUE );
}
static void
@@ -524,16 +529,21 @@ do_run_window( BaseWindow *window )
} else {
g_debug( "%s: starting gtk_dialog_run", thisfn );
- gint code = gtk_dialog_run( GTK_DIALOG( this_widget ));
- v_dialog_response( GTK_DIALOG( this_widget ), code, window );
+ gint code;
+ do {
+ code = gtk_dialog_run( GTK_DIALOG( this_widget ));
+ }
+ while( !v_dialog_response( GTK_DIALOG( this_widget ), code, window ));
}
}
-static void
+static gboolean
do_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
{
static const gchar *thisfn = "base_window_do_dialog_response";
g_debug( "%s: dialog=%p, code=%d, window=%p", thisfn, dialog, code, window );
+
+ return( TRUE );
}
static GObject *
@@ -601,8 +611,8 @@ base_window_error_dlg( BaseWindow *window, GtkMessageType type, const gchar *pri
}
gboolean
-base_window_yesno_dlg( BaseWindow *window, GtkMessageType type, const gchar *msg )
+base_window_yesno_dlg( BaseWindow *window, GtkMessageType type, const gchar *first, const gchar *second )
{
g_assert( BASE_IS_WINDOW( window ));
- return( base_application_yesno_dlg( window->private->application, type, msg ));
+ return( base_application_yesno_dlg( window->private->application, type, first, second ));
}
diff --git a/src/nact/base-window.h b/src/nact/base-window.h
index 87cc4e8..96de8a0 100644
--- a/src/nact/base-window.h
+++ b/src/nact/base-window.h
@@ -69,7 +69,7 @@ typedef struct {
void ( *initial_load_toplevel )( BaseWindow *window );
void ( *runtime_init_toplevel )( BaseWindow *window );
void ( *all_widgets_showed ) ( BaseWindow *window );
- void ( *dialog_response ) ( GtkDialog *dialog, gint code, BaseWindow *window );
+ gboolean ( *dialog_response ) ( GtkDialog *dialog, gint code, BaseWindow *window );
GObject * ( *get_application ) ( BaseWindow *window );
gchar * ( *get_toplevel_name ) ( BaseWindow *window );
GtkWindow * ( *get_toplevel_widget ) ( BaseWindow *window );
@@ -96,7 +96,7 @@ GtkWidget *base_window_get_widget( BaseWindow *window, const gchar *name );
void base_window_connect( BaseWindow *window, const gchar *widget, const gchar *signal, GCallback handler );
void base_window_error_dlg( BaseWindow *window, GtkMessageType type, const gchar *primary, const gchar *secondary );
-gboolean base_window_yesno_dlg( BaseWindow *window, GtkMessageType type, const gchar *msg );
+gboolean base_window_yesno_dlg( BaseWindow *window, GtkMessageType type, const gchar *first, const gchar *second );
G_END_DECLS
diff --git a/src/nact/nact-action-conditions-editor.c b/src/nact/nact-action-conditions-editor.c
index 048c9be..620a99f 100644
--- a/src/nact/nact-action-conditions-editor.c
+++ b/src/nact/nact-action-conditions-editor.c
@@ -72,10 +72,14 @@ static gchar *do_get_dialog_name( BaseWindow *dialog );
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( NactWindow *dialog );
-static void on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
+static void setup_dialog_title( NactActionConditionsEditor *dialog, gboolean is_modified );
+static void setup_buttons( NactActionConditionsEditor *dialog, gboolean is_modified );
+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 );
+static GObject *get_edited_profile( NactWindow *window );
static gboolean is_edited_modified( NactActionConditionsEditor *dialog );
GType
@@ -162,8 +166,7 @@ imenu_item_iface_init( NactIMenuItemInterface *iface )
g_debug( "%s: iface=%p", thisfn, iface );
iface->get_edited_action = get_edited_action;
- iface->update_dialog_title = setup_dialog_title;
- iface->signal_connected = nact_window_on_signal_connected;
+ iface->field_modified = on_modified_field;
}
static void
@@ -171,6 +174,9 @@ iprofile_conditions_iface_init( NactIProfileConditionsInterface *iface )
{
static const gchar *thisfn = "nact_action_conditions_editor_iprofile_conditions_iface_init";
g_debug( "%s: iface=%p", thisfn, iface );
+
+ iface->get_edited_profile = get_edited_profile;
+ iface->field_modified = on_modified_field;
}
static void
@@ -277,6 +283,10 @@ nact_action_conditions_editor_run_editor( NactWindow *parent, gpointer user_data
}
dialog->private->edited = na_action_duplicate( dialog->private->original );
+
+ g_assert( na_action_get_profiles_count( dialog->private->original ) == 1 );
+ g_assert( na_action_get_profiles_count( dialog->private->edited ) == 1 );
+
base_window_run( BASE_WINDOW( dialog ));
}
@@ -297,7 +307,9 @@ on_initial_load_dialog( BaseWindow *dialog )
NactActionConditionsEditor *window = NACT_ACTION_CONDITIONS_EDITOR( dialog );
nact_imenu_item_initial_load( NACT_WINDOW( window ), window->private->edited );
- nact_iprofile_conditions_initial_load( NACT_WINDOW( window ), window->private->edited );
+
+ NAActionProfile *profile = NA_ACTION_PROFILE( na_action_get_profiles( window->private->edited )->data );
+ nact_iprofile_conditions_initial_load( NACT_WINDOW( window ), profile );
}
static void
@@ -309,19 +321,20 @@ on_runtime_init_dialog( BaseWindow *dialog )
g_assert( NACT_IS_ACTION_CONDITIONS_EDITOR( dialog ));
NactActionConditionsEditor *window = NACT_ACTION_CONDITIONS_EDITOR( dialog );
- setup_dialog_title( NACT_WINDOW( window ));
+ setup_dialog_title( window, FALSE );
+
nact_imenu_item_runtime_init( NACT_WINDOW( window ), window->private->edited );
- nact_iprofile_conditions_runtime_init( NACT_WINDOW( window ), 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
-setup_dialog_title( NactWindow *window )
+setup_dialog_title( NactActionConditionsEditor *dialog, gboolean is_modified )
{
- g_assert( NACT_IS_ACTION_CONDITIONS_EDITOR( window ));
- NactActionConditionsEditor *dialog = ( NACT_ACTION_CONDITIONS_EDITOR( window ));
-
- gboolean is_modified = is_edited_modified( dialog );
-
GtkWindow *toplevel = base_window_get_toplevel_widget( BASE_WINDOW( dialog ));
gchar *title;
@@ -344,6 +357,41 @@ setup_dialog_title( NactWindow *window )
g_free( title );
}
+/*
+ * 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
+ */
+static void
+setup_buttons( NactActionConditionsEditor *dialog, gboolean is_modified )
+{
+ 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_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 );
+}
+
+static void
+on_modified_field( NactWindow *window )
+{
+ 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" );
+
+ setup_dialog_title( dialog, is_modified );
+ setup_buttons( dialog, is_modified );
+}
+
static void
on_all_widgets_showed( BaseWindow *dialog )
{
@@ -356,21 +404,52 @@ on_all_widgets_showed( BaseWindow *dialog )
nact_imenu_item_all_widgets_showed( NACT_WINDOW( dialog ));
}
-static void
+/*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 )
{
static const gchar *thisfn = "nact_action_conditions_editor_on_dialog_response";
g_debug( "%s: dialog=%p, code=%d, window=%p", thisfn, dialog, code, window );
g_assert( NACT_IS_ACTION_CONDITIONS_EDITOR( window ));
+ NactActionConditionsEditor *editor = NACT_ACTION_CONDITIONS_EDITOR( window );
+
+ gboolean is_modified = is_edited_modified( editor );
switch( code ){
case GTK_RESPONSE_NONE:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CLOSE:
- g_object_unref( window );
+ case GTK_RESPONSE_CANCEL:
+ if( !is_modified ||
+ nact_window_warn_action_modified( NACT_WINDOW( editor ), editor->private->original )){
+ g_object_unref( window );
+ return( TRUE );
+ }
+ break;
+
+ case GTK_RESPONSE_OK:
+ if( is_modified ){
+ if( nact_window_save_action( NACT_WINDOW( editor ), editor->private->edited )){
+ g_object_unref( editor->private->original );
+ editor->private->original = na_action_duplicate( editor->private->edited );
+ editor->private->is_new = FALSE;
+ g_debug( "%s: after replication", thisfn );
+ on_modified_field( NACT_WINDOW( editor ));
+ }
+ }
break;
}
+
+ return( FALSE );
}
static GObject *
@@ -380,6 +459,13 @@ get_edited_action( NactWindow *window )
return( G_OBJECT( NACT_ACTION_CONDITIONS_EDITOR( window )->private->edited ));
}
+static GObject *
+get_edited_profile( NactWindow *window )
+{
+ g_assert( NACT_IS_ACTION_CONDITIONS_EDITOR( window ));
+ return( G_OBJECT( na_action_get_profiles( NACT_ACTION_CONDITIONS_EDITOR( window )->private->edited )->data ));
+}
+
static gboolean
is_edited_modified( NactActionConditionsEditor *dialog )
{
diff --git a/src/nact/nact-action-profiles-editor.c b/src/nact/nact-action-profiles-editor.c
index 08812b8..3316764 100644
--- a/src/nact/nact-action-profiles-editor.c
+++ b/src/nact/nact-action-profiles-editor.c
@@ -56,20 +56,20 @@ struct NactActionProfilesEditorPrivate {
static GObjectClass *st_parent_class = NULL;
-static GType register_type( void );
-static void class_init( NactActionProfilesEditorClass *klass );
-static void imenu_item_iface_init( NactIMenuItemInterface *iface );
-static void instance_init( GTypeInstance *instance, gpointer klass );
-static void instance_dispose( GObject *dialog );
-static void instance_finalize( GObject *dialog );
+static GType register_type( void );
+static void class_init( NactActionProfilesEditorClass *klass );
+static void imenu_item_iface_init( NactIMenuItemInterface *iface );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *dialog );
+static void instance_finalize( GObject *dialog );
static NactActionProfilesEditor *action_profiles_editor_new( BaseApplication *application );
-static gchar *do_get_dialog_name( BaseWindow *dialog );
-static void on_initial_load_dialog( BaseWindow *dialog );
-static void on_runtime_init_dialog( BaseWindow *dialog );
-static void init_dialog_title( NactActionProfilesEditor *dialog );
-static void on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
+static gchar *do_get_dialog_name( BaseWindow *dialog );
+static void on_initial_load_dialog( BaseWindow *dialog );
+static void on_runtime_init_dialog( BaseWindow *dialog );
+static void init_dialog_title( NactActionProfilesEditor *dialog );
+static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
GType
nact_action_profiles_editor_get_type( void )
@@ -142,8 +142,6 @@ imenu_item_iface_init( NactIMenuItemInterface *iface )
{
static const gchar *thisfn = "nact_action_profiles_editor_imenu_item_iface_init";
g_debug( "%s: iface=%p", thisfn, iface );
-
- iface->signal_connected = nact_window_on_signal_connected;
}
static void
@@ -295,7 +293,7 @@ init_dialog_title( NactActionProfilesEditor *dialog )
}
}
-static void
+static gboolean
on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
{
static const gchar *thisfn = "nact_action_profiles_editor_on_dialog_response";
@@ -310,4 +308,6 @@ on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
g_object_unref( window );
break;
}
+
+ return( TRUE );
}
diff --git a/src/nact/nact-imenu-item.c b/src/nact/nact-imenu-item.c
index 9423727..bc3848b 100644
--- a/src/nact/nact-imenu-item.c
+++ b/src/nact/nact-imenu-item.c
@@ -58,8 +58,7 @@ static void interface_base_init( NactIMenuItemInterface *klass );
static void interface_base_finalize( NactIMenuItemInterface *klass );
static GObject *v_get_edited_action( NactWindow *window );
-static void v_update_dialog_title( NactWindow *window );
-static void v_signal_connected( NactWindow *window, gpointer instance, gulong handler_id );
+static void v_field_modified( NactWindow *window );
static void icon_combo_list_fill( GtkComboBoxEntry* combo );
static GtkTreeModel *create_stock_icon_model( void );
@@ -69,8 +68,7 @@ static gchar *strip_underscore( const gchar *text );
static void on_label_changed( GtkEntry *entry, gpointer user_data );
static void on_tooltip_changed( GtkEntry *entry, gpointer user_data );
static void on_icon_changed( GtkEntry *entry, gpointer user_data );
-
-static void record_signal( NactWindow *window, GObject *instance, const gchar *signal, GCallback fn, gpointer user_data );
+static void on_icon_browse( GtkButton *button, gpointer user_data );
GType
nact_imenu_item_get_type( void )
@@ -121,8 +119,7 @@ interface_base_init( NactIMenuItemInterface *klass )
klass->private = g_new0( NactIMenuItemInterfacePrivate, 1 );
klass->get_edited_action = NULL;
- klass->update_dialog_title = NULL;
- klass->signal_connected = NULL;
+ klass->field_modified = NULL;
initialized = TRUE;
}
@@ -163,22 +160,26 @@ nact_imenu_item_runtime_init( NactWindow *dialog, NAAction *action )
g_debug( "%s: dialog=%p, action=%p", thisfn, dialog, action );
GtkWidget *label_widget = base_window_get_widget( BASE_WINDOW( dialog ), "MenuLabelEntry" );
- record_signal( dialog, G_OBJECT( label_widget ), "changed", G_CALLBACK( on_label_changed ), dialog );
+ nact_window_signal_connect( dialog, G_OBJECT( label_widget ), "changed", G_CALLBACK( on_label_changed ));
gchar *label = na_action_get_label( action );
gtk_entry_set_text( GTK_ENTRY( label_widget ), label );
g_free( label );
GtkWidget *tooltip_widget = base_window_get_widget( BASE_WINDOW( dialog ), "MenuTooltipEntry" );
- record_signal( dialog, G_OBJECT( tooltip_widget ), "changed", G_CALLBACK( on_tooltip_changed ), dialog );
+ nact_window_signal_connect( dialog, G_OBJECT( tooltip_widget ), "changed", G_CALLBACK( on_tooltip_changed ));
gchar *tooltip = na_action_get_tooltip( action );
gtk_entry_set_text( GTK_ENTRY( tooltip_widget ), tooltip );
g_free( tooltip );
GtkWidget *icon_widget = base_window_get_widget( BASE_WINDOW( dialog ), "MenuIconComboBoxEntry" );
- record_signal( dialog, G_OBJECT( GTK_BIN( icon_widget )->child ), "changed", G_CALLBACK( on_icon_changed ), dialog );
+ g_debug( "%s: icon_widget=%p, child=%p", thisfn, icon_widget, GTK_BIN( icon_widget )->child );
+ nact_window_signal_connect( dialog, G_OBJECT( GTK_BIN( icon_widget )->child ), "changed", G_CALLBACK( on_icon_changed ));
gchar *icon = na_action_get_icon( action );
gtk_entry_set_text( GTK_ENTRY( GTK_BIN( icon_widget )->child ), icon );
g_free( icon );
+
+ GtkWidget *button = base_window_get_widget( BASE_WINDOW( dialog ), "IconBrowseButton" );
+ nact_window_signal_connect( dialog, G_OBJECT( button ), "clicked", G_CALLBACK( on_icon_browse ));
}
void
@@ -201,22 +202,12 @@ v_get_edited_action( NactWindow *window )
}
static void
-v_update_dialog_title( NactWindow *window )
-{
- g_assert( NACT_IS_IMENU_ITEM( window ));
-
- if( NACT_IMENU_ITEM_GET_INTERFACE( window )->update_dialog_title ){
- NACT_IMENU_ITEM_GET_INTERFACE( window )->update_dialog_title( window );
- }
-}
-
-static void
-v_signal_connected( NactWindow *window, gpointer instance, gulong handler_id )
+v_field_modified( NactWindow *window )
{
g_assert( NACT_IS_IMENU_ITEM( window ));
- if( NACT_IMENU_ITEM_GET_INTERFACE( window )->signal_connected ){
- NACT_IMENU_ITEM_GET_INTERFACE( window )->signal_connected( window, instance, handler_id );
+ if( NACT_IMENU_ITEM_GET_INTERFACE( window )->field_modified ){
+ NACT_IMENU_ITEM_GET_INTERFACE( window )->field_modified( window );
}
}
@@ -341,7 +332,7 @@ on_label_changed( GtkEntry *entry, gpointer user_data )
NAAction *edited = NA_ACTION( v_get_edited_action( dialog ));
na_action_set_label( edited, gtk_entry_get_text( entry ));
- v_update_dialog_title( dialog );
+ v_field_modified( dialog );
}
static void
@@ -353,7 +344,7 @@ on_tooltip_changed( GtkEntry *entry, gpointer user_data )
NAAction *edited = NA_ACTION( v_get_edited_action( dialog ));
na_action_set_tooltip( edited, gtk_entry_get_text( entry ));
- v_update_dialog_title( dialog );
+ v_field_modified( dialog );
}
static void
@@ -408,12 +399,30 @@ on_icon_changed( GtkEntry *icon_entry, gpointer user_data )
NAAction *edited = NA_ACTION( v_get_edited_action( dialog ));
na_action_set_icon( edited, icon_name );
- v_update_dialog_title( dialog );
+ v_field_modified( dialog );
}
+/* TODO: replace with a fds-compliant icon chooser */
static void
-record_signal( NactWindow *window, GObject *instance, const gchar *signal, GCallback fn, gpointer user_data )
+on_icon_browse( GtkButton *button, gpointer user_data )
{
- gulong handler_id = g_signal_connect( instance, signal, fn, user_data );
- v_signal_connected( window, instance, handler_id );
+ g_assert( NACT_IS_IMENU_ITEM( user_data ));
+
+ GtkWidget *dialog = gtk_file_chooser_dialog_new(
+ _( "Choosing an icon" ),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL
+ );
+
+ if( gtk_dialog_run( GTK_DIALOG( dialog )) == GTK_RESPONSE_ACCEPT ){
+ gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ));
+ GtkWidget *icon_widget = base_window_get_widget( BASE_WINDOW( user_data ), "MenuIconComboBoxEntry" );
+ gtk_entry_set_text( GTK_ENTRY( GTK_BIN( icon_widget )->child ), filename );
+ g_free (filename);
+ }
+
+ gtk_widget_destroy( dialog );
}
diff --git a/src/nact/nact-imenu-item.h b/src/nact/nact-imenu-item.h
index 0705a48..b7f9c87 100644
--- a/src/nact/nact-imenu-item.h
+++ b/src/nact/nact-imenu-item.h
@@ -57,9 +57,8 @@ typedef struct {
NactIMenuItemInterfacePrivate *private;
/* api */
- GObject * ( *get_edited_action ) ( NactWindow *window );
- void ( *update_dialog_title )( NactWindow *window );
- void ( *signal_connected ) ( NactWindow *window, gpointer instance, gulong handler_id );
+ GObject * ( *get_edited_action )( NactWindow *window );
+ void ( *field_modified ) ( NactWindow *window );
}
NactIMenuItemInterface;
diff --git a/src/nact/nact-iprofile-conditions.c b/src/nact/nact-iprofile-conditions.c
index 7ec4b38..ca3ae0b 100644
--- a/src/nact/nact-iprofile-conditions.c
+++ b/src/nact/nact-iprofile-conditions.c
@@ -32,8 +32,12 @@
#include <config.h>
#endif
+#include <glib/gi18n.h>
+#include <string.h>
+
#include <common/na-action.h>
#include <common/na-action-profile.h>
+#include <common/na-utils.h>
#include "nact-iprofile-conditions.h"
@@ -42,11 +46,36 @@
struct NactIProfileConditionsInterfacePrivate {
};
-static GType register_type( void );
-static void interface_base_init( NactIProfileConditionsInterface *klass );
-static void interface_base_finalize( NactIProfileConditionsInterface *klass );
+/* column ordering
+ */
+enum {
+ SCHEMES_CHECKBOX_COLUMN = 0,
+ SCHEMES_KEYWORD_COLUMN,
+ SCHEMES_DESC_COLUMN,
+ SCHEMES_N_COLUMN
+};
+
+static GType register_type( void );
+static void interface_base_init( NactIProfileConditionsInterface *klass );
+static void interface_base_finalize( NactIProfileConditionsInterface *klass );
-/*static GObject *v_get_edited_action( NactWindow *window );*/
+static GObject *v_get_edited_profile( NactWindow *window );
+static void v_field_modified( NactWindow *window );
+
+static gchar *basenames_to_text( GSList *basenames );
+static GSList *text_to_basenames( const gchar *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 GSList *get_schemes_default_list( NactWindow *window );
+
+static void on_path_changed( GtkEntry *entry, 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 );
+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 );
GType
nact_iprofile_conditions_get_type( void )
@@ -96,6 +125,9 @@ interface_base_init( NactIProfileConditionsInterface *klass )
klass->private = g_new0( NactIProfileConditionsInterfacePrivate, 1 );
+ klass->get_edited_profile = NULL;
+ klass->field_modified = NULL;
+
initialized = TRUE;
}
}
@@ -116,30 +148,328 @@ interface_base_finalize( NactIProfileConditionsInterface *klass )
}
void
-nact_iprofile_conditions_initial_load( NactWindow *dialog, NAAction *action )
+nact_iprofile_conditions_initial_load( NactWindow *dialog, NAActionProfile *profile )
{
+ create_schemes_selection_list( dialog );
}
void
-nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAAction *action )
+nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAActionProfile *profile )
{
+ static const gchar *thisfn = "nact_iprofile_conditions_runtime_init";
+ g_debug( "%s: dialog=%p, profile=%p", thisfn, dialog, profile );
+
+ 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 );
+ 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 );
+
+ 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 ));
+ gchar *parameters = na_action_profile_get_parameters( profile );
+ gtk_entry_set_text( GTK_ENTRY( parameters_widget ), parameters );
+ g_free( parameters );
+
+ button = base_window_get_widget( BASE_WINDOW( dialog ), "LegendButton" );
+ /* TODO: implement legend button */
+ gtk_widget_set_sensitive( button, FALSE );
+
+ GtkWidget *basenames_widget = base_window_get_widget( BASE_WINDOW( dialog ), "PatternEntry" );
+ nact_window_signal_connect( dialog, G_OBJECT( basenames_widget ), "changed", G_CALLBACK( on_basenames_changed ));
+ GSList *basenames = na_action_profile_get_basenames( profile );
+ gchar *basenames_text = basenames_to_text( basenames );
+ gtk_entry_set_text( GTK_ENTRY( basenames_widget ), basenames_text );
+ g_free( basenames_text );
+ na_utils_free_string_list( basenames );
+
+ /* TODO: match case */
+ /* TODO: mime types */
+ /* TODO: file/dir */
+ /* TODO: multiple selection */
+
+ 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 ));
+
+ column = gtk_tree_view_get_column( scheme_widget, SCHEMES_KEYWORD_COLUMN );
+ renderers = gtk_tree_view_column_get_cell_renderers( column );
+ nact_window_signal_connect( dialog, G_OBJECT( renderers->data ), "edited", G_CALLBACK( on_scheme_keyword_edited ));
+
+ column = gtk_tree_view_get_column( scheme_widget, SCHEMES_DESC_COLUMN );
+ 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 ));
+
+ 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 */
}
-/*void
-nact_iprofile_conditions_all_widgets_showed( NactWindow *dialog )
+static GObject *
+v_get_edited_profile( NactWindow *window )
{
- static const gchar *thisfn = "nact_iprofile_conditions_all_widgets_showed";
- g_debug( "%s: dialog=%p", thisfn, dialog );
-}*/
+ g_assert( NACT_IS_IPROFILE_CONDITIONS( window ));
+
+ if( NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->get_edited_profile ){
+ return( NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->get_edited_profile( window ));
+ }
+
+ return( NULL );
+}
-/*static GObject *
-v_get_edited_action( NactWindow *window )
+static void
+v_field_modified( NactWindow *window )
{
g_assert( NACT_IS_IPROFILE_CONDITIONS( window ));
- if( NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->get_edited_action ){
- return( NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->get_edited_action( window ));
+ if( NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->field_modified ){
+ NACT_IPROFILE_CONDITIONS_GET_INTERFACE( window )->field_modified( window );
}
+}
- return( NULL );
-}*/
+static gchar *
+basenames_to_text( GSList *basenames )
+{
+ GSList *ib;
+ gchar *tmp;
+ gchar *text = g_strdup( "" );
+
+ for( ib = basenames ; ib ; ib = ib->next ){
+ if( strlen( text )){
+ tmp = g_strdup_printf( "%s; ", text );
+ g_free( text );
+ text = tmp;
+ }
+ tmp = g_strdup_printf( "%s%s", text, ( gchar * ) ib->data );
+ g_free( text );
+ text = tmp;
+ }
+
+ return( text );
+}
+
+static GSList *
+text_to_basenames( const gchar *text )
+{
+ GSList *basenames = NULL;
+ gchar **tokens, **iter;
+ gchar *tmp;
+ gchar *source = g_strdup( text );
+
+ tmp = g_strstrip( source );
+ if( !strlen( tmp )){
+ basenames = g_slist_append( basenames, g_strdup( "*" ));
+
+ } else {
+ tokens = g_strsplit( source, ";", -1 );
+ iter = tokens;
+
+ while( *iter ){
+ tmp = g_strstrip( *iter );
+ basenames = g_slist_append( basenames, g_strdup( tmp ));
+ iter++;
+ }
+
+ g_strfreev( tokens );
+ }
+
+ g_free( source );
+ return( basenames );
+}
+
+static GtkTreeView *
+get_schemes_tree_view( NactWindow *window )
+{
+ return( GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( window ), "SchemesTreeView" )));
+}
+
+static GtkTreeModel *
+get_schemes_tree_model( NactWindow *window )
+{
+ GtkTreeView *schemes_view = get_schemes_tree_view( window );
+ return( gtk_tree_view_get_model( schemes_view ));
+}
+
+static void
+create_schemes_selection_list( NactWindow *window )
+{
+ static const char *thisfn = "nact_iprofile_conditions_create_schemes_selection_list";
+ g_debug( "%s: window=%p", thisfn, window );
+ g_assert( NACT_IS_IPROFILE_CONDITIONS( window ));
+
+ GtkWidget *listview = GTK_WIDGET( get_schemes_tree_view( window ));
+ GSList* schemes_list = get_schemes_default_list( window );
+ GtkListStore *model = gtk_list_store_new( SCHEMES_N_COLUMN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING );
+
+ GSList *iter;
+ GtkTreeIter row;
+ for( iter = schemes_list ; iter ; iter = iter->next ){
+
+ gchar **tokens = g_strsplit(( gchar * ) iter->data, "|", 2 );
+ gtk_list_store_append( model, &row );
+ gtk_list_store_set( model, &row,
+ SCHEMES_CHECKBOX_COLUMN, FALSE,
+ SCHEMES_KEYWORD_COLUMN, tokens[0],
+ SCHEMES_DESC_COLUMN, tokens[1],
+ -1 );
+ g_strfreev( tokens );
+ }
+
+ na_utils_free_string_list( schemes_list );
+
+ gtk_tree_view_set_model( GTK_TREE_VIEW( listview ), GTK_TREE_MODEL( model ));
+ g_object_unref( model );
+
+ GtkCellRenderer *toggled_cell = gtk_cell_renderer_toggle_new();
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
+ "scheme-selected",
+ toggled_cell,
+ "active", SCHEMES_CHECKBOX_COLUMN,
+ NULL );
+ gtk_tree_view_append_column( GTK_TREE_VIEW( listview ), column );
+ /*g_debug( "%s: toggled_cell=%p", thisfn, toggled_cell );*/
+
+ GtkCellRenderer *text_cell = gtk_cell_renderer_text_new();
+ g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
+ column = gtk_tree_view_column_new_with_attributes(
+ "scheme-code",
+ text_cell,
+ "text", SCHEMES_KEYWORD_COLUMN,
+ NULL );
+ gtk_tree_view_append_column( GTK_TREE_VIEW( listview ), column );
+
+ text_cell = gtk_cell_renderer_text_new();
+ g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
+ column = gtk_tree_view_column_new_with_attributes(
+ "scheme-description",
+ text_cell,
+ "text", SCHEMES_DESC_COLUMN,
+ NULL );
+ gtk_tree_view_append_column( GTK_TREE_VIEW( listview ), column );
+}
+
+static GSList *
+get_schemes_default_list( NactWindow *window )
+{
+ GSList *list = NULL;
+
+ /* i18n notes : description of 'file' scheme */
+ list = g_slist_append( list, g_strdup( _( "file|Local files")));
+ /* i18n notes : description of 'sftp' scheme */
+ list = g_slist_append( list, g_strdup( _( "sftp|SSH files")));
+ /* i18n notes : description of 'smb' scheme */
+ list = g_slist_append( list, g_strdup( _( "smb|Windows files")));
+ /* i18n notes : description of 'ftp' scheme */
+ list = g_slist_append( list, g_strdup( _( "ftp|FTP files")));
+ /* i18n notes : description of 'dav' scheme */
+ list = g_slist_append( list, g_strdup( _( "dav|WebDAV files")));
+
+ return( list );
+}
+
+static void
+on_path_changed( GtkEntry *entry, gpointer user_data )
+{
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+ na_action_profile_set_path( edited, gtk_entry_get_text( entry ));
+
+ v_field_modified( dialog );
+}
+
+static void
+on_parameters_changed( GtkEntry *entry, gpointer user_data )
+{
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+ na_action_profile_set_parameters( edited, gtk_entry_get_text( entry ));
+
+ v_field_modified( dialog );
+}
+
+static void
+on_basenames_changed( GtkEntry *entry, gpointer user_data )
+{
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ NAActionProfile *edited = NA_ACTION_PROFILE( v_get_edited_profile( dialog ));
+ const gchar *text = gtk_entry_get_text( entry );
+ GSList *basenames = text_to_basenames( text );
+ na_action_profile_set_basenames( edited, basenames );
+ na_utils_free_string_list( basenames );
+
+ v_field_modified( dialog );
+}
+
+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 );*/
+ 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;
+ 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 ));*/
+
+ v_field_modified( dialog );
+}
+
+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 );
+
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ 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 );
+
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ v_field_modified( dialog );
+}
+
+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 );
+
+ g_assert( NACT_IS_WINDOW( user_data ));
+ NactWindow *dialog = NACT_WINDOW( user_data );
+
+ v_field_modified( dialog );
+}
diff --git a/src/nact/nact-iprofile-conditions.h b/src/nact/nact-iprofile-conditions.h
index 57ffada..f79f038 100644
--- a/src/nact/nact-iprofile-conditions.h
+++ b/src/nact/nact-iprofile-conditions.h
@@ -38,7 +38,7 @@
* conditions for the action.
*/
-#include <common/na-action.h>
+#include <common/na-action-profile.h>
#include "nact-window.h"
@@ -58,15 +58,15 @@ typedef struct {
NactIProfileConditionsInterfacePrivate *private;
/* api */
- GObject * ( *get_edited_action ) ( NactWindow *window );
- void ( *signal_connected ) ( NactWindow *window, gpointer instance, gulong handler_id );
+ GObject * ( *get_edited_profile )( NactWindow *window );
+ void ( *field_modified ) ( NactWindow *window );
}
NactIProfileConditionsInterface;
GType nact_iprofile_conditions_get_type( void );
-void nact_iprofile_conditions_initial_load( NactWindow *dialog, NAAction *action );
-void nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAAction *action );
+void nact_iprofile_conditions_initial_load( NactWindow *dialog, NAActionProfile *profile );
+void nact_iprofile_conditions_runtime_init( NactWindow *dialog, NAActionProfile *profile );
G_END_DECLS
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index c54adf6..c48e5a3 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -83,7 +83,7 @@ static void on_edit_button_clicked( GtkButton *button, gpointer user_data );
static void on_duplicate_button_clicked( GtkButton *button, gpointer user_data );
static void on_delete_button_clicked( GtkButton *button, gpointer user_data );
static void on_import_export_button_clicked( GtkButton *button, gpointer user_data );
-static void on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window );
+static gboolean on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window );
static void on_actions_changed( NAIPivotContainer *instance, gpointer user_data );
@@ -497,7 +497,7 @@ on_delete_button_clicked( GtkButton *button, gpointer user_data )
gchar *label = na_action_get_label( action );
gchar *sure = g_strdup_printf( _( "Are you sure you want to delete \"%s\" action ?" ), label );
- if( base_window_yesno_dlg( BASE_WINDOW( wndmain ), GTK_MESSAGE_WARNING, sure )){
+ if( base_window_yesno_dlg( BASE_WINDOW( wndmain ), GTK_MESSAGE_WARNING, sure, NULL )){
gchar *msg = NULL;
NAPivot *pivot = NA_PIVOT( nact_window_get_pivot( wndmain ));
@@ -534,7 +534,7 @@ on_import_export_button_clicked( GtkButton *button, gpointer user_data )
}*/
}
-static void
+static gboolean
on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window )
{
static const gchar *thisfn = "nact_main_window_on_dialog_response";
@@ -557,11 +557,14 @@ on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window )
*/
g_object_unref( window );
+ return( TRUE );
/*gtk_widget_destroy (GTK_WIDGET (dialog));
nact_destroy_glade_objects ();
gtk_main_quit ();*/
break;
}
+
+ return( FALSE );
}
static void
diff --git a/src/nact/nact-profile-conditions-editor.c b/src/nact/nact-profile-conditions-editor.c
index a87611d..9935688 100644
--- a/src/nact/nact-profile-conditions-editor.c
+++ b/src/nact/nact-profile-conditions-editor.c
@@ -56,20 +56,20 @@ struct NactProfileConditionsEditorPrivate {
static GObjectClass *st_parent_class = NULL;
-static GType register_type( void );
-static void class_init( NactProfileConditionsEditorClass *klass );
-static void iprofile_conditions_iface_init( NactIProfileConditionsInterface *iface );
-static void instance_init( GTypeInstance *instance, gpointer klass );
-static void instance_dispose( GObject *dialog );
-static void instance_finalize( GObject *dialog );
+static GType register_type( void );
+static void class_init( NactProfileConditionsEditorClass *klass );
+static void iprofile_conditions_iface_init( NactIProfileConditionsInterface *iface );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *dialog );
+static void instance_finalize( GObject *dialog );
static NactProfileConditionsEditor *profile_conditions_editor_new( BaseApplication *application );
-static gchar *do_get_dialog_name( BaseWindow *dialog );
-static void on_initial_load_dialog( BaseWindow *dialog );
-static void on_runtime_init_dialog( BaseWindow *dialog );
-static void init_dialog_title( NactProfileConditionsEditor *dialog );
-static void on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
+static gchar *do_get_dialog_name( BaseWindow *dialog );
+static void on_initial_load_dialog( BaseWindow *dialog );
+static void on_runtime_init_dialog( BaseWindow *dialog );
+static void init_dialog_title( NactProfileConditionsEditor *dialog );
+static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
GType
nact_profile_conditions_editor_get_type( void )
@@ -260,7 +260,7 @@ on_initial_load_dialog( BaseWindow *dialog )
NactProfileConditionsEditor *window = NACT_PROFILE_CONDITIONS_EDITOR( dialog );
init_dialog_title( window );
- nact_iprofile_conditions_initial_load( NACT_WINDOW( window ), window->private->action );
+ /*nact_iprofile_conditions_initial_load( NACT_WINDOW( window ), window->private->action );*/
}
static void
@@ -273,7 +273,7 @@ on_runtime_init_dialog( BaseWindow *dialog )
NactProfileConditionsEditor *window = NACT_PROFILE_CONDITIONS_EDITOR( dialog );
init_dialog_title( window );
- nact_iprofile_conditions_runtime_init( NACT_WINDOW( window ), window->private->action );
+ /*nact_iprofile_conditions_runtime_init( NACT_WINDOW( window ), window->private->action );*/
}
static void
@@ -293,7 +293,7 @@ init_dialog_title( NactProfileConditionsEditor *dialog )
}
}
-static void
+static gboolean
on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
{
static const gchar *thisfn = "nact_profile_conditions_editor_on_dialog_response";
@@ -308,4 +308,6 @@ on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
g_object_unref( window );
break;
}
+
+ return( TRUE );
}
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index d99fe0d..5929abe 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -33,8 +33,10 @@
#endif
#include <glib.h>
+#include <glib/gi18n.h>
#include <common/na-pivot.h>
+#include <common/na-iio-provider.h>
#include "nact-application.h"
#include "nact-window.h"
@@ -206,6 +208,64 @@ nact_window_get_action( NactWindow *window, const gchar *uuid )
}
/**
+ * Saves a modified action to the I/O storage subsystem.
+ *
+ * @window: this NactWindow object.
+ *
+ * @action: the modified action.
+ */
+gboolean
+nact_window_save_action( NactWindow *window, const NAAction *action )
+{
+ NAPivot *pivot = NA_PIVOT( nact_window_get_pivot( window ));
+ g_assert( NA_IS_PIVOT( pivot ));
+
+ na_object_dump( NA_OBJECT( action ));
+
+ gchar *msg = NULL;
+ guint ret = na_pivot_write_action( pivot, G_OBJECT( action ), &msg );
+ if( msg ){
+ base_window_error_dlg(
+ BASE_WINDOW( window ),
+ GTK_MESSAGE_WARNING, _( "An error has occured when trying to save the action" ), msg );
+ g_free( msg );
+ }
+
+ return( ret == NA_IIO_PROVIDER_WRITE_OK );
+}
+
+/**
+ * Emits a warning if the action has been modified.
+ *
+ * @window: this NactWindow object.
+ *
+ * @action: the modified action.
+ *
+ * Returns TRUE if the user confirms he wants to quit.
+ */
+gboolean
+nact_window_warn_action_modified( NactWindow *window, const NAAction *action )
+{
+ gchar *label = na_action_get_label( action );
+
+ gchar *first;
+ if( label && strlen( label )){
+ first = g_strdup_printf( _( "The action \"%s\" has been modified." ), label );
+ } else {
+ first = g_strdup( _( "The newly created action has been modified" ));
+ }
+ gchar *second = g_strdup( _( "Are you sure you want to quit without saving it ?" ));
+
+ gboolean ok = base_window_yesno_dlg( BASE_WINDOW( window ), GTK_MESSAGE_QUESTION, first, second );
+
+ g_free( second );
+ g_free( first );
+ g_free( label );
+
+ return( ok );
+}
+
+/**
* Returns a pointer to the list of actions.
*/
GSList *
@@ -222,13 +282,16 @@ nact_window_get_actions( NactWindow *window )
* Records a connected signal, to be disconnected at NactWindow dispose.
*/
void
-nact_window_on_signal_connected( NactWindow *window, gpointer instance, gulong handler_id )
+nact_window_signal_connect( NactWindow *window, GObject *instance, const gchar *signal, GCallback fn )
{
- static const gchar *thisfn = "nact_window_on_signal_connected";
- g_debug( "%s: window=%p, instance=%p, handler_id=%lu", thisfn, window, instance, handler_id );
+ static const gchar *thisfn = "nact_window_signal_connect";
+
+ gulong handler_id = g_signal_connect( instance, signal, fn, window );
NactWindowRecordedSignal *str = g_new0( NactWindowRecordedSignal, 1 );
str->instance = instance;
str->handler_id = handler_id;
window->private->signals = g_slist_prepend( window->private->signals, str );
+
+ g_debug( "%s: connecting signal handler %p:%lu", thisfn, instance, handler_id );
}
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index d6e3cb0..bfd27d8 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -38,6 +38,8 @@
* It is a common base class for all Nautilus Actions window documents.
*/
+#include <common/na-action.h>
+
#include "base-window.h"
G_BEGIN_DECLS
@@ -70,10 +72,13 @@ GType nact_window_get_type( void );
GObject *nact_window_get_pivot( NactWindow *window );
GObject *nact_window_get_action( NactWindow *window, const gchar *uuid );
+gboolean nact_window_save_action( NactWindow *window, const NAAction *action );
+
+gboolean nact_window_warn_action_modified( NactWindow *window, const NAAction *action );
GSList *nact_window_get_actions( NactWindow *window );
-void nact_window_on_signal_connected( NactWindow *window, gpointer instance, gulong handler_id );
+void nact_window_signal_connect( NactWindow *window, GObject *instance, const gchar *signal, GCallback fn );
G_END_DECLS
diff --git a/src/nact/nautilus-actions-config.ui b/src/nact/nautilus-actions-config.ui
index 50cba4f..e4ad3f9 100644
--- a/src/nact/nautilus-actions-config.ui
+++ b/src/nact/nautilus-actions-config.ui
@@ -994,7 +994,7 @@
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
- <object class="GtkButton" id="cancelbutton1">
+ <object class="GtkButton" id="CancelButton">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -1009,8 +1009,8 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="okbutton1">
- <property name="label">gtk-ok</property>
+ <object class="GtkButton" id="SaveButton">
+ <property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
@@ -1033,8 +1033,8 @@
</object>
</child>
<action-widgets>
- <action-widget response="-6">cancelbutton1</action-widget>
- <action-widget response="-5">okbutton1</action-widget>
+ <action-widget response="-6">CancelButton</action-widget>
+ <action-widget response="-5">SaveButton</action-widget>
</action-widgets>
</object>
</interface>
diff --git a/src/plugin/nautilus-actions.c b/src/plugin/nautilus-actions.c
index 075ca75..fa4d2e0 100644
--- a/src/plugin/nautilus-actions.c
+++ b/src/plugin/nautilus-actions.c
@@ -328,7 +328,7 @@ create_menu_item( NAAction *action, NAActionProfile *profile, GList *files )
gchar *tooltip = na_action_get_tooltip( action );
gchar* icon_name = na_action_get_verified_icon_name( action );
- NAActionProfile *dup4menu = na_action_profile_duplicate( profile );
+ NAActionProfile *dup4menu = na_action_profile_duplicate( action, profile );
item = nautilus_menu_item_new( name, label, tooltip, icon_name );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]