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)
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"
46 struct _NactAddSchemeDialogClassPrivate
{
47 void *empty
; /* so that gcc -pedantic is happy */
50 /* private instance data
52 struct _NactAddSchemeDialogPrivate
{
53 gboolean dispose_has_run
;
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
);
85 nact_add_scheme_dialog_get_type( void )
87 static GType dialog_type
= 0;
90 dialog_type
= register_type();
93 return( dialog_type
);
99 static const gchar
*thisfn
= "nact_add_scheme_dialog_register_type";
102 static GTypeInfo info
= {
103 sizeof( NactAddSchemeDialogClass
),
104 ( GBaseInitFunc
) NULL
,
105 ( GBaseFinalizeFunc
) NULL
,
106 ( GClassInitFunc
) class_init
,
109 sizeof( NactAddSchemeDialog
),
111 ( GInstanceInitFunc
) instance_init
114 g_debug( "%s", thisfn
);
116 type
= g_type_register_static( BASE_DIALOG_TYPE
, "NactAddSchemeDialog", &info
, 0 );
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
;
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
;
179 instance_dispose( GObject
*dialog
)
181 static const gchar
*thisfn
= "nact_add_scheme_dialog_instance_dispose";
182 NactAddSchemeDialog
*self
;
183 GtkTreeView
*listview
;
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
);
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
,
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.
256 nact_add_scheme_dialog_run( BaseWindow
*parent
, GSList
*schemes
)
258 static const gchar
*thisfn
= "nact_add_scheme_dialog_run";
259 NactAddSchemeDialog
*dialog
;
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
);
279 base_get_iprefs_window_id( const BaseWindow
*window
)
281 return( g_strdup( NA_IPREFS_SCHEME_ADD_SCHEME_WSP
));
285 base_get_dialog_name( const BaseWindow
*window
)
287 return( g_strdup( "AddSchemeDialog" ));
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
);
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
));
331 base_window_signal_connect_by_name(
332 BASE_WINDOW( dialog
),
335 G_CALLBACK( on_cancel_clicked
));
337 base_window_signal_connect_by_name(
338 BASE_WINDOW( dialog
),
341 G_CALLBACK( on_ok_clicked
));
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
));
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
);
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
);
382 on_ok_clicked( GtkButton
*button
, NactAddSchemeDialog
*dialog
)
388 * this function is a callback, called from nact-schemes-list:on_selection_changed
389 * this let us validate/invalidate the OK button
392 on_selection_changed( const gchar
*scheme
, gboolean used
, NactAddSchemeDialog
*dialog
)
396 button
= base_window_get_widget( BASE_WINDOW( dialog
), "OKButton" );
397 gtk_widget_set_sensitive( button
, !used
);
401 try_for_send_ok( NactAddSchemeDialog
*dialog
)
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
);
416 is_sensitive
= GTK_WIDGET_IS_SENSITIVE( button
);
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
);
433 validate_dialog( NactAddSchemeDialog
*dialog
)
435 dialog
->private->scheme
= nact_schemes_list_get_current_scheme( BASE_WINDOW( dialog
));
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
);
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
: