Convert NASettings to a private singleton
[nautilus-actions.git] / src / core / na-importer-ask.c
blobeb4aad9930940226c2275ffefcef1cf4a8696f80
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 <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"
44 /* private class data
46 struct _NAImporterAskClassPrivate {
47 void *empty; /* so that gcc -pedantic is happy */
50 /* private instance data
52 struct _NAImporterAskPrivate {
53 gboolean dispose_has_run;
54 GtkBuilder *builder;
55 GtkWindow *toplevel;
56 NAObjectItem *importing;
57 NAObjectItem *existing;
58 NAImporterAskUserParms *parms;
59 guint mode;
60 gint dialog_code;
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 );
79 GType
80 na_importer_ask_get_type( void )
82 static GType dialog_type = 0;
84 if( !dialog_type ){
85 dialog_type = register_type();
88 return( dialog_type );
91 static GType
92 register_type( void )
94 static const gchar *thisfn = "na_importer_ask_register_type";
95 GType type;
97 static GTypeInfo info = {
98 sizeof( NAImporterAskClass ),
99 ( GBaseInitFunc ) NULL,
100 ( GBaseFinalizeFunc ) NULL,
101 ( GClassInitFunc ) class_init,
102 NULL,
103 NULL,
104 sizeof( NAImporterAsk ),
106 ( GInstanceInitFunc ) instance_init
109 g_debug( "%s", thisfn );
111 type = g_type_register_static( GTK_TYPE_DIALOG, "NAImporterAsk", &info, 0 );
113 return( type );
116 static void
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 );
133 static void
134 instance_init( GTypeInstance *instance, gpointer klass )
136 static const gchar *thisfn = "na_importer_ask_instance_init";
137 NAImporterAsk *self;
138 GError *error;
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();
151 error = NULL;
152 gtk_builder_add_from_file( self->private->builder, PKGDATADIR "/na-importer-ask.ui", &error );
153 if( error ){
154 g_warning( "%s: %s", thisfn, error->message );
155 g_error_free( error );
157 } else {
158 self->private->toplevel = GTK_WINDOW( gtk_builder_get_object( self->private->builder, "ImporterAskDialog" ));
161 self->private->dispose_has_run = FALSE;
164 static void
165 instance_dispose( GObject *dialog )
167 static const gchar *thisfn = "na_importer_ask_instance_dispose";
168 NAImporterAsk *self;
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 );
189 static void
190 instance_finalize( GObject *dialog )
192 static const gchar *thisfn = "na_importer_ask_instance_finalize";
193 NAImporterAsk *self;
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 *
213 import_ask_new()
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.
232 guint
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;
237 guint mode;
238 gint code;
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" );*/
260 do {
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 ));
269 } else {
270 g_object_unref( dialog );
273 return( mode );
276 static void
277 init_dialog( NAImporterAsk *editor )
279 static const gchar *thisfn = "na_importer_ask_init_dialog";
280 gchar *imported_label, *existing_label;
281 gchar *label;
282 GtkWidget *widget;
283 GtkWidget *button;
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 );
298 } else {
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 );
307 g_free( 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" );
312 break;
314 case IMPORTER_MODE_OVERRIDE:
315 button = na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor->private->toplevel ), "AskOverrideButton" );
316 break;
318 case IMPORTER_MODE_NO_IMPORT:
319 default:
320 button = na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor->private->toplevel ), "AskNoImportButton" );
321 break;
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" );
329 g_signal_connect(
330 G_OBJECT( button ),
331 "clicked",
332 G_CALLBACK( on_ok_clicked ),
333 editor );
335 button = na_gtk_utils_search_for_child_widget( GTK_CONTAINER( editor->private->toplevel ), "CancelButton" );
336 g_signal_connect(
337 G_OBJECT( button ),
338 "clicked",
339 G_CALLBACK( on_cancel_clicked ),
340 editor );
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 ));
349 static void
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 );
359 static void
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 );
369 static void
370 get_selected_mode( NAImporterAsk *editor )
372 guint import_mode;
373 GtkWidget *button;
374 gboolean keep;
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;
382 } else {
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 !
401 static gboolean
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;
413 return( TRUE );
414 break;
416 case GTK_RESPONSE_OK:
417 get_selected_mode( editor );
418 return( TRUE );
419 break;
421 case GTK_RESPONSE_NONE:
422 case GTK_RESPONSE_DELETE_EVENT:
423 case GTK_RESPONSE_CLOSE:
424 break;
427 return( FALSE );