3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
9 * This Program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This Program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this Library; see the file COPYING. If not,
21 * write to the Free Software Foundation, Inc., 59 Temple Place,
22 * Suite 330, Boston, MA 02111-1307, USA.
25 * Frederic Ruaudel <grumz@grumz.net>
26 * Rodrigo Moya <rodrigo@gnome-db.org>
27 * Pierre Wieser <pwieser@trychlos.org>
28 * ... and many others (see AUTHORS)
36 #include <glib/gi18n.h>
40 #include "base-application.h"
41 #include "base-iprefs.h"
42 #include "base-window.h"
43 #include "nact-gtk-utils.h"
47 struct _BaseWindowClassPrivate
{
48 void *empty
; /* so that gcc -pedantic is happy */
51 /* private instance data
53 struct _BaseWindowPrivate
{
54 gboolean dispose_has_run
;
59 BaseApplication
*application
;
60 gchar
*xmlui_filename
;
61 gboolean has_own_builder
;
66 GtkWindow
*gtk_toplevel
;
70 gboolean save_window_position
;
74 /* connected signal, to be disconnected at NactWindow dispose
80 BaseWindowRecordedSignal
;
82 /* instance properties
88 BASE_PROP_APPLICATION_ID
,
89 BASE_PROP_XMLUI_FILENAME_ID
,
90 BASE_PROP_HAS_OWN_BUILDER_ID
,
91 BASE_PROP_TOPLEVEL_NAME_ID
,
93 BASE_PROP_N_PROPERTIES
96 /* signals defined in BaseWindow, to be used in all derived classes
105 static GObjectClass
*st_parent_class
= NULL
;
106 static gint st_signals
[ LAST_SIGNAL
] = { 0 };
107 static gboolean st_debug_signal_connect
= FALSE
;
108 static BaseWindow
*st_first_window
= NULL
;
110 static GType
register_type( void );
111 static void class_init( BaseWindowClass
*klass
);
112 static void iprefs_base_iface_init( BaseIPrefsInterface
*iface
);
113 static void instance_init( GTypeInstance
*instance
, gpointer klass
);
114 static void instance_get_property( GObject
*object
, guint property_id
, GValue
*value
, GParamSpec
*spec
);
115 static void instance_set_property( GObject
*object
, guint property_id
, const GValue
*value
, GParamSpec
*spec
);
116 static void instance_dispose( GObject
*application
);
117 static void instance_finalize( GObject
*application
);
119 static gboolean
setup_builder( const BaseWindow
*window
);
120 static gboolean
load_gtk_toplevel( const BaseWindow
*window
);
121 static gboolean
is_gtk_toplevel_initialized( const BaseWindow
*window
, GtkWindow
*gtk_toplevel
);
122 static void set_gtk_toplevel_initialized( const BaseWindow
*window
, GtkWindow
*gtk_toplevel
, gboolean init
);
124 static gboolean
on_delete_event( GtkWidget
*widget
, GdkEvent
*event
, BaseWindow
*window
);
126 static void on_initialize_gtk_toplevel_class_handler( BaseWindow
*window
, gpointer user_data
);
127 static void do_initialize_gtk_toplevel( BaseWindow
*window
, gpointer user_data
);
128 static void on_initialize_base_window_class_handler( BaseWindow
*window
, gpointer user_data
);
129 static void do_initialize_base_window( BaseWindow
*window
, gpointer user_data
);
130 static void on_all_widgets_showed_class_handler( BaseWindow
*window
, gpointer user_data
);
132 static gboolean
v_dialog_response( GtkDialog
*dialog
, gint code
, BaseWindow
*window
);
133 static gchar
*v_get_toplevel_name( const BaseWindow
*window
);
134 static gchar
*v_get_iprefs_window_id( const BaseWindow
*window
);
136 static gboolean
window_do_dialog_response( GtkDialog
*dialog
, gint code
, BaseWindow
*window
);
137 static gboolean
window_do_delete_event( BaseWindow
*window
, GtkWindow
*toplevel
, GdkEvent
*event
);
138 static gboolean
window_do_is_willing_to_quit( const BaseWindow
*window
);
140 static gboolean
is_main_window( BaseWindow
*window
);
142 static void record_connected_signal( BaseWindow
*window
, GObject
*instance
, gulong handler_id
);
143 static gint
display_dlg( const BaseWindow
*parent
, GtkMessageType type_message
, GtkButtonsType type_buttons
, const gchar
*primary
, const gchar
*secondary
);
146 base_window_get_type( void )
148 static GType window_type
= 0;
151 window_type
= register_type();
154 return( window_type
);
158 register_type( void )
160 static const gchar
*thisfn
= "base_window_register_type";
163 static GTypeInfo info
= {
164 sizeof( BaseWindowClass
),
165 ( GBaseInitFunc
) NULL
,
166 ( GBaseFinalizeFunc
) NULL
,
167 ( GClassInitFunc
) class_init
,
170 sizeof( BaseWindow
),
172 ( GInstanceInitFunc
) instance_init
175 static const GInterfaceInfo iprefs_base_iface_info
= {
176 ( GInterfaceInitFunc
) iprefs_base_iface_init
,
181 g_debug( "%s", thisfn
);
183 type
= g_type_register_static( G_TYPE_OBJECT
, "BaseWindow", &info
, 0 );
185 g_type_add_interface_static( type
, BASE_IPREFS_TYPE
, &iprefs_base_iface_info
);
191 class_init( BaseWindowClass
*klass
)
193 static const gchar
*thisfn
= "base_window_class_init";
194 GObjectClass
*object_class
;
196 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
198 st_parent_class
= g_type_class_peek_parent( klass
);
200 object_class
= G_OBJECT_CLASS( klass
);
201 object_class
->dispose
= instance_dispose
;
202 object_class
->finalize
= instance_finalize
;
203 object_class
->get_property
= instance_get_property
;
204 object_class
->set_property
= instance_set_property
;
206 g_object_class_install_property( object_class
, BASE_PROP_PARENT_ID
,
207 g_param_spec_pointer(
209 _( "Parent BaseWindow" ),
210 _( "A pointer (not a reference) to the BaseWindow parent of this BaseWindow" ),
211 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
213 g_object_class_install_property( object_class
, BASE_PROP_APPLICATION_ID
,
214 g_param_spec_pointer(
215 BASE_PROP_APPLICATION
,
216 _( "BaseApplication" ),
217 _( "A pointer (not a reference) to the BaseApplication instance" ),
218 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
220 g_object_class_install_property( object_class
, BASE_PROP_XMLUI_FILENAME_ID
,
222 BASE_PROP_XMLUI_FILENAME
,
223 _( "XML UI filename" ),
224 _( "The filename which contains the XML UI definition" ),
226 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
228 g_object_class_install_property( object_class
, BASE_PROP_HAS_OWN_BUILDER_ID
,
229 g_param_spec_boolean(
230 BASE_PROP_HAS_OWN_BUILDER
,
231 _( "Has its own GtkBuilder" ),
232 _( "Whether this BaseWindow reallocates a new GtkBuilder each time it is opened" ),
234 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
236 g_object_class_install_property( object_class
, BASE_PROP_TOPLEVEL_NAME_ID
,
238 BASE_PROP_TOPLEVEL_NAME
,
239 _( "Toplevel name" ),
240 _( "The internal GtkBuildable name of the toplevel window" ),
242 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
244 klass
->private = g_new0( BaseWindowClassPrivate
, 1 );
246 klass
->initial_load_toplevel
= do_initialize_gtk_toplevel
;
247 klass
->runtime_init_toplevel
= do_initialize_base_window
;
248 klass
->all_widgets_showed
= NULL
;
249 klass
->dialog_response
= window_do_dialog_response
;
250 klass
->delete_event
= window_do_delete_event
;
251 klass
->get_toplevel_name
= NULL
;
252 klass
->get_iprefs_window_id
= NULL
;
253 klass
->get_ui_filename
= NULL
;
254 klass
->is_willing_to_quit
= window_do_is_willing_to_quit
;
257 * base-window-initialize-gtk:
259 * The signal is emitted by the #BaseWindow instance when it has
260 * loaded for the first time the Gtk toplevel widget from the GtkBuilder.
262 st_signals
[ INITIALIZE_GTK
] =
263 g_signal_new_class_handler(
264 BASE_SIGNAL_INITIALIZE_GTK
,
265 G_TYPE_FROM_CLASS( klass
),
267 G_CALLBACK( on_initialize_gtk_toplevel_class_handler
),
270 g_cclosure_marshal_VOID__POINTER
,
276 * base-window-initialize-window:
278 * The signal is emitted by the #BaseWindow instance after the toplevel
279 * GtkWindow has been initialized, before actually displaying the window.
280 * Is is so time to initialize it with runtime values.
282 st_signals
[ INITIALIZE_BASE
] =
283 g_signal_new_class_handler(
284 BASE_SIGNAL_INITIALIZE_WINDOW
,
285 G_TYPE_FROM_CLASS( klass
),
287 G_CALLBACK( on_initialize_base_window_class_handler
),
290 g_cclosure_marshal_VOID__POINTER
,
296 * nact-signal-base-window-all-widgets-showed:
298 * The signal is emitted by the #BaseWindow instance when the
299 * toplevel widget has been initialized with its runtime values,
300 * just after showing it and all its descendants.
302 * It is typically used by notebooks, to select the first visible
305 st_signals
[ ALL_WIDGETS_SHOWED
] =
306 g_signal_new_class_handler(
307 BASE_SIGNAL_ALL_WIDGETS_SHOWED
,
308 G_TYPE_FROM_CLASS( klass
),
310 G_CALLBACK( on_all_widgets_showed_class_handler
),
313 g_cclosure_marshal_VOID__POINTER
,
320 iprefs_base_iface_init( BaseIPrefsInterface
*iface
)
322 static const gchar
*thisfn
= "base_window_iprefs_base_iface_init";
324 g_debug( "%s: iface=%p", thisfn
, ( void * ) iface
);
326 iface
->iprefs_get_window_id
= v_get_iprefs_window_id
;
330 instance_init( GTypeInstance
*instance
, gpointer klass
)
332 static const gchar
*thisfn
= "base_window_instance_init";
335 g_return_if_fail( BASE_IS_WINDOW( instance
));
337 g_debug( "%s: instance=%p (%s), klass=%p",
338 thisfn
, ( void * ) instance
, G_OBJECT_TYPE_NAME( instance
), ( void * ) klass
);
340 self
= BASE_WINDOW( instance
);
342 /* at a first glance, we may suppose that this first window is the main one
343 * if this is not the case, we have to write some more code
345 if( !st_first_window
){
346 st_first_window
= self
;
349 self
->private = g_new0( BaseWindowPrivate
, 1 );
351 self
->private->dispose_has_run
= FALSE
;
352 self
->private->signals
= NULL
;
353 self
->private->save_window_position
= TRUE
;
357 instance_get_property( GObject
*object
, guint property_id
, GValue
*value
, GParamSpec
*spec
)
361 g_return_if_fail( BASE_IS_WINDOW( object
));
362 self
= BASE_WINDOW( object
);
364 if( !self
->private->dispose_has_run
){
366 switch( property_id
){
367 case BASE_PROP_PARENT_ID
:
368 g_value_set_pointer( value
, self
->private->parent
);
371 case BASE_PROP_APPLICATION_ID
:
372 g_value_set_pointer( value
, self
->private->application
);
375 case BASE_PROP_XMLUI_FILENAME_ID
:
376 g_value_set_string( value
, self
->private->xmlui_filename
);
379 case BASE_PROP_HAS_OWN_BUILDER_ID
:
380 g_value_set_boolean( value
, self
->private->has_own_builder
);
383 case BASE_PROP_TOPLEVEL_NAME_ID
:
384 g_value_set_string( value
, self
->private->toplevel_name
);
388 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
395 instance_set_property( GObject
*object
, guint property_id
, const GValue
*value
, GParamSpec
*spec
)
399 g_return_if_fail( BASE_IS_WINDOW( object
));
400 self
= BASE_WINDOW( object
);
402 if( !self
->private->dispose_has_run
){
404 switch( property_id
){
405 case BASE_PROP_PARENT_ID
:
406 self
->private->parent
= g_value_get_pointer( value
);
409 case BASE_PROP_APPLICATION_ID
:
410 self
->private->application
= g_value_get_pointer( value
);
413 case BASE_PROP_XMLUI_FILENAME_ID
:
414 g_free( self
->private->xmlui_filename
);
415 self
->private->xmlui_filename
= g_value_dup_string( value
);
418 case BASE_PROP_HAS_OWN_BUILDER_ID
:
419 self
->private->has_own_builder
= g_value_get_boolean( value
);
422 case BASE_PROP_TOPLEVEL_NAME_ID
:
423 g_free( self
->private->toplevel_name
);
424 self
->private->toplevel_name
= g_value_dup_string( value
);
428 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
435 instance_dispose( GObject
*window
)
437 static const gchar
*thisfn
= "base_window_instance_dispose";
441 g_return_if_fail( BASE_IS_WINDOW( window
));
443 self
= BASE_WINDOW( window
);
445 if( !self
->private->dispose_has_run
){
447 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
449 if( self
->private->save_window_position
){
450 base_iprefs_save_window_position( self
);
453 /* signals must be deconnected before quitting main loop
455 for( is
= self
->private->signals
; is
; is
= is
->next
){
456 BaseWindowRecordedSignal
*str
= ( BaseWindowRecordedSignal
* ) is
->data
;
457 if( g_signal_handler_is_connected( str
->instance
, str
->handler_id
)){
458 g_signal_handler_disconnect( str
->instance
, str
->handler_id
);
459 if( st_debug_signal_connect
){
460 g_debug( "%s: disconnecting signal handler %p:%lu", thisfn
, str
->instance
, str
->handler_id
);
465 g_slist_free( self
->private->signals
);
467 if( is_main_window( BASE_WINDOW( window
))){
468 g_debug( "%s: quitting main window", thisfn
);
470 gtk_widget_destroy( GTK_WIDGET( self
->private->gtk_toplevel
));
472 } else if( GTK_IS_ASSISTANT( self
->private->gtk_toplevel
)){
473 g_debug( "%s: quitting assistant", thisfn
);
475 if( is_gtk_toplevel_initialized( self
, self
->private->gtk_toplevel
)){
476 gtk_widget_hide( GTK_WIDGET( self
->private->gtk_toplevel
));
480 g_debug( "%s: quitting dialog", thisfn
);
481 if( is_gtk_toplevel_initialized( self
, self
->private->gtk_toplevel
)){
482 gtk_widget_hide( GTK_WIDGET( self
->private->gtk_toplevel
));
486 /* must dispose _after_ quitting the loop
488 self
->private->dispose_has_run
= TRUE
;
490 /* release the Gtkbuilder, if any
492 if( self
->private->has_own_builder
){
493 if( self
->private->builder
){
494 g_object_unref( self
->private->builder
);
498 /* chain up to the parent class */
499 if( G_OBJECT_CLASS( st_parent_class
)->dispose
){
500 G_OBJECT_CLASS( st_parent_class
)->dispose( window
);
506 instance_finalize( GObject
*window
)
508 static const gchar
*thisfn
= "base_window_instance_finalize";
511 g_return_if_fail( BASE_IS_WINDOW( window
));
513 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
515 self
= BASE_WINDOW( window
);
517 g_free( self
->private->toplevel_name
);
518 g_free( self
->private->xmlui_filename
);
520 g_free( self
->private );
522 /* chain call to parent class */
523 if( G_OBJECT_CLASS( st_parent_class
)->finalize
){
524 G_OBJECT_CLASS( st_parent_class
)->finalize( window
);
530 * @window: this #BaseWindow object.
532 * Initializes the window.
534 * This is a one-time initialization just after the BaseWindow has been
535 * allocated. This should leave the BaseWindow object with a valid
536 * toplevel GtkWindow dialog. This is also time to make one-time
537 * initialization on this toplevel dialog.
539 * For an every-time initialization, see base_window_run().
541 * Note that the BaseWindow itself should be initialized each time
542 * the user opens the dialog, though the GtkWindow itself needs only
543 * be initialized the first time it is loaded.
545 * Returns: %TRUE if the window has been successfully initialized,
549 base_window_init( BaseWindow
*window
)
551 static const gchar
*thisfn
= "base_window_init";
553 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
555 if( !window
->private->dispose_has_run
&&
556 !window
->private->initialized
){
558 g_debug( "%s: window=%p", thisfn
, ( void * ) window
);
560 if( !window
->private->application
){
561 g_return_val_if_fail( window
->private->parent
, FALSE
);
562 g_return_val_if_fail( BASE_IS_WINDOW( window
->private->parent
), FALSE
);
563 window
->private->application
= BASE_APPLICATION( base_window_get_application( window
->private->parent
));
564 g_debug( "%s: application=%p", thisfn
, ( void * ) window
->private->application
);
567 g_return_val_if_fail( window
->private->application
, FALSE
);
568 g_return_val_if_fail( BASE_IS_APPLICATION( window
->private->application
), FALSE
);
570 if( setup_builder( window
) &
571 load_gtk_toplevel( window
)){
573 if( window
->private->gtk_toplevel
){
574 g_return_val_if_fail( GTK_IS_WINDOW( window
->private->gtk_toplevel
), FALSE
);
576 if( !is_gtk_toplevel_initialized( window
, window
->private->gtk_toplevel
)){
577 g_signal_emit_by_name( window
, BASE_SIGNAL_INITIALIZE_GTK
, NULL
);
578 set_gtk_toplevel_initialized( window
, window
->private->gtk_toplevel
, TRUE
);
581 window
->private->initialized
= TRUE
;
586 return( window
->private->initialized
);
590 * setup the builder of the window as a new one, or use the global one
592 * A dialog may have its own builder ,sharing the common UI XML definition file
593 * or a dialog may have its own UI XML definition file, sharing the common builder
594 * or a dialog may have both its UI XML definition file with its own builder
597 setup_builder( const BaseWindow
*window
)
599 static const gchar
*thisfn
= "base_window_setup_builder";
601 GError
*error
= NULL
;
604 /* allocate a dedicated BaseBuilder or use the common one
606 if( window
->private->has_own_builder
){
607 window
->private->builder
= base_builder_new();
609 g_return_val_if_fail( BASE_IS_APPLICATION( window
->private->application
), FALSE
);
610 window
->private->builder
= base_application_get_builder( window
->private->application
);
613 /* use the xml ui filename provided as a construction property
614 * or ask the window for it
616 if(( !window
->private->xmlui_filename
|| !g_utf8_strlen( window
->private->xmlui_filename
, -1 )) &&
617 BASE_WINDOW_GET_CLASS( window
)->get_ui_filename
){
619 g_free( window
->private->xmlui_filename
);
620 window
->private->xmlui_filename
= BASE_WINDOW_GET_CLASS( window
)->get_ui_filename( window
);
623 /* load the XML definition from the UI file
626 if( window
->private->xmlui_filename
&& g_utf8_strlen( window
->private->xmlui_filename
, -1 )){
627 if( base_builder_add_from_file( window
->private->builder
, window
->private->xmlui_filename
, &error
)){
630 msg
= g_strdup_printf( _( "Unable to load %s UI XML definition: %s" ), window
->private->xmlui_filename
, error
->message
);
631 base_window_display_error_dlg( NULL
, thisfn
, msg
);
633 g_error_free( error
);
641 load_gtk_toplevel( const BaseWindow
*window
)
643 gchar
*toplevel_name
;
644 GtkWindow
*gtk_toplevel
;
647 /* we should only test for the construction property toplevel_name
648 * during the transition, also asks the derived class
650 toplevel_name
= v_get_toplevel_name( window
);
654 if( strlen( toplevel_name
)){
655 g_return_val_if_fail( BASE_IS_BUILDER( window
->private->builder
), FALSE
);
656 gtk_toplevel
= base_builder_get_toplevel_by_name( window
->private->builder
, toplevel_name
);
659 msg
= g_strdup_printf( _( "Unable to load %s dialog definition." ), toplevel_name
);
660 base_window_display_error_dlg( NULL
, msg
, NULL
);
666 g_free( toplevel_name
);
667 window
->private->gtk_toplevel
= gtk_toplevel
;
669 return( gtk_toplevel
!= NULL
);
673 is_gtk_toplevel_initialized( const BaseWindow
*window
, GtkWindow
*gtk_toplevel
)
675 gboolean initialized
;
677 initialized
= GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( gtk_toplevel
), "base-window-gtk-toplevel-initialized" ));
679 return( initialized
);
683 set_gtk_toplevel_initialized( const BaseWindow
*window
, GtkWindow
*gtk_toplevel
, gboolean initialized
)
685 g_object_set_data( G_OBJECT( gtk_toplevel
), "base-window-gtk-toplevel-initialized", GUINT_TO_POINTER( initialized
));
690 * @window: this #BaseWindow object.
694 * Returns: the exit code of the program is this is the main window.
697 base_window_run( BaseWindow
*window
)
699 static const gchar
*thisfn
= "base_window_run";
703 g_return_val_if_fail( BASE_IS_WINDOW( window
), BASE_EXIT_CODE_START_FAIL
);
707 if( !window
->private->dispose_has_run
){
709 run_ok
= window
->private->initialized
;
711 if( !window
->private->initialized
){
712 run_ok
= base_window_init( window
);
716 g_return_val_if_fail( GTK_IS_WINDOW( window
->private->gtk_toplevel
), BASE_EXIT_CODE_START_FAIL
);
718 g_debug( "%s: window=%p", thisfn
, ( void * ) window
);
719 g_signal_emit_by_name( window
, BASE_SIGNAL_INITIALIZE_WINDOW
, NULL
);
721 gtk_widget_show_all( GTK_WIDGET( window
->private->gtk_toplevel
));
722 g_signal_emit_by_name( window
, BASE_SIGNAL_ALL_WIDGETS_SHOWED
, NULL
);
724 if( is_main_window( window
)){
725 if( GTK_IS_DIALOG( window
->private->gtk_toplevel
)){
726 g_signal_connect( G_OBJECT( window
->private->gtk_toplevel
), "response", G_CALLBACK( v_dialog_response
), window
);
728 g_signal_connect( G_OBJECT( window
->private->gtk_toplevel
), "delete-event", G_CALLBACK( on_delete_event
), window
);
731 g_debug( "%s: application=%p, starting gtk_main", thisfn
, ( void * ) window
->private->application
);
734 } else if( GTK_IS_ASSISTANT( window
->private->gtk_toplevel
)){
735 g_debug( "%s: starting gtk_main", thisfn
);
739 g_assert( GTK_IS_DIALOG( window
->private->gtk_toplevel
));
740 g_debug( "%s: starting gtk_dialog_run", thisfn
);
742 code
= gtk_dialog_run( GTK_DIALOG( window
->private->gtk_toplevel
));
744 while( !v_dialog_response( GTK_DIALOG( window
->private->gtk_toplevel
), code
, window
));
749 return( run_ok
? BASE_EXIT_CODE_OK
: BASE_EXIT_CODE_MAIN_WINDOW
);
753 * base_window_get_application:
754 * @window: this #BaseWindow object.
756 * Returns: a pointer on the #BaseApplication object.
758 * The returned pointer is owned by the primary allocator of the
759 * application ; it should not be g_free() nor g_object_unref() by the
763 base_window_get_application( const BaseWindow
*window
)
765 BaseApplication
*application
= NULL
;
767 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
769 if( !window
->private->dispose_has_run
){
771 application
= window
->private->application
;
774 return( application
);
778 * base_window_get_parent:
779 * @window: this #BaseWindow instance..
781 * Returns the #BaseWindow parent of @window.
783 * The returned object is owned by @window, and should not be freed.
786 base_window_get_parent( const BaseWindow
*window
)
788 BaseWindow
*parent
= NULL
;
790 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
792 if( !window
->private->dispose_has_run
){
794 parent
= window
->private->parent
;
801 * base_window_get_gtk_toplevel:
802 * @window: this #BaseWindow instance..
804 * Returns the top-level GtkWindow attached to this BaseWindow object.
806 * The caller may close the window by g_object_unref()-ing the returned
810 base_window_get_gtk_toplevel( const BaseWindow
*window
)
812 GtkWindow
*gtk_toplevel
= NULL
;
814 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
816 if( !window
->private->dispose_has_run
){
818 gtk_toplevel
= window
->private->gtk_toplevel
;
821 return( gtk_toplevel
);
825 * base_window_get_gtk_toplevel_by_name:
826 * @window: this #BaseWindow instance.
827 * @name: the name of the searched GtkWindow.
829 * Returns: the named top-level GtkWindow.
831 * This is just a convenience function to be able to open quickly a
832 * window (e.g. Legend dialog).
834 * The caller may close the window by g_object_unref()-ing the returned
838 base_window_get_gtk_toplevel_by_name( const BaseWindow
*window
, const gchar
*name
)
840 GtkWindow
*gtk_toplevel
= NULL
;
842 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
844 if( !window
->private->dispose_has_run
){
846 gtk_toplevel
= base_builder_get_toplevel_by_name( window
->private->builder
, name
);
849 return( gtk_toplevel
);
853 * base_window_get_widget:
854 * @window: this #BaseWindow instance.
855 * @name: the name of the searched child.
857 * Returns a pointer to the named widget which is a child of the
858 * toplevel #GtkWindow associated with @window.
860 * Returns: a pointer to the searched widget, or NULL.
861 * This pointer is owned by GtkBuilder instance, and must not be
862 * g_free() nor g_object_unref() by the caller.
865 base_window_get_widget( const BaseWindow
*window
, const gchar
*name
)
867 GtkWidget
*widget
= NULL
;
869 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
871 if( !window
->private->dispose_has_run
){
873 widget
= nact_gtk_utils_get_widget_by_name( window
->private->gtk_toplevel
, name
);
880 * base_window_is_willing_to_quit:
881 * @window: this #BaseWindow instance.
883 * Returns: %TRUE if the application is willing to quit, %FALSE else.
885 * This function is called when the session manager detects the end of
886 * session and thus asks its client if they are willing to quit.
889 base_window_is_willing_to_quit( const BaseWindow
*window
)
896 g_return_val_if_fail( BASE_IS_WINDOW( window
), TRUE
);
898 if( !window
->private->dispose_has_run
){
900 for( class = G_OBJECT_GET_CLASS( window
) ; willing_to
&& BASE_IS_WINDOW_CLASS( class ) ; class = g_type_class_peek_parent( class )){
901 if( BASE_WINDOW_CLASS( class )->is_willing_to_quit
){
902 willing_to
= BASE_WINDOW_CLASS( class )->is_willing_to_quit( window
);
907 return( willing_to
);
911 * handler of "delete-event" message
912 * let a chance to derived class to handle it
913 * our own function does nothing, and let the signal be propagated.
916 on_delete_event( GtkWidget
*toplevel
, GdkEvent
*event
, BaseWindow
*window
)
918 static const gchar
*thisfn
= "base_window_on_delete_event";
919 static gboolean stop
= FALSE
;
921 g_debug( "%s: toplevel=%p, event=%p, window=%p",
922 thisfn
, ( void * ) toplevel
, ( void * ) event
, ( void * ) window
);
923 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
925 if( !window
->private->dispose_has_run
){
927 if( BASE_WINDOW_GET_CLASS( window
)->delete_event
){
928 stop
= BASE_WINDOW_GET_CLASS( window
)->delete_event( window
, GTK_WINDOW( toplevel
), event
);
931 stop
= window_do_delete_event( window
, GTK_WINDOW( toplevel
), event
);
939 * default class handler for "base-window-initialize-gtk" signal
941 * successively invokes the method of each derived class, starting from
942 * the topmost derived up to this BaseWindow
945 on_initialize_gtk_toplevel_class_handler( BaseWindow
*window
, gpointer user_data
)
947 static const gchar
*thisfn
= "base_window_on_initialize_gtk_toplevel_class_handler";
950 g_return_if_fail( BASE_IS_WINDOW( window
));
952 g_debug( "%s: window=%p, user_data=%p", thisfn
, ( void * ) window
, ( void * ) user_data
);
954 if( !window
->private->dispose_has_run
){
956 for( class = G_OBJECT_GET_CLASS( window
) ; BASE_IS_WINDOW_CLASS( class ) ; class = g_type_class_peek_parent( class )){
957 if( BASE_WINDOW_CLASS( class )->initial_load_toplevel
){
958 BASE_WINDOW_CLASS( class )->initial_load_toplevel( window
, user_data
);
965 do_initialize_gtk_toplevel( BaseWindow
*window
, gpointer user_data
)
967 static const gchar
*thisfn
= "base_window_do_initialize_gtk_toplevel";
968 GtkWindow
*parent_gtk_toplevel
;
970 g_return_if_fail( BASE_IS_WINDOW( window
));
972 g_debug( "%s: window=%p, user_data=%p", thisfn
, ( void * ) window
, ( void * ) user_data
);
974 if( !window
->private->dispose_has_run
){
976 g_debug( "%s: parent=%p (%s)", thisfn
,
977 ( void * ) window
->private->parent
,
978 window
->private->parent
? G_OBJECT_TYPE_NAME( window
->private->parent
) : "null" );
980 if( window
->private->parent
){
982 g_return_if_fail( BASE_IS_WINDOW( window
->private->parent
));
983 parent_gtk_toplevel
= base_window_get_gtk_toplevel( BASE_WINDOW( window
->private->parent
));
984 g_debug( "%s: toplevel=%p, parent_gtk_toplevel=%p", thisfn
, ( void * ) window
->private->gtk_toplevel
, ( void * ) parent_gtk_toplevel
);
985 gtk_window_set_transient_for( window
->private->gtk_toplevel
, parent_gtk_toplevel
);
991 * default class handler for "nact-signal-base-window-runtime-init" message
992 * -> does nothing here
995 on_initialize_base_window_class_handler( BaseWindow
*window
, gpointer user_data
)
997 static const gchar
*thisfn
= "base_window_on_initialize_base_window_class_handler";
1000 g_return_if_fail( BASE_IS_WINDOW( window
));
1002 g_debug( "%s: window=%p, user_data=%p", thisfn
, ( void * ) window
, ( void * ) user_data
);
1004 if( !window
->private->dispose_has_run
){
1006 for( class = G_OBJECT_GET_CLASS( window
) ; BASE_IS_WINDOW_CLASS( class ) ; class = g_type_class_peek_parent( class )){
1007 if( BASE_WINDOW_CLASS( class )->runtime_init_toplevel
){
1008 BASE_WINDOW_CLASS( class )->runtime_init_toplevel( window
, user_data
);
1015 do_initialize_base_window( BaseWindow
*window
, gpointer user_data
)
1017 static const gchar
*thisfn
= "base_window_do_initialize_base_window";
1019 g_return_if_fail( BASE_IS_WINDOW( window
));
1021 g_debug( "%s: window=%p, user_data=%p, parent_window=%p",
1022 thisfn
, ( void * ) window
, ( void * ) user_data
, ( void * ) window
->private->parent
);
1024 if( !window
->private->dispose_has_run
){
1026 base_iprefs_position_window( window
);
1031 on_all_widgets_showed_class_handler( BaseWindow
*window
, gpointer user_data
)
1033 static const gchar
*thisfn
= "base_window_on_all_widgets_showed_class_handler";
1034 GObjectClass
*class;
1036 g_return_if_fail( BASE_IS_WINDOW( window
));
1038 g_debug( "%s: window=%p, user_data=%p", thisfn
, ( void * ) window
, ( void * ) user_data
);
1040 if( !window
->private->dispose_has_run
){
1042 for( class = G_OBJECT_GET_CLASS( window
) ; BASE_IS_WINDOW_CLASS( class ) ; class = g_type_class_peek_parent( class )){
1043 if( BASE_WINDOW_CLASS( class )->all_widgets_showed
){
1044 BASE_WINDOW_CLASS( class )->all_widgets_showed( window
, user_data
);
1051 v_dialog_response( GtkDialog
*dialog
, gint code
, BaseWindow
*window
)
1053 static const gchar
*thisfn
= "base_window_v_dialog_response";
1054 gboolean stop
= FALSE
;
1056 g_debug( "%s: dialog=%p, code=%d, window=%p", thisfn
, ( void * ) dialog
, code
, ( void * ) window
);
1057 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
1059 if( !window
->private->dispose_has_run
){
1061 if( BASE_WINDOW_GET_CLASS( window
)->dialog_response
){
1062 stop
= BASE_WINDOW_GET_CLASS( window
)->dialog_response( dialog
, code
, window
);
1065 stop
= window_do_dialog_response( dialog
, code
, window
);
1073 v_get_toplevel_name( const BaseWindow
*window
)
1077 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
1079 g_object_get( G_OBJECT( window
), BASE_PROP_TOPLEVEL_NAME
, &name
, NULL
);
1081 if( !name
|| !strlen( name
)){
1082 if( BASE_WINDOW_GET_CLASS( window
)->get_toplevel_name
){
1083 name
= BASE_WINDOW_GET_CLASS( window
)->get_toplevel_name( window
);
1084 if( name
&& strlen( name
)){
1085 g_object_set( G_OBJECT( window
), BASE_PROP_TOPLEVEL_NAME
, name
, NULL
);
1094 v_get_iprefs_window_id( const BaseWindow
*window
)
1098 g_return_val_if_fail( BASE_IS_WINDOW( window
), NULL
);
1100 if( !window
->private->dispose_has_run
){
1102 if( BASE_WINDOW_GET_CLASS( window
)->get_iprefs_window_id
){
1103 id
= BASE_WINDOW_GET_CLASS( window
)->get_iprefs_window_id( window
);
1111 * return TRUE to quit the dialog loop
1114 window_do_dialog_response( GtkDialog
*dialog
, gint code
, BaseWindow
*window
)
1116 static const gchar
*thisfn
= "base_window_do_dialog_response";
1118 g_debug( "%s: dialog=%p, code=%d, window=%p", thisfn
, ( void * ) dialog
, code
, ( void * ) window
);
1119 g_return_val_if_fail( GTK_IS_DIALOG( dialog
), FALSE
);
1120 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
1126 * return TRUE to stop other handlers from being invoked for the event.
1127 * note that default handler will destroy this window
1130 window_do_delete_event( BaseWindow
*window
, GtkWindow
*toplevel
, GdkEvent
*event
)
1132 static const gchar
*thisfn
= "base_window_do_delete_event";
1134 g_debug( "%s: window=%p, toplevel=%p, event=%p",
1135 thisfn
, ( void * ) window
, ( void * ) toplevel
, ( void * ) event
);
1136 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
1137 g_return_val_if_fail( GTK_IS_WINDOW( toplevel
), FALSE
);
1143 window_do_is_willing_to_quit( const BaseWindow
*window
)
1145 static const gchar
*thisfn
= "base_window_do_is_willing_to_quit";
1147 g_debug( "%s: window=%p", thisfn
, ( void * ) window
);
1153 is_main_window( BaseWindow
*window
)
1155 gboolean is_main
= FALSE
;
1157 g_return_val_if_fail( BASE_IS_WINDOW( window
), FALSE
);
1159 if( !window
->private->dispose_has_run
){
1161 is_main
= ( window
== st_first_window
);
1168 * base_window_display_error_dlg:
1169 * @parent: the #BaseWindow parent, may be %NULL.
1170 * @primary: the primary message.
1171 * @secondary: the secondary message.
1173 * Display an error dialog box, with a 'OK' button only.
1175 * if @secondary is not null, then @primary is displayed as a bold title.
1178 base_window_display_error_dlg( const BaseWindow
*parent
, const gchar
*primary
, const gchar
*secondary
)
1180 display_dlg( parent
, GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
, primary
, secondary
);
1184 * base_window_display_yesno_dlg:
1185 * @parent: the #BaseWindow parent, may be %NULL.
1186 * @primary: the primary message.
1187 * @secondary: the secondary message.
1189 * Display a warning dialog box, with a 'OK' button only.
1191 * if @secondary is not null, then @primary is displayed as a bold title.
1193 * Returns: %TRUE if the user has clicked 'Yes', %FALSE else.
1196 base_window_display_yesno_dlg( const BaseWindow
*parent
, const gchar
*primary
, const gchar
*secondary
)
1200 result
= display_dlg( parent
, GTK_MESSAGE_QUESTION
, GTK_BUTTONS_YES_NO
, primary
, secondary
);
1202 return( result
== GTK_RESPONSE_YES
);
1206 * base_window_display_message_dlg:
1207 * @parent: the #BaseWindow parent, may be %NULL.
1208 * @message: the message to be displayed.
1210 * Displays an information dialog with only an OK button.
1213 base_window_display_message_dlg( const BaseWindow
*parent
, GSList
*msg
)
1218 string
= g_string_new( "" );
1219 for( im
= msg
; im
; im
= im
->next
){
1220 if( g_utf8_strlen( string
->str
, -1 )){
1221 string
= g_string_append( string
, "\n" );
1223 string
= g_string_append( string
, ( gchar
* ) im
->data
);
1225 display_dlg( parent
, GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
, string
->str
, NULL
);
1227 g_string_free( string
, TRUE
);
1231 display_dlg( const BaseWindow
*parent
, GtkMessageType type_message
, GtkButtonsType type_buttons
, const gchar
*primary
, const gchar
*secondary
)
1233 GtkWindow
*gtk_parent
;
1239 gtk_parent
= base_window_get_gtk_toplevel( parent
);
1242 dialog
= gtk_message_dialog_new( gtk_parent
, GTK_DIALOG_MODAL
, type_message
, type_buttons
, "%s", primary
);
1244 if( secondary
&& g_utf8_strlen( secondary
, -1 )){
1245 gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( dialog
), "%s", secondary
);
1248 g_object_set( G_OBJECT( dialog
) , "title", g_get_application_name(), NULL
);
1250 result
= gtk_dialog_run( GTK_DIALOG( dialog
));
1252 gtk_widget_destroy( dialog
);
1258 * Records a connected signal, to be disconnected at NactWindow dispose.
1261 base_window_signal_connect( BaseWindow
*window
, GObject
*instance
, const gchar
*signal
, GCallback fn
)
1263 gulong handler_id
= 0;
1265 g_return_val_if_fail( BASE_IS_WINDOW( window
), ( gulong
) 0 );
1267 if( !window
->private->dispose_has_run
){
1269 handler_id
= g_signal_connect( instance
, signal
, fn
, window
);
1270 record_connected_signal( window
, instance
, handler_id
);
1273 return( handler_id
);
1277 base_window_signal_connect_after( BaseWindow
*window
, GObject
*instance
, const gchar
*signal
, GCallback fn
)
1279 gulong handler_id
= 0;
1281 g_return_val_if_fail( BASE_IS_WINDOW( window
), ( gulong
) 0 );
1283 if( !window
->private->dispose_has_run
){
1285 handler_id
= g_signal_connect_after( instance
, signal
, fn
, window
);
1286 record_connected_signal( window
, instance
, handler_id
);
1289 return( handler_id
);
1293 base_window_signal_connect_by_name( BaseWindow
*window
, const gchar
*name
, const gchar
*signal
, GCallback fn
)
1295 gulong handler_id
= 0;
1297 g_return_val_if_fail( BASE_IS_WINDOW( window
), ( gulong
) 0 );
1299 if( !window
->private->dispose_has_run
){
1301 GtkWidget
*widget
= base_window_get_widget( window
, name
);
1302 if( GTK_IS_WIDGET( widget
)){
1304 handler_id
= base_window_signal_connect( window
, G_OBJECT( widget
), signal
, fn
);
1308 return( handler_id
);
1312 base_window_signal_connect_with_data( BaseWindow
*window
, GObject
*instance
, const gchar
*signal
, GCallback fn
, void *user_data
)
1314 gulong handler_id
= 0;
1316 g_return_val_if_fail( BASE_IS_WINDOW( window
), ( gulong
) 0 );
1318 if( !window
->private->dispose_has_run
){
1320 handler_id
= g_signal_connect( instance
, signal
, fn
, user_data
);
1321 record_connected_signal( window
, instance
, handler_id
);
1324 return( handler_id
);
1328 record_connected_signal( BaseWindow
*window
, GObject
*instance
, gulong handler_id
)
1330 static const gchar
*thisfn
= "base_window_record_connected_signal";
1332 BaseWindowRecordedSignal
*str
= g_new0( BaseWindowRecordedSignal
, 1 );
1333 str
->instance
= instance
;
1334 str
->handler_id
= handler_id
;
1335 window
->private->signals
= g_slist_prepend( window
->private->signals
, str
);
1337 if( st_debug_signal_connect
){
1338 g_debug( "%s: connecting signal handler %p:%lu", thisfn
, ( void * ) instance
, handler_id
);