3 * A file-manager extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2015 Pierre Wieser and others (see AUTHORS)
9 * FileManager-Actions 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 * FileManager-Actions 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 GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with FileManager-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
24 * Frederic Ruaudel <grumz@grumz.net>
25 * Rodrigo Moya <rodrigo@gnome-db.org>
26 * Pierre Wieser <pwieser@trychlos.org>
27 * ... and many others (see AUTHORS)
35 #include <glib/gi18n.h>
37 #include "base-assistant.h"
38 #include "base-keysyms.h"
39 #include "fma-application.h"
41 /* private instance data
43 struct _BaseAssistantPrivate
{
44 gboolean dispose_has_run
;
48 gboolean quit_on_escape
;
49 gboolean warn_on_escape
;
53 gboolean escape_key_pressed
;
56 /* instance properties
61 BASE_PROP_QUIT_ON_ESCAPE_ID
,
62 BASE_PROP_WARN_ON_ESCAPE_ID
,
64 BASE_PROP_N_PROPERTIES
67 static BaseWindowClass
*st_parent_class
= NULL
;
69 static GType
register_type( void );
70 static void class_init( BaseAssistantClass
*klass
);
71 static void instance_init( GTypeInstance
*instance
, gpointer klass
);
72 static void instance_get_property( GObject
*object
, guint property_id
, GValue
*value
, GParamSpec
*spec
);
73 static void instance_set_property( GObject
*object
, guint property_id
, const GValue
*value
, GParamSpec
*spec
);
74 static void instance_constructed( GObject
*window
);
75 static void instance_dispose( GObject
*window
);
76 static void instance_finalize( GObject
*window
);
78 static void on_initialize_base_window( BaseAssistant
*window
);
79 static int do_run( BaseWindow
*window
);
80 static gboolean
on_key_pressed_event( GtkWidget
*widget
, GdkEventKey
*event
, BaseAssistant
*assistant
);
81 static void on_apply( GtkAssistant
*assistant
, BaseAssistant
*window
);
82 static void on_prepare( GtkAssistant
*assistant
, GtkWidget
*page
, BaseAssistant
*window
);
83 static void on_cancel( GtkAssistant
*assistant
, BaseAssistant
*window
);
84 static void on_close( GtkAssistant
*assistant
, BaseAssistant
*window
);
85 static void do_close( BaseAssistant
*window
, GtkAssistant
*assistant
);
88 base_assistant_get_type( void )
90 static GType window_type
= 0;
93 window_type
= register_type();
96 return( window_type
);
100 register_type( void )
102 static const gchar
*thisfn
= "base_assistant_register_type";
105 static GTypeInfo info
= {
106 sizeof( BaseAssistantClass
),
107 ( GBaseInitFunc
) NULL
,
108 ( GBaseFinalizeFunc
) NULL
,
109 ( GClassInitFunc
) class_init
,
112 sizeof( BaseAssistant
),
114 ( GInstanceInitFunc
) instance_init
117 g_debug( "%s", thisfn
);
119 type
= g_type_register_static( BASE_TYPE_WINDOW
, "BaseAssistant", &info
, 0 );
125 class_init( BaseAssistantClass
*klass
)
127 static const gchar
*thisfn
= "base_assistant_class_init";
128 GObjectClass
*object_class
;
129 BaseWindowClass
*base_class
;
131 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
133 st_parent_class
= g_type_class_peek_parent( klass
);
135 object_class
= G_OBJECT_CLASS( klass
);
136 object_class
->constructed
= instance_constructed
;
137 object_class
->get_property
= instance_get_property
;
138 object_class
->set_property
= instance_set_property
;
139 object_class
->dispose
= instance_dispose
;
140 object_class
->finalize
= instance_finalize
;
142 g_object_class_install_property( object_class
, BASE_PROP_QUIT_ON_ESCAPE_ID
,
143 g_param_spec_boolean(
144 BASE_PROP_QUIT_ON_ESCAPE
,
145 _( "Quit on Escape" ),
146 _( "Should the assistant 'Quit' when the user hits Escape ?" ),
148 G_PARAM_CONSTRUCT
| G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
150 g_object_class_install_property( object_class
, BASE_PROP_WARN_ON_ESCAPE_ID
,
151 g_param_spec_boolean(
152 BASE_PROP_WARN_ON_ESCAPE
,
153 _( "Warn on Escape" ),
154 _( "Should the user be asked to confirm when exiting the assistant via Escape ?" ),
156 G_PARAM_CONSTRUCT
| G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
158 base_class
= BASE_WINDOW_CLASS( klass
);
159 base_class
->run
= do_run
;
163 instance_init( GTypeInstance
*instance
, gpointer klass
)
165 static const gchar
*thisfn
= "base_assistant_instance_init";
168 g_return_if_fail( BASE_IS_ASSISTANT( instance
));
170 g_debug( "%s: instance=%p (%s), klass=%p",
171 thisfn
, ( void * ) instance
, G_OBJECT_TYPE_NAME( instance
), ( void * ) klass
);
173 self
= BASE_ASSISTANT( instance
);
175 self
->private = g_new0( BaseAssistantPrivate
, 1 );
177 self
->private->dispose_has_run
= FALSE
;
178 self
->private->quit_on_escape
= FALSE
;
179 self
->private->warn_on_escape
= FALSE
;
180 self
->private->escape_key_pressed
= FALSE
;
184 instance_get_property( GObject
*object
, guint property_id
, GValue
*value
, GParamSpec
*spec
)
188 g_return_if_fail( BASE_IS_ASSISTANT( object
));
190 self
= BASE_ASSISTANT( object
);
192 if( !self
->private->dispose_has_run
){
194 switch( property_id
){
195 case BASE_PROP_QUIT_ON_ESCAPE_ID
:
196 g_value_set_boolean( value
, self
->private->quit_on_escape
);
199 case BASE_PROP_WARN_ON_ESCAPE_ID
:
200 g_value_set_boolean( value
, self
->private->warn_on_escape
);
204 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
211 instance_set_property( GObject
*object
, guint property_id
, const GValue
*value
, GParamSpec
*spec
)
215 g_return_if_fail( BASE_IS_ASSISTANT( object
));
217 self
= BASE_ASSISTANT( object
);
219 if( !self
->private->dispose_has_run
){
221 switch( property_id
){
222 case BASE_PROP_QUIT_ON_ESCAPE_ID
:
223 self
->private->quit_on_escape
= g_value_get_boolean( value
);
226 case BASE_PROP_WARN_ON_ESCAPE_ID
:
227 self
->private->warn_on_escape
= g_value_get_boolean( value
);
231 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
238 instance_constructed( GObject
*window
)
240 static const gchar
*thisfn
= "base_assistant_instance_constructed";
241 BaseAssistantPrivate
*priv
;
243 g_return_if_fail( BASE_IS_ASSISTANT( window
));
245 priv
= BASE_ASSISTANT( window
)->private;
247 if( !priv
->dispose_has_run
){
249 /* chain up to the parent class */
250 if( G_OBJECT_CLASS( st_parent_class
)->constructed
){
251 G_OBJECT_CLASS( st_parent_class
)->constructed( window
);
254 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
256 base_window_signal_connect(
257 BASE_WINDOW( window
),
259 BASE_SIGNAL_INITIALIZE_WINDOW
,
260 G_CALLBACK( on_initialize_base_window
));
265 instance_dispose( GObject
*window
)
267 static const gchar
*thisfn
= "base_assistant_instance_dispose";
268 BaseAssistantPrivate
*priv
;
270 g_return_if_fail( BASE_IS_ASSISTANT( window
));
272 priv
= BASE_ASSISTANT( window
)->private;
274 if( !priv
->dispose_has_run
){
275 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
277 priv
->dispose_has_run
= TRUE
;
281 /* chain up to the parent class */
282 if( G_OBJECT_CLASS( st_parent_class
)->dispose
){
283 G_OBJECT_CLASS( st_parent_class
)->dispose( window
);
289 instance_finalize( GObject
*window
)
291 static const gchar
*thisfn
= "base_assistant_instance_finalize";
292 BaseAssistantPrivate
*priv
;
294 g_return_if_fail( BASE_IS_ASSISTANT( window
));
296 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
298 priv
= BASE_ASSISTANT( window
)->private;
302 /* chain call to parent class */
303 if( G_OBJECT_CLASS( st_parent_class
)->finalize
){
304 G_OBJECT_CLASS( st_parent_class
)->finalize( window
);
309 on_initialize_base_window( BaseAssistant
*window
)
311 static const gchar
*thisfn
= "base_assistant_on_initialize_base_window";
314 g_return_if_fail( BASE_IS_ASSISTANT( window
));
316 g_debug( "%s: window=%p (%s)", thisfn
, ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
318 if( !window
->private->dispose_has_run
){
320 toplevel
= base_window_get_gtk_toplevel( BASE_WINDOW( window
));
321 g_return_if_fail( GTK_IS_ASSISTANT( toplevel
));
323 /* deals with 'Esc' key
325 base_window_signal_connect(
326 BASE_WINDOW( window
),
327 G_OBJECT( toplevel
),
329 G_CALLBACK( on_key_pressed_event
));
331 /* transforms 'prepare' and 'apply' messages into virtual methods
333 base_window_signal_connect(
334 BASE_WINDOW( window
),
335 G_OBJECT( toplevel
),
337 G_CALLBACK( on_prepare
));
339 base_window_signal_connect(
340 BASE_WINDOW( window
),
341 G_OBJECT( toplevel
),
343 G_CALLBACK( on_apply
));
345 /* close the assistant
347 base_window_signal_connect(
348 BASE_WINDOW( window
),
349 G_OBJECT( toplevel
),
351 G_CALLBACK( on_cancel
));
353 base_window_signal_connect(
354 BASE_WINDOW( window
),
355 G_OBJECT( toplevel
),
357 G_CALLBACK( on_close
));
362 * run the assistant in a main event loop, which will be quitted
366 do_run( BaseWindow
*window
)
368 static const gchar
*thisfn
= "base_assistant_do_run";
371 g_return_val_if_fail( BASE_IS_ASSISTANT( window
), FMA_EXIT_CODE_PROGRAM
);
373 code
= FMA_EXIT_CODE_WINDOW
;
375 if( !BASE_ASSISTANT( window
)->private->dispose_has_run
){
377 g_debug( "%s: window=%p (%s), starting gtk_main",
379 ( void * ) window
, G_OBJECT_TYPE_NAME( window
));
383 code
= FMA_EXIT_CODE_OK
;
390 on_key_pressed_event( GtkWidget
*widget
, GdkEventKey
*event
, BaseAssistant
*assistant
)
392 gboolean stop
= FALSE
;
395 g_return_val_if_fail( BASE_IS_ASSISTANT( assistant
), FALSE
);
397 if( !assistant
->private->dispose_has_run
){
399 if( event
->keyval
== FMA_KEY_Escape
&& assistant
->private->quit_on_escape
){
401 assistant
->private->escape_key_pressed
= TRUE
;
402 toplevel
= base_window_get_gtk_toplevel( BASE_WINDOW( assistant
));
403 g_signal_emit_by_name( toplevel
, "cancel", toplevel
);
412 on_prepare( GtkAssistant
*assistant
, GtkWidget
*page
, BaseAssistant
*window
)
414 g_return_if_fail( BASE_IS_ASSISTANT( window
));
416 if( BASE_ASSISTANT_GET_CLASS( window
)->prepare
){
417 BASE_ASSISTANT_GET_CLASS( window
)->prepare( window
, assistant
, page
);
422 on_apply( GtkAssistant
*assistant
, BaseAssistant
*window
)
424 g_return_if_fail( BASE_IS_ASSISTANT( window
));
426 if( BASE_ASSISTANT_GET_CLASS( window
)->apply
){
427 BASE_ASSISTANT_GET_CLASS( window
)->apply( window
, assistant
);
432 * either the 'Cancel' button has been clicked
433 * or the 'cancel' message has been emitted on the toplevel GtkAssistant
434 * due to the 'Escape' key being pressed and 'quit-on-cancel' property
438 on_cancel( GtkAssistant
*assistant
, BaseAssistant
*window
)
440 static const gchar
*thisfn
= "base_assistant_on_cancel";
444 g_return_if_fail( BASE_IS_ASSISTANT( window
));
446 g_debug( "%s: window=%p, assistant=%p", thisfn
, ( void * ) window
, ( void * ) assistant
);
448 if( window
->private->warn_on_escape
&& window
->private->escape_key_pressed
){
450 msg
= g_strdup( _( "Are you sure you want to quit this assistant ?" ));
451 ok
= base_window_display_yesno_dlg( BASE_WINDOW( window
), msg
, NULL
);
455 window
->private->escape_key_pressed
= FALSE
;
458 do_close( window
, assistant
);
463 on_close( GtkAssistant
*assistant
, BaseAssistant
*window
)
465 g_return_if_fail( BASE_IS_ASSISTANT( window
));
467 do_close( window
, assistant
);
471 do_close( BaseAssistant
*window
, GtkAssistant
*assistant
)
473 static const gchar
*thisfn
= "base_assistant_do_close";
475 g_debug( "%s: window=%p, assistant=%p", thisfn
, ( void * ) window
, ( void * ) assistant
);
477 g_object_unref( window
);