[nautilus-actions] Defines a new 'base-window-willing-to-quit' stop-with-accumulator signal
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Defines a new 'base-window-willing-to-quit' stop-with-accumulator signal
- Date: Sat, 19 Feb 2011 14:35:50 +0000 (UTC)
commit e6452a1b4a4ca308908b095daffd9e189a5d4005
Author: Pierre Wieser <pwieser trychlos org>
Date: Thu Feb 17 20:01:26 2011 +0100
Defines a new 'base-window-willing-to-quit' stop-with-accumulator signal
As other BaseWindow signals, the default object handler converts the signal to a virtual method.
See also base-window.c for a comment about G_SIGNAL_RUN_LAST vs. G_SIGNAL_RUN_CLEANUP behaviors.
ChangeLog | 9 ++
src/nact/base-window.c | 106 +++++++++++++++++++++++++-
src/nact/base-window.h | 3 +-
src/nact/nact-main-window.c | 33 +++++----
src/nact/nact-marshal.def | 3 +
src/nact/nact-menubar-maintainer.c | 10 +++
src/nact/nact-menubar-priv.h | 1 +
src/nact/nact-menubar.c | 3 +
src/nact/nautilus-actions-maintainer.actions | 2 +
9 files changed, 152 insertions(+), 18 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d0043d8..266da91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-02-17 Pierre Wieser <pwieser trychlos org>
+
+ * src/nact/base-window.h:
+ * src/nact/base-window.c (class_init):
+ Defines a new 'base-window-willing-to-quit' stop-with-accumulator signal.
+
+ * src/nact/nact-main-window.c:
+ Connect to the signal instead of implementing a virtual method.
+
2011-02-16 Pierre Wieser <pwieser trychlos org>
* src/core/na-iduplicable.c (interface_base_init):
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index f40ae34..3457e3a 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -39,6 +39,7 @@
#include "base-application.h"
#include "base-window.h"
#include "base-gtk-utils.h"
+#include "nact-marshal.h"
/* private class data
*/
@@ -97,6 +98,7 @@ enum {
INITIALIZE_GTK,
INITIALIZE_BASE,
ALL_WIDGETS_SHOWED,
+ WILLING_TO_QUIT,
LAST_SIGNAL
};
@@ -131,8 +133,10 @@ static void on_all_widgets_showed_class_handler( BaseWindow *window );
static gboolean do_run( BaseWindow *window, GtkWindow *toplevel );
static gboolean is_main_window( BaseWindow *window );
static gboolean on_delete_event( GtkWidget *widget, GdkEvent *event, BaseWindow *window );
+static gboolean on_is_willing_to_quit_class_handler( BaseWindow *window );
static void record_connected_signal( BaseWindow *window, GObject *instance, gulong handler_id );
+static gboolean signal_accumulator_false_handled( GSignalInvocationHint *hint, GValue *return_accu, const GValue *handler_return, gpointer dummy);
static gint display_dlg( const BaseWindow *parent, GtkMessageType type_message, GtkButtonsType type_buttons, const gchar *primary, const gchar *secondary );
GType
@@ -304,6 +308,45 @@ class_init( BaseWindowClass *klass )
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0 );
+
+ /**
+ * BaseWindow::base-window-willing-to-quit:
+ *
+ * The signal is emitted when the application is about to terminate,
+ * to determine if all BaseWindow-derived windows are actually willing
+ * to quit.
+ *
+ * If the window is not willing to quit, then the user handler should
+ * return %FALSE to stop the signal emission.
+ *
+ * Returning %TRUE will let the signal be emitted to other connected
+ * handlers, eventually authorizing the application to terminate.
+ *
+ * Notes about GLib signals.
+ *
+ * If the signal is defined as G_SIGNAL_RUN_CLEANUP, then the object
+ * handler does not participate to the return value of the signal
+ * (accumulator is not called). More this object handler is triggered
+ * unconditionnally, event if a user handler has returned %FALSE to
+ * stop the emission.
+ *
+ * Contrarily, if the signal is defined as G_SIGNAL_RUN_LAST, then the
+ * object handler returned value is taken into account by the accumulator,
+ * and can participate to the return value for the signal. If a user
+ * handler returns FALSE to stop the emission, then the object handler
+ * will not be triggered.
+ */
+ st_signals[ WILLING_TO_QUIT ] =
+ g_signal_new_class_handler(
+ BASE_SIGNAL_WILLING_TO_QUIT,
+ G_TYPE_FROM_CLASS( klass ),
+ G_SIGNAL_RUN_LAST,
+ G_CALLBACK( on_is_willing_to_quit_class_handler ),
+ ( GSignalAccumulator ) signal_accumulator_false_handled,
+ NULL,
+ nact_cclosure_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN,
+ 0 );
}
static void
@@ -879,7 +922,7 @@ is_main_window( BaseWindow *window )
}
/*
- * Handler of "delete-event" message connected on the main window Gtk toplevel
+ * Handler of BASE_SIGNAL_WILLING_TO_QUIT signal
*
* Our own function does nothing, and let the signal be propagated
* it so ends up in the default class handler for this signal
@@ -1043,6 +1086,45 @@ base_window_get_widget( const BaseWindow *window, const gchar *name )
gboolean
base_window_is_willing_to_quit( const BaseWindow *window )
{
+ static const gchar *thisfn = "base_window_is_willing_to_quit";
+ gboolean willing_to_quit;
+ GValue instance_params = {0};
+ GValue return_value = {0};
+
+ willing_to_quit = TRUE;
+
+ g_return_val_if_fail( BASE_IS_WINDOW( window ), TRUE );
+
+ if( !window->private->dispose_has_run ){
+ g_debug( "%s: window=%p", thisfn, ( void * ) window );
+
+ g_value_init( &instance_params, G_TYPE_FROM_INSTANCE( window ));
+ g_value_set_instance( &instance_params, ( gpointer ) window );
+
+ g_value_init( &return_value, G_TYPE_BOOLEAN );
+ g_value_set_boolean( &return_value, TRUE );
+
+ g_signal_emitv( &instance_params, st_signals[WILLING_TO_QUIT], 0, &return_value );
+
+ willing_to_quit = g_value_get_boolean( &return_value );
+ }
+
+ return( willing_to_quit );
+}
+
+/*
+ * Handler of BASE_SIGNAL_WILLING_TO_QUIT message connected on the main window Gtk toplevel
+ *
+ * As other BaseWindow signals, the default object handler converts the
+ * signal to a virtual method.
+ *
+ * Main window should handle this signal in order to trap application termination,
+ * returning %FALSE if it is not willing to quit.
+ */
+static gboolean
+on_is_willing_to_quit_class_handler( BaseWindow *window )
+{
+ static const gchar *thisfn = "base_window_on_is_willing_to_quit_class_handler";
gboolean willing_to;
willing_to = TRUE;
@@ -1050,15 +1132,35 @@ base_window_is_willing_to_quit( const BaseWindow *window )
g_return_val_if_fail( BASE_IS_WINDOW( window ), TRUE );
if( !window->private->dispose_has_run ){
+ g_debug( "%s: window=%p", thisfn, ( void * ) window );
if( BASE_WINDOW_GET_CLASS( window )->is_willing_to_quit ){
- BASE_WINDOW_GET_CLASS( window )->is_willing_to_quit( window );
+ willing_to = BASE_WINDOW_GET_CLASS( window )->is_willing_to_quit( window );
}
}
return( willing_to );
}
+/*
+ * the first handler which returns FALSE stops the emission
+ * this is used on BASE_SIGNAL_WILLING_TO_QUIT signal
+ */
+static gboolean
+signal_accumulator_false_handled( GSignalInvocationHint *hint, GValue *return_accu, const GValue *handler_return, gpointer dummy)
+{
+ static const gchar *thisfn = "base_window_signal_accumulator_false_handled";
+ gboolean continue_emission;
+ gboolean willing_to_quit;
+
+ willing_to_quit = g_value_get_boolean( handler_return );
+ g_value_set_boolean( return_accu, willing_to_quit );
+ continue_emission = willing_to_quit;
+
+ g_debug( "%s: willing_to handler returns %s", thisfn, willing_to_quit ? "True":"False" );
+ return( continue_emission );
+}
+
/**
* base_window_display_error_dlg:
* @parent: the #BaseWindow parent, may be %NULL.
diff --git a/src/nact/base-window.h b/src/nact/base-window.h
index 0de35f4..7384399 100644
--- a/src/nact/base-window.h
+++ b/src/nact/base-window.h
@@ -203,7 +203,7 @@ typedef struct {
/**
* Signals defined by the BaseWindow class.
*
- * All signals of this class have the same behavior:
+ * All signals of this class share the same behavior:
*
* - the message is sent to all derived classes, which are free to
* connect to the signal in order to implement their own code;
@@ -219,6 +219,7 @@ typedef struct {
#define BASE_SIGNAL_INITIALIZE_GTK "base-window-initialize-gtk"
#define BASE_SIGNAL_INITIALIZE_WINDOW "base-window-initialize-window"
#define BASE_SIGNAL_ALL_WIDGETS_SHOWED "base-window-all-widgets-showed"
+#define BASE_SIGNAL_WILLING_TO_QUIT "base-window-willing-to-quit"
GType base_window_get_type( void );
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 52077db..70770c1 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -201,7 +201,7 @@ static gboolean confirm_for_giveup_from_menu( const NactMainWindow *window );
static void load_or_reload_items( NactMainWindow *window );
/* application termination */
-static gboolean base_is_willing_to_quit( const BaseWindow *window );
+static gboolean on_base_is_willing_to_quit( const BaseWindow *window, gconstpointer user_data );
static gboolean on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window );
static gboolean warn_modified( NactMainWindow *window );
@@ -340,7 +340,6 @@ class_init( NactMainWindowClass *klass )
{
static const gchar *thisfn = "nact_main_window_class_init";
GObjectClass *object_class;
- BaseWindowClass *base_class;
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
@@ -390,9 +389,6 @@ class_init( NactMainWindowClass *klass )
klass->private = g_new0( NactMainWindowClassPrivate, 1 );
- base_class = BASE_WINDOW_CLASS( klass );
- base_class->is_willing_to_quit = base_is_willing_to_quit;
-
/**
* NactMainWindow::main-item-updated:
*
@@ -881,6 +877,11 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
base_window_signal_connect( BASE_WINDOW( window ),
G_OBJECT( base_window_get_gtk_toplevel( BASE_WINDOW( window ))),
"delete-event", G_CALLBACK( on_delete_event ));
+
+ /* is willing to quit ?
+ */
+ base_window_signal_connect( BASE_WINDOW( window ),
+ G_OBJECT( window ), BASE_SIGNAL_WILLING_TO_QUIT, G_CALLBACK( on_base_is_willing_to_quit ));
}
}
@@ -1326,24 +1327,26 @@ nact_main_window_quit( NactMainWindow *window )
return( terminated );
}
+/*
+ * signal handler
+ * should return %FALSE if it is not willing to quit
+ * this will also stop the emission of the signal (i.e. the first FALSE wins)
+ */
static gboolean
-base_is_willing_to_quit( const BaseWindow *window )
+on_base_is_willing_to_quit( const BaseWindow *window, gconstpointer user_data )
{
- static const gchar *thisfn = "nact_main_window_is_willing_to_quit";
+ static const gchar *thisfn = "nact_main_window_on_base_is_willing_to_quit";
gboolean willing_to;
- g_debug( "%s: window=%p", thisfn, ( void * ) window );
+ g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), TRUE );
willing_to = TRUE;
- if( NACT_MAIN_WINDOW( window )->private->is_tree_modified ){
- willing_to = nact_confirm_logout_run( NACT_MAIN_WINDOW( window ));
- }
+ if( !NACT_MAIN_WINDOW( window )->private->dispose_has_run ){
+ g_debug( "%s (virtual): window=%p", thisfn, ( void * ) window );
- /* call parent class */
- if( willing_to ){
- if( BASE_WINDOW_CLASS( st_parent_class )->is_willing_to_quit ){
- willing_to = BASE_WINDOW_CLASS( st_parent_class )->is_willing_to_quit( window );
+ if( NACT_MAIN_WINDOW( window )->private->is_tree_modified ){
+ willing_to = nact_confirm_logout_run( NACT_MAIN_WINDOW( window ));
}
}
diff --git a/src/nact/nact-marshal.def b/src/nact/nact-marshal.def
index 4623a90..c88f1dd 100644
--- a/src/nact/nact-marshal.def
+++ b/src/nact/nact-marshal.def
@@ -1,3 +1,6 @@
+# BaseWindow:: BASE_SIGNAL_WILLING_TO_QUIT
+BOOLEAN:VOID
+#
# NactTreeView:: TREE_SIGNAL_COUNT_CHANGED
VOID:BOOLEAN,INT,INT,INT
#
diff --git a/src/nact/nact-menubar-maintainer.c b/src/nact/nact-menubar-maintainer.c
index 4b226b7..75dc15f 100644
--- a/src/nact/nact-menubar-maintainer.c
+++ b/src/nact/nact-menubar-maintainer.c
@@ -116,3 +116,13 @@ nact_menubar_maintainer_on_dump_clipboard( GtkAction *action, BaseWindow *window
{
nact_clipboard_dump( nact_main_window_get_clipboard( NACT_MAIN_WINDOW( window )));
}
+
+/*
+ * Test a miscellaneous function
+ */
+void
+nact_menubar_maintainer_on_test_function( GtkAction *action, BaseWindow *window )
+{
+ gboolean is_willing = base_window_is_willing_to_quit( BASE_WINDOW( window ));
+ g_debug( "nact_menubar_maintainer_on_test_function: willing_to=%s", is_willing ? "True":"False" );
+}
diff --git a/src/nact/nact-menubar-priv.h b/src/nact/nact-menubar-priv.h
index 64c98c2..e49d021 100644
--- a/src/nact/nact-menubar-priv.h
+++ b/src/nact/nact-menubar-priv.h
@@ -158,6 +158,7 @@ void nact_menubar_maintainer_on_dump_selection ( GtkAction *action, BaseWi
void nact_menubar_maintainer_on_brief_tree_store_dump( GtkAction *action, BaseWindow *window );
void nact_menubar_maintainer_on_list_modified_items ( GtkAction *action, BaseWindow *window );
void nact_menubar_maintainer_on_dump_clipboard ( GtkAction *action, BaseWindow *window );
+void nact_menubar_maintainer_on_test_function ( GtkAction *action, BaseWindow *window );
void nact_menubar_tools_on_update_sensitivities( const NactMenubar *bar );
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index bf5c92b..59dd682 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -150,6 +150,9 @@ static const GtkActionEntry entries[] = {
/* i18n: tooltip displayed in the status bar when selecting the DumpClipboard item */
N_( "Dump the content of the clipboard object" ),
G_CALLBACK( nact_menubar_maintainer_on_dump_clipboard ) },
+ { "FunctionTest", NULL, "_Test a function", NULL,
+ "Test a function (see nact-menubar-maintainer.c",
+ G_CALLBACK( nact_menubar_maintainer_on_test_function ) },
{ "HelpItem" , GTK_STOCK_HELP, N_( "Contents" ), "F1",
/* i18n: tooltip displayed in the status bar when selecting the Help item */
diff --git a/src/nact/nautilus-actions-maintainer.actions b/src/nact/nautilus-actions-maintainer.actions
index 9dca50e..98a1a65 100644
--- a/src/nact/nautilus-actions-maintainer.actions
+++ b/src/nact/nautilus-actions-maintainer.actions
@@ -7,6 +7,7 @@
<menuitem action="BriefTreeStoreDumpItem" />
<menuitem action="ListModifiedItems" />
<menuitem action="DumpClipboard" />
+ <menuitem action="FunctionTest" />
</menu>
</placeholder>
</menubar>
@@ -16,5 +17,6 @@
<toolitem action="BriefTreeStoreDumpItem" />
<toolitem action="ListModifiedItems" />
<toolitem action="DumpClipboard" />
+ <toolitem action="FunctionTest" />
</toolbar>
</ui>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]