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 <glib/gi18n.h>
37 #include <api/na-iimporter.h>
38 #include <api/na-object-api.h>
40 #include "na-gtk-utils.h"
41 #include "na-iprefs.h"
42 #include "na-importer-ask.h"
46 struct _NAImporterAskClassPrivate
{
47 void *empty
; /* so that gcc -pedantic is happy */
50 /* private instance data
52 struct _NAImporterAskPrivate
{
53 gboolean dispose_has_run
;
56 NAObjectItem
*importing
;
57 NAObjectItem
*existing
;
58 NAImporterAskUserParms
*parms
;
63 static GtkDialogClass
*st_parent_class
= NULL
;
65 static GType
register_type( void );
66 static void class_init( NAImporterAskClass
*klass
);
67 static void instance_init( GTypeInstance
*instance
, gpointer klass
);
68 static void instance_dispose( GObject
*dialog
);
69 static void instance_finalize( GObject
*dialog
);
71 static NAImporterAsk
*import_ask_new();
73 static void init_dialog( NAImporterAsk
*editor
);
74 static void on_cancel_clicked( GtkButton
*button
, NAImporterAsk
*editor
);
75 static void on_ok_clicked( GtkButton
*button
, NAImporterAsk
*editor
);
76 static void get_selected_mode( NAImporterAsk
*editor
);
77 static gboolean
on_dialog_response( NAImporterAsk
*editor
, gint code
);
80 na_importer_ask_get_type( void )
82 static GType dialog_type
= 0;
85 dialog_type
= register_type();
88 return( dialog_type
);
94 static const gchar
*thisfn
= "na_importer_ask_register_type";
97 static GTypeInfo info
= {
98 sizeof( NAImporterAskClass
),
99 ( GBaseInitFunc
) NULL
,
100 ( GBaseFinalizeFunc
) NULL
,
101 ( GClassInitFunc
) class_init
,
104 sizeof( NAImporterAsk
),
106 ( GInstanceInitFunc
) instance_init
109 g_debug( "%s", thisfn
);
111 type
= g_type_register_static( GTK_TYPE_DIALOG
, "NAImporterAsk", &info
, 0 );
117 class_init( NAImporterAskClass
*klass
)
119 static const gchar
*thisfn
= "na_importer_ask_class_init";
120 GObjectClass
*object_class
;
122 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
124 st_parent_class
= g_type_class_peek_parent( klass
);
126 object_class
= G_OBJECT_CLASS( klass
);
127 object_class
->dispose
= instance_dispose
;
128 object_class
->finalize
= instance_finalize
;
130 klass
->private = g_new0( NAImporterAskClassPrivate
, 1 );
134 instance_init( GTypeInstance
*instance
, gpointer klass
)
136 static const gchar
*thisfn
= "na_importer_ask_instance_init";
140 g_return_if_fail( NA_IS_IMPORTER_ASK( instance
));
142 g_debug( "%s: instance=%p (%s), klass=%p",
143 thisfn
, ( void * ) instance
, G_OBJECT_TYPE_NAME( instance
), ( void * ) klass
);
145 self
= NA_IMPORTER_ASK( instance
);
147 self
->private = g_new0( NAImporterAskPrivate
, 1 );
149 self
->private->builder
= gtk_builder_new();
152 gtk_builder_add_from_file( self
->private->builder
, PKGDATADIR
"/na-importer-ask.ui", &error
);
154 g_warning( "%s: %s", thisfn
, error
->message
);
155 g_error_free( error
);
158 self
->private->toplevel
= GTK_WINDOW( gtk_builder_get_object( self
->private->builder
, "ImporterAskDialog" ));
161 self
->private->dispose_has_run
= FALSE
;
165 instance_dispose( GObject
*dialog
)
167 static const gchar
*thisfn
= "na_importer_ask_instance_dispose";
170 g_return_if_fail( NA_IS_IMPORTER_ASK( dialog
));
172 self
= NA_IMPORTER_ASK( dialog
);
174 if( !self
->private->dispose_has_run
){
176 g_debug( "%s: dialog=%p (%s)", thisfn
, ( void * ) dialog
, G_OBJECT_TYPE_NAME( dialog
));
178 self
->private->dispose_has_run
= TRUE
;
180 g_object_unref( self
->private->builder
);
182 /* chain up to the parent class */
183 if( G_OBJECT_CLASS( st_parent_class
)->dispose
){
184 G_OBJECT_CLASS( st_parent_class
)->dispose( dialog
);
190 instance_finalize( GObject
*dialog
)
192 static const gchar
*thisfn
= "na_importer_ask_instance_finalize";
195 g_return_if_fail( NA_IS_IMPORTER_ASK( dialog
));
197 g_debug( "%s: dialog=%p", thisfn
, ( void * ) dialog
);
199 self
= NA_IMPORTER_ASK( dialog
);
201 g_free( self
->private );
203 /* chain call to parent class */
204 if( G_OBJECT_CLASS( st_parent_class
)->finalize
){
205 G_OBJECT_CLASS( st_parent_class
)->finalize( dialog
);
210 * Returns a newly allocated NAImporterAsk object.
212 static NAImporterAsk
*
215 return( g_object_new( NA_IMPORTER_ASK_TYPE
, NULL
));
219 * na_importer_ask_user:
220 * @importing: the #NAObjectItem-derived object being currently imported.
221 * @existing: the #NAObjectItem-derived already existing object with the same ID.
222 * @parms: a #NAIImporterUriParms structure.
224 * Ask the user for what to do when an imported item has the same ID
225 * that an already existing one.
227 * Returns: the definitive import mode.
229 * When the user selects 'Keep same choice without asking me', this choice
230 * becomes his preference import mode.
233 na_importer_ask_user( const NAObjectItem
*importing
, const NAObjectItem
*existing
, NAImporterAskUserParms
*parms
)
235 static const gchar
*thisfn
= "na_importer_ask_user";
236 NAImporterAsk
*dialog
;
240 g_return_val_if_fail( NA_IS_OBJECT_ITEM( importing
), IMPORTER_MODE_NO_IMPORT
);
241 g_return_val_if_fail( NA_IS_OBJECT_ITEM( existing
), IMPORTER_MODE_NO_IMPORT
);
243 g_debug( "%s: importing=%p, existing=%p, parms=%p",
244 thisfn
, ( void * ) importing
, ( void * ) existing
, ( void * ) parms
);
246 mode
= IMPORTER_MODE_NO_IMPORT
;
247 dialog
= import_ask_new();
249 if( dialog
->private->toplevel
){
251 dialog
->private->importing
= ( NAObjectItem
* ) importing
;
252 dialog
->private->existing
= ( NAObjectItem
* ) existing
;
253 dialog
->private->parms
= parms
;
254 dialog
->private->mode
= na_iprefs_get_import_mode( NA_IPREFS_IMPORT_ASK_USER_LAST_MODE
, NULL
);
256 init_dialog( dialog
);
257 /* toplevel is modal, not dialog
258 g_debug( "dialog is modal: %s", gtk_window_get_modal( GTK_WINDOW( dialog )) ? "True":"False" );
259 g_debug( "toplevel is modal: %s", gtk_window_get_modal( dialog->private->toplevel ) ? "True":"False" );*/
261 code
= gtk_dialog_run( GTK_DIALOG( dialog
->private->toplevel
));
262 } while ( !on_dialog_response( dialog
, code
));
264 mode
= dialog
->private->mode
;
266 gtk_widget_hide( GTK_WIDGET( dialog
->private->toplevel
));
267 gtk_widget_destroy( GTK_WIDGET( dialog
->private->toplevel
));
270 g_object_unref( dialog
);
277 init_dialog( NAImporterAsk
*editor
)
279 static const gchar
*thisfn
= "na_importer_ask_init_dialog";
280 gchar
*imported_label
, *existing_label
;
285 g_return_if_fail( NA_IS_IMPORTER_ASK( editor
));
287 g_debug( "%s: editor=%p", thisfn
, ( void * ) editor
);
289 imported_label
= na_object_get_label( editor
->private->importing
);
290 existing_label
= na_object_get_label( editor
->private->existing
);
292 if( NA_IS_OBJECT_ACTION( editor
->private->importing
)){
293 /* i18n: The action <action_label> imported from <file> has the same id than <existing_label> */
294 label
= g_strdup_printf(
295 _( "The action \"%s\" imported from \"%s\" has the same identifiant than the already existing \"%s\"." ),
296 imported_label
, editor
->private->parms
->uri
, existing_label
);
299 /* i18n: The menu <menu_label> imported from <file> has the same id than <existing_label> */
300 label
= g_strdup_printf(
301 _( "The menu \"%s\" imported from \"%s\" has the same identifiant than the already existing \"%s\"." ),
302 imported_label
, editor
->private->parms
->uri
, existing_label
);
305 widget
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "ImporterAskLabel" );
306 gtk_label_set_text( GTK_LABEL( widget
), label
);
309 switch( editor
->private->mode
){
310 case IMPORTER_MODE_RENUMBER
:
311 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskRenumberButton" );
314 case IMPORTER_MODE_OVERRIDE
:
315 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskOverrideButton" );
318 case IMPORTER_MODE_NO_IMPORT
:
320 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskNoImportButton" );
323 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( button
), TRUE
);
325 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskKeepChoiceButton" );
326 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( button
), editor
->private->parms
->keep_choice
);
328 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "OKButton" );
332 G_CALLBACK( on_ok_clicked
),
335 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "CancelButton" );
339 G_CALLBACK( on_cancel_clicked
),
342 if( editor
->private->parms
->parent
){
343 gtk_window_set_transient_for( editor
->private->toplevel
, editor
->private->parms
->parent
);
346 gtk_widget_show_all( GTK_WIDGET( editor
->private->toplevel
));
350 on_cancel_clicked( GtkButton
*button
, NAImporterAsk
*editor
)
352 g_debug( "na_importer_ask_on_cancel_clicked" );
354 editor
->private->dialog_code
= GTK_RESPONSE_CANCEL
;
356 gtk_dialog_response( GTK_DIALOG( editor
), GTK_RESPONSE_CANCEL
);
360 on_ok_clicked( GtkButton
*button
, NAImporterAsk
*editor
)
362 g_debug( "na_importer_ask_on_ok_clicked" );
364 editor
->private->dialog_code
= GTK_RESPONSE_OK
;
366 gtk_dialog_response( GTK_DIALOG( editor
), GTK_RESPONSE_OK
);
370 get_selected_mode( NAImporterAsk
*editor
)
376 import_mode
= IMPORTER_MODE_NO_IMPORT
;
378 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskRenumberButton" );
379 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( button
))){
380 import_mode
= IMPORTER_MODE_RENUMBER
;
383 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskOverrideButton" );
384 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( button
))){
385 import_mode
= IMPORTER_MODE_OVERRIDE
;
389 editor
->private->mode
= import_mode
;
390 na_iprefs_set_import_mode( NA_IPREFS_IMPORT_ASK_USER_LAST_MODE
, editor
->private->mode
);
392 button
= na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor
->private->toplevel
), "AskKeepChoiceButton" );
393 keep
= gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( button
));
394 na_settings_set_boolean( NA_IPREFS_IMPORT_ASK_USER_KEEP_LAST_CHOICE
, keep
);
398 * very curiously, the code sent by on_cancel_clicked() and
399 * on_ok_clicked() arrives here at zero ! we so rely on a private one !
402 on_dialog_response( NAImporterAsk
*editor
, gint code
)
404 static const gchar
*thisfn
= "na_importer_ask_on_dialog_response";
406 g_return_val_if_fail( NA_IS_IMPORTER_ASK( editor
), FALSE
);
408 g_debug( "%s: editor=%p, code=%d", thisfn
, ( void * ) editor
, code
);
410 switch( editor
->private->dialog_code
){
411 case GTK_RESPONSE_CANCEL
:
412 editor
->private->mode
= IMPORTER_MODE_NO_IMPORT
;
416 case GTK_RESPONSE_OK
:
417 get_selected_mode( editor
);
421 case GTK_RESPONSE_NONE
:
422 case GTK_RESPONSE_DELETE_EVENT
:
423 case GTK_RESPONSE_CLOSE
: