README: add deprecation notice
[nautilus-actions.git] / src / ui / base-assistant.c
blob5e0d9545d4d9718b49cc205c4e5feedc62556604
1 /*
2 * FileManager-Actions
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/>.
23 * Authors:
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)
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
34 #include <glib.h>
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;
46 /* properties
48 gboolean quit_on_escape;
49 gboolean warn_on_escape;
51 /* internals
53 gboolean escape_key_pressed;
56 /* instance properties
58 enum {
59 BASE_PROP_0,
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 );
87 GType
88 base_assistant_get_type( void )
90 static GType window_type = 0;
92 if( !window_type ){
93 window_type = register_type();
96 return( window_type );
99 static GType
100 register_type( void )
102 static const gchar *thisfn = "base_assistant_register_type";
103 GType type;
105 static GTypeInfo info = {
106 sizeof( BaseAssistantClass ),
107 ( GBaseInitFunc ) NULL,
108 ( GBaseFinalizeFunc ) NULL,
109 ( GClassInitFunc ) class_init,
110 NULL,
111 NULL,
112 sizeof( BaseAssistant ),
114 ( GInstanceInitFunc ) instance_init
117 g_debug( "%s", thisfn );
119 type = g_type_register_static( BASE_TYPE_WINDOW, "BaseAssistant", &info, 0 );
121 return( type );
124 static void
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 ?" ),
147 FALSE,
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 ?" ),
155 FALSE,
156 G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
158 base_class = BASE_WINDOW_CLASS( klass );
159 base_class->run = do_run;
162 static void
163 instance_init( GTypeInstance *instance, gpointer klass )
165 static const gchar *thisfn = "base_assistant_instance_init";
166 BaseAssistant *self;
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;
183 static void
184 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
186 BaseAssistant *self;
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 );
197 break;
199 case BASE_PROP_WARN_ON_ESCAPE_ID:
200 g_value_set_boolean( value, self->private->warn_on_escape );
201 break;
203 default:
204 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
205 break;
210 static void
211 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
213 BaseAssistant *self;
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 );
224 break;
226 case BASE_PROP_WARN_ON_ESCAPE_ID:
227 self->private->warn_on_escape = g_value_get_boolean( value );
228 break;
230 default:
231 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
232 break;
237 static void
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 ),
258 G_OBJECT( window ),
259 BASE_SIGNAL_INITIALIZE_WINDOW,
260 G_CALLBACK( on_initialize_base_window ));
264 static void
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;
279 gtk_main_quit();
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 );
288 static void
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;
300 g_free( priv );
302 /* chain call to parent class */
303 if( G_OBJECT_CLASS( st_parent_class )->finalize ){
304 G_OBJECT_CLASS( st_parent_class )->finalize( window );
308 static void
309 on_initialize_base_window( BaseAssistant *window )
311 static const gchar *thisfn = "base_assistant_on_initialize_base_window";
312 GtkWindow *toplevel;
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 ),
328 "key-press-event",
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 ),
336 "prepare",
337 G_CALLBACK( on_prepare ));
339 base_window_signal_connect(
340 BASE_WINDOW( window ),
341 G_OBJECT( toplevel ),
342 "apply",
343 G_CALLBACK( on_apply ));
345 /* close the assistant
347 base_window_signal_connect(
348 BASE_WINDOW( window ),
349 G_OBJECT( toplevel ),
350 "cancel",
351 G_CALLBACK( on_cancel ));
353 base_window_signal_connect(
354 BASE_WINDOW( window ),
355 G_OBJECT( toplevel ),
356 "close",
357 G_CALLBACK( on_close ));
362 * run the assistant in a main event loop, which will be quitted
363 * at dispose time
365 static int
366 do_run( BaseWindow *window )
368 static const gchar *thisfn = "base_assistant_do_run";
369 int code;
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",
378 thisfn,
379 ( void * ) window, G_OBJECT_TYPE_NAME( window ));
381 gtk_main();
383 code = FMA_EXIT_CODE_OK;
386 return( code );
389 static gboolean
390 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseAssistant *assistant )
392 gboolean stop = FALSE;
393 GtkWindow *toplevel;
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 );
404 stop = TRUE;
408 return( stop );
411 static void
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 );
421 static void
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
435 * is true
437 static void
438 on_cancel( GtkAssistant *assistant, BaseAssistant *window )
440 static const gchar *thisfn = "base_assistant_on_cancel";
441 gboolean ok = TRUE;
442 gchar *msg;
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 );
452 g_free( msg );
455 window->private->escape_key_pressed = FALSE;
457 if( ok ){
458 do_close( window, assistant );
462 static void
463 on_close( GtkAssistant *assistant, BaseAssistant *window )
465 g_return_if_fail( BASE_IS_ASSISTANT( window ));
467 do_close( window, assistant );
470 static void
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 );