Remove BaseWindow::get_ui_filename() virtual method
[nautilus-actions.git] / src / nact / nact-add-scheme-dialog.c
blob29f72ed69ebed41617f5a880ef028e0f4b6598a5
1 /*
2 * Nautilus-Actions
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.
24 * Authors:
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)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <gdk/gdkkeysyms.h>
37 #include <api/na-core-utils.h>
39 #include <core/na-settings.h>
41 #include "nact-schemes-list.h"
42 #include "nact-add-scheme-dialog.h"
44 /* private class data
46 struct _NactAddSchemeDialogClassPrivate {
47 void *empty; /* so that gcc -pedantic is happy */
50 /* private instance data
52 struct _NactAddSchemeDialogPrivate {
53 gboolean dispose_has_run;
54 GSList *already_used;
55 gchar *scheme;
58 static const gchar *st_xmlui_filename = PKGDATADIR "/nact-add-scheme.ui";
60 static GObjectClass *st_parent_class = NULL;
62 static GType register_type( void );
63 static void class_init( NactAddSchemeDialogClass *klass );
64 static void instance_init( GTypeInstance *instance, gpointer klass );
65 static void instance_dispose( GObject *dialog );
66 static void instance_finalize( GObject *dialog );
68 static NactAddSchemeDialog *add_scheme_dialog_new( BaseWindow *parent );
70 static gchar *base_get_iprefs_window_id( const BaseWindow *window );
71 static gchar *base_get_dialog_name( const BaseWindow *window );
72 static void on_base_initial_load_dialog( NactAddSchemeDialog *editor, gpointer user_data );
73 static void on_base_runtime_init_dialog( NactAddSchemeDialog *editor, gpointer user_data );
74 static void on_base_all_widgets_showed( NactAddSchemeDialog *editor, gpointer user_data );
75 static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactAddSchemeDialog *dialog );
76 static void on_cancel_clicked( GtkButton *button, NactAddSchemeDialog *editor );
77 static void on_ok_clicked( GtkButton *button, NactAddSchemeDialog *editor );
78 static void on_selection_changed( const gchar *scheme, gboolean used, NactAddSchemeDialog *dialog );
79 static void try_for_send_ok( NactAddSchemeDialog *dialog );
80 static void send_ok( NactAddSchemeDialog *dialog );
81 static void validate_dialog( NactAddSchemeDialog *editor );
82 static gboolean base_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
84 GType
85 nact_add_scheme_dialog_get_type( void )
87 static GType dialog_type = 0;
89 if( !dialog_type ){
90 dialog_type = register_type();
93 return( dialog_type );
96 static GType
97 register_type( void )
99 static const gchar *thisfn = "nact_add_scheme_dialog_register_type";
100 GType type;
102 static GTypeInfo info = {
103 sizeof( NactAddSchemeDialogClass ),
104 ( GBaseInitFunc ) NULL,
105 ( GBaseFinalizeFunc ) NULL,
106 ( GClassInitFunc ) class_init,
107 NULL,
108 NULL,
109 sizeof( NactAddSchemeDialog ),
111 ( GInstanceInitFunc ) instance_init
114 g_debug( "%s", thisfn );
116 type = g_type_register_static( BASE_DIALOG_TYPE, "NactAddSchemeDialog", &info, 0 );
118 return( type );
121 static void
122 class_init( NactAddSchemeDialogClass *klass )
124 static const gchar *thisfn = "nact_add_scheme_dialog_class_init";
125 GObjectClass *object_class;
126 BaseWindowClass *base_class;
128 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
130 st_parent_class = g_type_class_peek_parent( klass );
132 object_class = G_OBJECT_CLASS( klass );
133 object_class->dispose = instance_dispose;
134 object_class->finalize = instance_finalize;
136 klass->private = g_new0( NactAddSchemeDialogClassPrivate, 1 );
138 base_class = BASE_WINDOW_CLASS( klass );
139 base_class->dialog_response = base_dialog_response;
140 base_class->get_toplevel_name = base_get_dialog_name;
141 base_class->get_iprefs_window_id = base_get_iprefs_window_id;
144 static void
145 instance_init( GTypeInstance *instance, gpointer klass )
147 static const gchar *thisfn = "nact_add_scheme_dialog_instance_init";
148 NactAddSchemeDialog *self;
150 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( instance ));
151 g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
152 self = NACT_ADD_SCHEME_DIALOG( instance );
154 self->private = g_new0( NactAddSchemeDialogPrivate, 1 );
156 base_window_signal_connect(
157 BASE_WINDOW( instance ),
158 G_OBJECT( instance ),
159 BASE_SIGNAL_INITIALIZE_GTK,
160 G_CALLBACK( on_base_initial_load_dialog ));
162 base_window_signal_connect(
163 BASE_WINDOW( instance ),
164 G_OBJECT( instance ),
165 BASE_SIGNAL_INITIALIZE_WINDOW,
166 G_CALLBACK( on_base_runtime_init_dialog ));
168 base_window_signal_connect(
169 BASE_WINDOW( instance ),
170 G_OBJECT( instance ),
171 BASE_SIGNAL_ALL_WIDGETS_SHOWED,
172 G_CALLBACK( on_base_all_widgets_showed));
174 self->private->dispose_has_run = FALSE;
175 self->private->scheme = NULL;
178 static void
179 instance_dispose( GObject *dialog )
181 static const gchar *thisfn = "nact_add_scheme_dialog_instance_dispose";
182 NactAddSchemeDialog *self;
183 GtkTreeView *listview;
184 GtkTreeModel *model;
185 GtkTreeSelection *selection;
187 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog ));
188 g_debug( "%s: dialog=%p", thisfn, ( void * ) dialog );
189 self = NACT_ADD_SCHEME_DIALOG( dialog );
191 if( !self->private->dispose_has_run ){
193 self->private->dispose_has_run = TRUE;
195 listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog ), "SchemesTreeView" ));
196 model = gtk_tree_view_get_model( listview );
197 selection = gtk_tree_view_get_selection( listview );
198 gtk_tree_selection_unselect_all( selection );
199 gtk_list_store_clear( GTK_LIST_STORE( model ));
201 /* chain up to the parent class */
202 if( G_OBJECT_CLASS( st_parent_class )->dispose ){
203 G_OBJECT_CLASS( st_parent_class )->dispose( dialog );
208 static void
209 instance_finalize( GObject *dialog )
211 static const gchar *thisfn = "nact_add_scheme_dialog_instance_finalize";
212 NactAddSchemeDialog *self;
214 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog ));
215 g_debug( "%s: dialog=%p", thisfn, ( void * ) dialog );
216 self = NACT_ADD_SCHEME_DIALOG( dialog );
218 na_core_utils_slist_free( self->private->already_used );
219 g_free( self->private->scheme );
221 g_free( self->private );
223 /* chain call to parent class */
224 if( G_OBJECT_CLASS( st_parent_class )->finalize ){
225 G_OBJECT_CLASS( st_parent_class )->finalize( dialog );
230 * Returns a newly allocated NactAddSchemeDialog object.
232 * @parent: the BaseWindow parent of this dialog (usually, the main
233 * toplevel window of the application).
235 static NactAddSchemeDialog *
236 add_scheme_dialog_new( BaseWindow *parent )
238 return( g_object_new( NACT_ADD_SCHEME_DIALOG_TYPE,
239 BASE_PROP_PARENT, parent,
240 BASE_PROP_XMLUI_FILENAME, st_xmlui_filename,
241 NULL ));
245 * nact_add_scheme_dialog_run:
246 * @parent: the BaseWindow parent of this dialog
247 * (usually the NactMainWindow).
248 * @schemes: list of already used schemes.
250 * Initializes and runs the dialog.
252 * Returns: the selected scheme, as a newly allocated string which should
253 * be g_free() by the caller, or NULL.
255 gchar *
256 nact_add_scheme_dialog_run( BaseWindow *parent, GSList *schemes )
258 static const gchar *thisfn = "nact_add_scheme_dialog_run";
259 NactAddSchemeDialog *dialog;
260 gchar *scheme;
262 g_debug( "%s: parent=%p", thisfn, ( void * ) parent );
264 g_return_val_if_fail( BASE_IS_WINDOW( parent ), NULL );
266 dialog = add_scheme_dialog_new( parent );
267 dialog->private->already_used = na_core_utils_slist_duplicate( schemes );
269 base_window_run( BASE_WINDOW( dialog ));
271 scheme = g_strdup( dialog->private->scheme );
273 g_object_unref( dialog );
275 return( scheme );
278 static gchar *
279 base_get_iprefs_window_id( const BaseWindow *window )
281 return( g_strdup( NA_IPREFS_SCHEME_ADD_SCHEME_WSP ));
284 static gchar *
285 base_get_dialog_name( const BaseWindow *window )
287 return( g_strdup( "AddSchemeDialog" ));
290 static void
291 on_base_initial_load_dialog( NactAddSchemeDialog *dialog, gpointer user_data )
293 static const gchar *thisfn = "nact_add_scheme_dialog_on_initial_load_dialog";
294 GtkTreeView *listview;
296 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog ));
298 if( !dialog->private->dispose_has_run ){
299 g_debug( "%s: dialog=%p, user_data=%p", thisfn, ( void * ) dialog, ( void * ) user_data );
301 listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog ), "SchemesTreeView" ));
302 nact_schemes_list_create_model( listview, SCHEMES_LIST_FOR_ADD_FROM_DEFAULTS );
306 static void
307 on_base_runtime_init_dialog( NactAddSchemeDialog *dialog, gpointer user_data )
309 static const gchar *thisfn = "nact_add_scheme_dialog_on_runtime_init_dialog";
310 GtkTreeView *listview;
312 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog ));
314 if( !dialog->private->dispose_has_run ){
315 g_debug( "%s: dialog=%p, user_data=%p", thisfn, ( void * ) dialog, ( void * ) user_data );
317 listview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog ), "SchemesTreeView" ));
318 nact_schemes_list_init_view( listview, BASE_WINDOW( dialog ), ( pf_new_selection_cb ) on_selection_changed, ( void * ) dialog );
320 nact_schemes_list_setup_values( BASE_WINDOW( dialog ), dialog->private->already_used );
322 /* catch double-click */
323 base_window_signal_connect(
324 BASE_WINDOW( dialog ),
325 G_OBJECT( listview ),
326 "button-press-event",
327 G_CALLBACK( on_button_press_event ));
329 /* dialog buttons
331 base_window_signal_connect_by_name(
332 BASE_WINDOW( dialog ),
333 "CancelButton",
334 "clicked",
335 G_CALLBACK( on_cancel_clicked ));
337 base_window_signal_connect_by_name(
338 BASE_WINDOW( dialog ),
339 "OKButton",
340 "clicked",
341 G_CALLBACK( on_ok_clicked ));
345 static void
346 on_base_all_widgets_showed( NactAddSchemeDialog *dialog, gpointer user_data )
348 static const gchar *thisfn = "nact_add_scheme_dialog_on_all_widgets_showed";
350 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog ));
352 if( !dialog->private->dispose_has_run ){
353 g_debug( "%s: dialog=%p, user_data=%p", thisfn, ( void * ) dialog, ( void * ) user_data );
355 nact_schemes_list_show_all( BASE_WINDOW( dialog ));
359 static gboolean
360 on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactAddSchemeDialog *dialog )
362 gboolean stop = FALSE;
364 /* double-click of left button */
365 if( event->type == GDK_2BUTTON_PRESS && event->button == 1 ){
366 try_for_send_ok( dialog );
367 stop = TRUE;
370 return( stop );
373 static void
374 on_cancel_clicked( GtkButton *button, NactAddSchemeDialog *dialog )
376 GtkWindow *toplevel = base_window_get_gtk_toplevel( BASE_WINDOW( dialog ));
378 gtk_dialog_response( GTK_DIALOG( toplevel ), GTK_RESPONSE_CLOSE );
381 static void
382 on_ok_clicked( GtkButton *button, NactAddSchemeDialog *dialog )
384 send_ok( dialog );
388 * this function is a callback, called from nact-schemes-list:on_selection_changed
389 * this let us validate/invalidate the OK button
391 static void
392 on_selection_changed( const gchar *scheme, gboolean used, NactAddSchemeDialog *dialog )
394 GtkWidget *button;
396 button = base_window_get_widget( BASE_WINDOW( dialog ), "OKButton" );
397 gtk_widget_set_sensitive( button, !used );
400 static void
401 try_for_send_ok( NactAddSchemeDialog *dialog )
403 GtkWidget *button;
404 gboolean is_sensitive;
406 button = base_window_get_widget( BASE_WINDOW( dialog ), "OKButton" );
408 /* gtk_widget_is_sensitive() appears with Gtk+ 2.17.5 released on 2009-07-18
409 * see http://git.gnome.org/browse/gtk+/commit/?id=8f6017622937770082f7b49dfbe135fae5608704
410 * GTK_WIDGET_IS_SENSITIVE macro is deprecated since 2.19.7 released on 2010-03-09
411 * see http://git.gnome.org/browse/gtk+/commit/?id=a27d5a2c9eba7af5b056de32ff9b2b4dd1eb97e1
413 #if GTK_CHECK_VERSION( 2, 17, 5 )
414 is_sensitive = gtk_widget_is_sensitive( button );
415 #else
416 is_sensitive = GTK_WIDGET_IS_SENSITIVE( button );
417 #endif
419 if( is_sensitive ){
420 send_ok( dialog );
424 static void
425 send_ok( NactAddSchemeDialog *dialog )
427 GtkWindow *toplevel = base_window_get_gtk_toplevel( BASE_WINDOW( dialog ));
429 gtk_dialog_response( GTK_DIALOG( toplevel ), GTK_RESPONSE_OK );
432 static void
433 validate_dialog( NactAddSchemeDialog *dialog )
435 dialog->private->scheme = nact_schemes_list_get_current_scheme( BASE_WINDOW( dialog ));
438 static gboolean
439 base_dialog_response( GtkDialog *dialog_box, gint code, BaseWindow *window )
441 static const gchar *thisfn = "nact_add_scheme_dialog_on_dialog_response";
442 NactAddSchemeDialog *dialog;
444 g_return_val_if_fail( NACT_IS_ADD_SCHEME_DIALOG( window ), FALSE );
446 dialog = NACT_ADD_SCHEME_DIALOG( window );
448 if( !dialog->private->dispose_has_run ){
449 g_debug( "%s: dialog_box=%p, code=%d, window=%p", thisfn, ( void * ) dialog_box, code, ( void * ) window );
451 switch( code ){
452 case GTK_RESPONSE_OK:
453 validate_dialog( dialog );
455 case GTK_RESPONSE_NONE:
456 case GTK_RESPONSE_DELETE_EVENT:
457 case GTK_RESPONSE_CLOSE:
458 case GTK_RESPONSE_CANCEL:
459 return( TRUE );
460 break;
464 return( FALSE );