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";
59 static const gchar
*st_toplevel_name
= "AddSchemeDialog";
60 static const gchar
*st_wsp_name
= NA_IPREFS_SCHEME_ADD_SCHEME_WSP
;
62 static GObjectClass
*st_parent_class
= NULL
;
64 static GType
register_type( void );
65 static void class_init( NactAddSchemeDialogClass
*klass
);
66 static void instance_init( GTypeInstance
*instance
, gpointer klass
);
67 static void instance_dispose( GObject
*dialog
);
68 static void instance_finalize( GObject
*dialog
);
70 static void on_base_initialize_gtk_toplevel( NactAddSchemeDialog
*editor
, GtkDialog
*toplevel
);
71 static void on_base_initialize_base_window( NactAddSchemeDialog
*editor
);
72 static void on_base_all_widgets_showed( NactAddSchemeDialog
*editor
);
73 static gboolean
on_button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, NactAddSchemeDialog
*dialog
);
74 static void on_cancel_clicked( GtkButton
*button
, NactAddSchemeDialog
*editor
);
75 static void on_ok_clicked( GtkButton
*button
, NactAddSchemeDialog
*editor
);
76 static void on_selection_changed( const gchar
*scheme
, gboolean used
, NactAddSchemeDialog
*dialog
);
77 static void try_for_send_ok( NactAddSchemeDialog
*dialog
);
78 static void send_ok( NactAddSchemeDialog
*dialog
);
79 static void on_dialog_ok( BaseDialog
*dialog
);
82 nact_add_scheme_dialog_get_type( void )
84 static GType dialog_type
= 0;
87 dialog_type
= register_type();
90 return( dialog_type
);
96 static const gchar
*thisfn
= "nact_add_scheme_dialog_register_type";
99 static GTypeInfo info
= {
100 sizeof( NactAddSchemeDialogClass
),
101 ( GBaseInitFunc
) NULL
,
102 ( GBaseFinalizeFunc
) NULL
,
103 ( GClassInitFunc
) class_init
,
106 sizeof( NactAddSchemeDialog
),
108 ( GInstanceInitFunc
) instance_init
111 g_debug( "%s", thisfn
);
113 type
= g_type_register_static( BASE_DIALOG_TYPE
, "NactAddSchemeDialog", &info
, 0 );
119 class_init( NactAddSchemeDialogClass
*klass
)
121 static const gchar
*thisfn
= "nact_add_scheme_dialog_class_init";
122 GObjectClass
*object_class
;
123 BaseDialogClass
*dialog_class
;
125 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
127 st_parent_class
= g_type_class_peek_parent( klass
);
129 object_class
= G_OBJECT_CLASS( klass
);
130 object_class
->dispose
= instance_dispose
;
131 object_class
->finalize
= instance_finalize
;
133 klass
->private = g_new0( NactAddSchemeDialogClassPrivate
, 1 );
135 dialog_class
= BASE_DIALOG_CLASS( klass
);
136 dialog_class
->ok
= on_dialog_ok
;
140 instance_init( GTypeInstance
*instance
, gpointer klass
)
142 static const gchar
*thisfn
= "nact_add_scheme_dialog_instance_init";
143 NactAddSchemeDialog
*self
;
145 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( instance
));
147 g_debug( "%s: instance=%p, klass=%p", thisfn
, ( void * ) instance
, ( void * ) klass
);
149 self
= NACT_ADD_SCHEME_DIALOG( instance
);
151 self
->private = g_new0( NactAddSchemeDialogPrivate
, 1 );
153 base_window_signal_connect( BASE_WINDOW( instance
),
154 G_OBJECT( instance
), BASE_SIGNAL_INITIALIZE_GTK
, G_CALLBACK( on_base_initialize_gtk_toplevel
));
156 base_window_signal_connect( BASE_WINDOW( instance
),
157 G_OBJECT( instance
), BASE_SIGNAL_INITIALIZE_WINDOW
, G_CALLBACK( on_base_initialize_base_window
));
159 base_window_signal_connect( BASE_WINDOW( instance
),
160 G_OBJECT( instance
), BASE_SIGNAL_ALL_WIDGETS_SHOWED
, G_CALLBACK( on_base_all_widgets_showed
));
162 self
->private->dispose_has_run
= FALSE
;
163 self
->private->scheme
= NULL
;
167 instance_dispose( GObject
*dialog
)
169 static const gchar
*thisfn
= "nact_add_scheme_dialog_instance_dispose";
170 NactAddSchemeDialog
*self
;
171 GtkTreeView
*listview
;
173 GtkTreeSelection
*selection
;
175 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog
));
177 g_debug( "%s: dialog=%p (%s)", thisfn
, ( void * ) dialog
, G_OBJECT_TYPE_NAME( dialog
));
179 self
= NACT_ADD_SCHEME_DIALOG( dialog
);
181 if( !self
->private->dispose_has_run
){
183 self
->private->dispose_has_run
= TRUE
;
185 listview
= GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog
), "SchemesTreeView" ));
186 model
= gtk_tree_view_get_model( listview
);
187 selection
= gtk_tree_view_get_selection( listview
);
188 gtk_tree_selection_unselect_all( selection
);
189 gtk_list_store_clear( GTK_LIST_STORE( model
));
191 /* chain up to the parent class */
192 if( G_OBJECT_CLASS( st_parent_class
)->dispose
){
193 G_OBJECT_CLASS( st_parent_class
)->dispose( dialog
);
199 instance_finalize( GObject
*dialog
)
201 static const gchar
*thisfn
= "nact_add_scheme_dialog_instance_finalize";
202 NactAddSchemeDialog
*self
;
204 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog
));
206 g_debug( "%s: dialog=%p (%s)", thisfn
, ( void * ) dialog
, G_OBJECT_TYPE_NAME( dialog
));
208 self
= NACT_ADD_SCHEME_DIALOG( dialog
);
210 na_core_utils_slist_free( self
->private->already_used
);
211 g_free( self
->private->scheme
);
213 g_free( self
->private );
215 /* chain call to parent class */
216 if( G_OBJECT_CLASS( st_parent_class
)->finalize
){
217 G_OBJECT_CLASS( st_parent_class
)->finalize( dialog
);
222 * nact_add_scheme_dialog_run:
223 * @parent: the BaseWindow parent of this dialog
224 * (usually the NactMainWindow).
225 * @schemes: list of already used schemes.
227 * Initializes and runs the dialog.
229 * Returns: the selected scheme, as a newly allocated string which should
230 * be g_free() by the caller, or NULL.
233 nact_add_scheme_dialog_run( BaseWindow
*parent
, GSList
*schemes
)
235 static const gchar
*thisfn
= "nact_add_scheme_dialog_run";
236 NactAddSchemeDialog
*dialog
;
239 g_debug( "%s: parent=%p", thisfn
, ( void * ) parent
);
241 g_return_val_if_fail( BASE_IS_WINDOW( parent
), NULL
);
243 dialog
= g_object_new( NACT_ADD_SCHEME_DIALOG_TYPE
,
244 BASE_PROP_PARENT
, parent
,
245 BASE_PROP_XMLUI_FILENAME
, st_xmlui_filename
,
246 BASE_PROP_TOPLEVEL_NAME
, st_toplevel_name
,
247 BASE_PROP_WSP_NAME
, st_wsp_name
,
250 dialog
->private->already_used
= na_core_utils_slist_duplicate( schemes
);
253 if( base_window_run( BASE_WINDOW( dialog
)) == GTK_RESPONSE_OK
){
254 scheme
= g_strdup( dialog
->private->scheme
);
257 g_object_unref( dialog
);
263 on_base_initialize_gtk_toplevel( NactAddSchemeDialog
*dialog
, GtkDialog
*toplevel
)
265 static const gchar
*thisfn
= "nact_add_scheme_dialog_on_base_initialize_gtk_toplevel";
266 GtkTreeView
*listview
;
268 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog
));
270 if( !dialog
->private->dispose_has_run
){
271 g_debug( "%s: dialog=%p, toplevel=%p", thisfn
, ( void * ) dialog
, ( void * ) toplevel
);
273 listview
= GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog
), "SchemesTreeView" ));
274 nact_schemes_list_create_model( listview
, SCHEMES_LIST_FOR_ADD_FROM_DEFAULTS
);
276 #if !GTK_CHECK_VERSION( 2,22,0 )
277 gtk_dialog_set_has_separator( toplevel
, FALSE
);
283 on_base_initialize_base_window( NactAddSchemeDialog
*dialog
)
285 static const gchar
*thisfn
= "nact_add_scheme_dialog_on_base_initialize_base_window";
286 GtkTreeView
*listview
;
288 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog
));
290 if( !dialog
->private->dispose_has_run
){
291 g_debug( "%s: dialog=%p", thisfn
, ( void * ) dialog
);
293 listview
= GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( dialog
), "SchemesTreeView" ));
294 nact_schemes_list_init_view( listview
, BASE_WINDOW( dialog
), ( pf_new_selection_cb
) on_selection_changed
, ( void * ) dialog
);
296 nact_schemes_list_setup_values( BASE_WINDOW( dialog
), dialog
->private->already_used
);
298 /* catch double-click */
299 base_window_signal_connect(
300 BASE_WINDOW( dialog
),
301 G_OBJECT( listview
),
302 "button-press-event",
303 G_CALLBACK( on_button_press_event
));
307 base_window_signal_connect_by_name(
308 BASE_WINDOW( dialog
),
311 G_CALLBACK( on_cancel_clicked
));
313 base_window_signal_connect_by_name(
314 BASE_WINDOW( dialog
),
317 G_CALLBACK( on_ok_clicked
));
322 on_base_all_widgets_showed( NactAddSchemeDialog
*dialog
)
324 static const gchar
*thisfn
= "nact_add_scheme_dialog_on_base_all_widgets_showed";
326 g_return_if_fail( NACT_IS_ADD_SCHEME_DIALOG( dialog
));
328 if( !dialog
->private->dispose_has_run
){
329 g_debug( "%s: dialog=%p", thisfn
, ( void * ) dialog
);
331 nact_schemes_list_show_all( BASE_WINDOW( dialog
));
336 on_button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, NactAddSchemeDialog
*dialog
)
338 gboolean stop
= FALSE
;
340 /* double-click of left button */
341 if( event
->type
== GDK_2BUTTON_PRESS
&& event
->button
== 1 ){
342 try_for_send_ok( dialog
);
350 on_cancel_clicked( GtkButton
*button
, NactAddSchemeDialog
*dialog
)
352 GtkWindow
*toplevel
= base_window_get_gtk_toplevel( BASE_WINDOW( dialog
));
354 gtk_dialog_response( GTK_DIALOG( toplevel
), GTK_RESPONSE_CLOSE
);
358 on_ok_clicked( GtkButton
*button
, NactAddSchemeDialog
*dialog
)
364 * this function is a callback, called from nact-schemes-list:on_selection_changed
365 * this let us validate/invalidate the OK button
368 on_selection_changed( const gchar
*scheme
, gboolean used
, NactAddSchemeDialog
*dialog
)
372 button
= base_window_get_widget( BASE_WINDOW( dialog
), "OKButton" );
373 gtk_widget_set_sensitive( button
, !used
);
377 try_for_send_ok( NactAddSchemeDialog
*dialog
)
380 gboolean is_sensitive
;
382 button
= base_window_get_widget( BASE_WINDOW( dialog
), "OKButton" );
384 /* gtk_widget_is_sensitive() appears with Gtk+ 2.17.5 released on 2009-07-18
385 * see http://git.gnome.org/browse/gtk+/commit/?id=8f6017622937770082f7b49dfbe135fae5608704
386 * GTK_WIDGET_IS_SENSITIVE macro is deprecated since 2.19.7 released on 2010-03-09
387 * see http://git.gnome.org/browse/gtk+/commit/?id=a27d5a2c9eba7af5b056de32ff9b2b4dd1eb97e1
389 #if GTK_CHECK_VERSION( 2, 17, 5 )
390 is_sensitive
= gtk_widget_is_sensitive( button
);
392 is_sensitive
= GTK_WIDGET_IS_SENSITIVE( button
);
401 send_ok( NactAddSchemeDialog
*dialog
)
403 GtkWindow
*toplevel
= base_window_get_gtk_toplevel( BASE_WINDOW( dialog
));
405 gtk_dialog_response( GTK_DIALOG( toplevel
), GTK_RESPONSE_OK
);
409 on_dialog_ok( BaseDialog
*dialog
)
411 NactAddSchemeDialog
*editor
= NACT_ADD_SCHEME_DIALOG( dialog
);
412 editor
->private->scheme
= nact_schemes_list_get_current_scheme( BASE_WINDOW( dialog
));