1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* GTK - The GIMP Toolkit
3
* Copyright (C) Christian Kellner <gicmo@gnome.org>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
22
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23
* file for a list of people on the GTK+ Team. See the ChangeLog
24
* files for a list of changes. These files are distributed with
25
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30
#include <glib/gi18n.h>
33
#include "ev-mount-operation.h"
35
/* GObject, GtkObject methods
37
static void ev_mount_operation_set_property (GObject *object,
41
static void ev_mount_operation_get_property (GObject *object,
45
static void ev_mount_operation_finalize (GObject *object);
47
/* GMountOperation methods
49
static void ev_mount_operation_ask_password (GMountOperation *op,
51
const char *default_user,
52
const char *default_domain,
53
GAskPasswordFlags flags);
55
static void ev_mount_operation_ask_question (GMountOperation *op,
57
const char *choices[]);
59
G_DEFINE_TYPE (EvMountOperation, ev_mount_operation, G_TYPE_MOUNT_OPERATION);
69
struct EvMountOperationPrivate {
70
GtkWindow *parent_window;
74
/* for the ask-password dialog */
75
GtkWidget *entry_container;
76
GtkWidget *username_entry;
77
GtkWidget *domain_entry;
78
GtkWidget *password_entry;
79
GtkWidget *anonymous_toggle;
81
GAskPasswordFlags ask_flags;
82
GPasswordSave password_save;
87
ev_mount_operation_finalize (GObject *object)
89
EvMountOperation *operation;
90
EvMountOperationPrivate *priv;
92
operation = EV_MOUNT_OPERATION (object);
94
priv = operation->priv;
96
if (priv->parent_window)
97
g_object_unref (priv->parent_window);
100
g_object_unref (priv->screen);
102
G_OBJECT_CLASS (ev_mount_operation_parent_class)->finalize (object);
106
ev_mount_operation_class_init (EvMountOperationClass *klass)
108
GObjectClass *object_class = G_OBJECT_CLASS (klass);
109
GMountOperationClass *mount_op_class;
111
g_type_class_add_private (klass, sizeof (EvMountOperationPrivate));
113
object_class->finalize = ev_mount_operation_finalize;
114
object_class->get_property = ev_mount_operation_get_property;
115
object_class->set_property = ev_mount_operation_set_property;
117
mount_op_class = G_MOUNT_OPERATION_CLASS (klass);
118
mount_op_class->ask_password = ev_mount_operation_ask_password;
119
mount_op_class->ask_question = ev_mount_operation_ask_question;
121
g_object_class_install_property (object_class,
123
g_param_spec_object ("parent",
129
g_object_class_install_property (object_class,
131
g_param_spec_boolean ("is-showing",
133
"Are we showing a dialog",
137
g_object_class_install_property (object_class,
139
g_param_spec_object ("screen",
141
"The screen where this window will be displayed.",
148
ev_mount_operation_set_property (GObject *object,
153
EvMountOperation *operation;
156
operation = EV_MOUNT_OPERATION (object);
161
tmp = g_value_get_object (value);
162
ev_mount_operation_set_parent (operation, tmp);
166
tmp = g_value_get_object (value);
167
ev_mount_operation_set_screen (operation, tmp);
170
case PROP_IS_SHOWING:
172
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
178
ev_mount_operation_get_property (GObject *object,
183
EvMountOperationPrivate *priv;
184
EvMountOperation *operation;
186
operation = EV_MOUNT_OPERATION (object);
187
priv = operation->priv;
192
g_value_set_object (value, priv->parent_window);
195
case PROP_IS_SHOWING:
196
g_value_set_boolean (value, priv->dialog != NULL);
200
g_value_set_object (value, priv->screen);
204
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
210
ev_mount_operation_init (EvMountOperation *operation)
212
operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
213
EV_TYPE_MOUNT_OPERATION,
214
EvMountOperationPrivate);
218
remember_button_toggled (GtkWidget *widget,
219
EvMountOperation *operation)
221
EvMountOperationPrivate *priv = operation->priv;
224
data = g_object_get_data (G_OBJECT (widget), "password-save");
225
priv->password_save = GPOINTER_TO_INT (data);
229
pw_dialog_got_response (GtkDialog *dialog,
231
EvMountOperation *mount_op)
233
EvMountOperationPrivate *priv;
236
priv = mount_op->priv;
237
op = G_MOUNT_OPERATION (mount_op);
239
if (response_id == GTK_RESPONSE_OK)
243
if (priv->ask_flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED)
244
g_mount_operation_set_anonymous (op, priv->anonymous);
246
if (priv->username_entry)
248
text = gtk_entry_get_text (GTK_ENTRY (priv->username_entry));
249
g_mount_operation_set_username (op, text);
252
if (priv->domain_entry)
254
text = gtk_entry_get_text (GTK_ENTRY (priv->domain_entry));
255
g_mount_operation_set_domain (op, text);
258
if (priv->password_entry)
260
text = gtk_entry_get_text (GTK_ENTRY (priv->password_entry));
261
g_mount_operation_set_password (op, text);
264
if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
265
g_mount_operation_set_password_save (op, priv->password_save);
267
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
270
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
273
g_object_notify (G_OBJECT (op), "is-showing");
274
gtk_widget_destroy (GTK_WIDGET (dialog));
279
entry_has_input (GtkWidget *entry_widget)
283
if (entry_widget == NULL)
286
text = gtk_entry_get_text (GTK_ENTRY (entry_widget));
288
return text != NULL && text[0] != '\0';
292
pw_dialog_input_is_valid (EvMountOperation *operation)
294
EvMountOperationPrivate *priv = operation->priv;
295
gboolean is_valid = TRUE;
297
is_valid = entry_has_input (priv->username_entry) &&
298
entry_has_input (priv->domain_entry) &&
299
entry_has_input (priv->password_entry);
305
pw_dialog_verify_input (GtkEditable *editable,
306
EvMountOperation *operation)
308
EvMountOperationPrivate *priv = operation->priv;
311
is_valid = pw_dialog_input_is_valid (operation);
312
gtk_dialog_set_response_sensitive (GTK_DIALOG (priv->dialog),
318
pw_dialog_anonymous_toggled (GtkWidget *widget,
319
EvMountOperation *operation)
321
EvMountOperationPrivate *priv = operation->priv;
324
priv->anonymous = widget == priv->anonymous_toggle;
329
is_valid = pw_dialog_input_is_valid (operation);
331
gtk_widget_set_sensitive (priv->entry_container, priv->anonymous == FALSE);
332
gtk_dialog_set_response_sensitive (GTK_DIALOG (priv->dialog),
339
pw_dialog_cycle_focus (GtkWidget *widget,
340
EvMountOperation *operation)
342
EvMountOperationPrivate *priv;
343
GtkWidget *next_widget = NULL;
345
priv = operation->priv;
347
if (widget == priv->username_entry)
349
if (priv->domain_entry != NULL)
350
next_widget = priv->domain_entry;
351
else if (priv->password_entry != NULL)
352
next_widget = priv->password_entry;
354
else if (widget == priv->domain_entry && priv->password_entry)
355
next_widget = priv->password_entry;
358
gtk_widget_grab_focus (next_widget);
359
else if (pw_dialog_input_is_valid (operation))
360
gtk_window_activate_default (GTK_WINDOW (priv->dialog));
364
table_add_entry (GtkWidget *table,
366
const char *label_text,
373
label = gtk_label_new_with_mnemonic (label_text);
374
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
376
entry = gtk_entry_new ();
379
gtk_entry_set_text (GTK_ENTRY (entry), value);
381
gtk_table_attach (GTK_TABLE (table), label,
383
GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
384
gtk_table_attach_defaults (GTK_TABLE (table), entry,
386
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
388
g_signal_connect (entry, "changed",
389
G_CALLBACK (pw_dialog_verify_input), user_data);
391
g_signal_connect (entry, "activate",
392
G_CALLBACK (pw_dialog_cycle_focus), user_data);
398
ev_mount_operation_ask_password (GMountOperation *mount_op,
400
const char *default_user,
401
const char *default_domain,
402
GAskPasswordFlags flags)
404
EvMountOperation *operation;
405
EvMountOperationPrivate *priv;
409
GtkWidget *entry_container;
410
GtkWidget *hbox, *main_vbox, *vbox, *icon;
412
GtkWidget *message_label;
413
gboolean can_anonymous;
416
operation = EV_MOUNT_OPERATION (mount_op);
417
priv = operation->priv;
419
priv->ask_flags = flags;
421
widget = gtk_dialog_new ();
422
dialog = GTK_DIALOG (widget);
423
window = GTK_WINDOW (widget);
425
priv->dialog = dialog;
427
/* Set the dialog up with HIG properties */
428
gtk_dialog_set_has_separator (dialog, FALSE);
429
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
430
gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* 2 * 5 + 2 = 12 */
431
gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
432
gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
434
gtk_window_set_resizable (window, FALSE);
435
gtk_window_set_icon_name (window, GTK_STOCK_DIALOG_AUTHENTICATION);
437
gtk_dialog_add_buttons (dialog,
438
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
439
_("Co_nnect"), GTK_RESPONSE_OK,
441
gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
443
gtk_dialog_set_alternative_button_order (dialog,
449
hbox = gtk_hbox_new (FALSE, 12);
450
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
451
gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0);
453
icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
454
GTK_ICON_SIZE_DIALOG);
456
gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0.0);
457
gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
459
main_vbox = gtk_vbox_new (FALSE, 18);
460
gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
462
message_label = gtk_label_new (message);
463
gtk_misc_set_alignment (GTK_MISC (message_label), 0.0, 0.5);
464
gtk_label_set_line_wrap (GTK_LABEL (message_label), TRUE);
465
gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (message_label),
468
vbox = gtk_vbox_new (FALSE, 6);
469
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
471
can_anonymous = flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
479
anon_box = gtk_vbox_new (FALSE, 6);
480
gtk_box_pack_start (GTK_BOX (vbox), anon_box,
483
choice = gtk_radio_button_new_with_mnemonic (NULL, _("Connect _anonymously"));
484
gtk_box_pack_start (GTK_BOX (anon_box),
487
g_signal_connect (choice, "toggled",
488
G_CALLBACK (pw_dialog_anonymous_toggled), operation);
489
priv->anonymous_toggle = choice;
491
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
492
choice = gtk_radio_button_new_with_mnemonic (group, _("Connect as u_ser:"));
493
gtk_box_pack_start (GTK_BOX (anon_box),
496
g_signal_connect (choice, "toggled",
497
G_CALLBACK (pw_dialog_anonymous_toggled), operation);
502
if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
505
if (flags & G_ASK_PASSWORD_NEED_USERNAME)
508
if (flags &G_ASK_PASSWORD_NEED_DOMAIN)
511
/* The table that holds the entries */
512
entry_container = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
514
gtk_alignment_set_padding (GTK_ALIGNMENT (entry_container),
515
0, 0, can_anonymous ? 12 : 0, 0);
517
gtk_box_pack_start (GTK_BOX (vbox), entry_container,
519
priv->entry_container = entry_container;
521
table = gtk_table_new (rows, 2, FALSE);
522
gtk_table_set_col_spacings (GTK_TABLE (table), 12);
523
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
524
gtk_container_add (GTK_CONTAINER (entry_container), table);
528
if (flags & G_ASK_PASSWORD_NEED_USERNAME)
529
priv->username_entry = table_add_entry (table, rows++, _("_Username:"),
530
default_user, operation);
532
if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
533
priv->domain_entry = table_add_entry (table, rows++, _("_Domain:"),
534
default_domain, operation);
536
if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
538
priv->password_entry = table_add_entry (table, rows++, _("_Password:"),
540
gtk_entry_set_visibility (GTK_ENTRY (priv->password_entry), FALSE);
543
if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
546
GtkWidget *remember_box;
549
remember_box = gtk_vbox_new (FALSE, 6);
550
gtk_box_pack_start (GTK_BOX (vbox), remember_box,
553
choice = gtk_radio_button_new_with_mnemonic (NULL, _("_Forget password immediately"));
554
g_object_set_data (G_OBJECT (choice), "password-save",
555
GINT_TO_POINTER (G_PASSWORD_SAVE_NEVER));
556
g_signal_connect (choice, "toggled",
557
G_CALLBACK (remember_button_toggled), operation);
558
gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
560
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
561
choice = gtk_radio_button_new_with_mnemonic (group, _("_Remember password until you logout"));
562
g_object_set_data (G_OBJECT (choice), "password-save",
563
GINT_TO_POINTER (G_PASSWORD_SAVE_FOR_SESSION));
564
g_signal_connect (choice, "toggled",
565
G_CALLBACK (remember_button_toggled), operation);
566
gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
568
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
569
choice = gtk_radio_button_new_with_mnemonic (group, _("_Remember forever"));
570
g_object_set_data (G_OBJECT (choice), "password-save",
571
GINT_TO_POINTER (G_PASSWORD_SAVE_PERMANENTLY));
572
g_signal_connect (choice, "toggled",
573
G_CALLBACK (remember_button_toggled), operation);
574
gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
577
g_signal_connect (G_OBJECT (dialog), "response",
578
G_CALLBACK (pw_dialog_got_response), operation);
582
/* The anonymous option will be active by default,
583
* ensure the toggled signal is emitted for it.
585
gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (priv->anonymous_toggle));
587
else if (! pw_dialog_input_is_valid (operation))
588
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE);
590
g_object_notify (G_OBJECT (operation), "is-showing");
592
if (priv->parent_window)
594
gtk_window_set_transient_for (window, priv->parent_window);
595
gtk_window_set_modal (window, TRUE);
597
else if (priv->screen)
598
gtk_window_set_screen (GTK_WINDOW (dialog), priv->screen);
600
gtk_widget_show_all (GTK_WIDGET (dialog));
602
g_object_ref (operation);
606
question_dialog_button_clicked (GtkDialog *dialog,
610
EvMountOperationPrivate *priv;
611
EvMountOperation *operation;
613
operation = EV_MOUNT_OPERATION (op);
614
priv = operation->priv;
616
if (button_number >= 0)
618
g_mount_operation_set_choice (op, button_number);
619
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
622
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
625
g_object_notify (G_OBJECT (operation), "is-showing");
626
gtk_widget_destroy (GTK_WIDGET (dialog));
631
ev_mount_operation_ask_question (GMountOperation *op,
633
const char *choices[])
635
EvMountOperationPrivate *priv;
637
const char *secondary = NULL;
641
g_return_if_fail (EV_IS_MOUNT_OPERATION (op));
642
g_return_if_fail (message != NULL);
643
g_return_if_fail (choices != NULL);
645
priv = EV_MOUNT_OPERATION (op)->priv;
647
primary = strstr (message, "\n");
650
secondary = primary + 1;
651
primary = g_strndup (message, primary - message);
654
dialog = gtk_message_dialog_new (priv->parent_window, 0,
655
GTK_MESSAGE_QUESTION,
656
GTK_BUTTONS_NONE, "%s",
657
primary != NULL ? primary : message);
661
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
664
/* First count the items in the list then
665
* add the buttons in reverse order */
667
while (choices[len] != NULL)
670
for (count = len - 1; count >= 0; count--)
671
gtk_dialog_add_button (GTK_DIALOG (dialog), choices[count], count);
673
g_signal_connect (G_OBJECT (dialog), "response",
674
G_CALLBACK (question_dialog_button_clicked), op);
676
priv->dialog = GTK_DIALOG (dialog);
677
g_object_notify (G_OBJECT (op), "is-showing");
679
if (priv->parent_window == NULL && priv->screen)
680
gtk_window_set_screen (GTK_WINDOW (dialog), priv->screen);
682
gtk_widget_show (dialog);
687
ev_mount_operation_new (GtkWindow *parent)
689
GMountOperation *mount_operation;
691
mount_operation = g_object_new (EV_TYPE_MOUNT_OPERATION,
692
"parent", parent, NULL);
694
return mount_operation;
698
ev_mount_operation_is_showing (EvMountOperation *op)
700
g_return_val_if_fail (EV_IS_MOUNT_OPERATION (op), FALSE);
702
return op->priv->dialog != NULL;
706
ev_mount_operation_set_parent (EvMountOperation *op,
709
EvMountOperationPrivate *priv;
711
g_return_if_fail (EV_IS_MOUNT_OPERATION (op));
712
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
716
if (priv->parent_window == parent)
719
if (priv->parent_window)
721
g_signal_handlers_disconnect_by_func (priv->parent_window,
722
gtk_widget_destroyed,
723
&priv->parent_window);
724
priv->parent_window = NULL;
729
priv->parent_window = g_object_ref (parent);
731
g_signal_connect (parent, "destroy",
732
G_CALLBACK (gtk_widget_destroyed),
733
&priv->parent_window);
736
gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), parent);
739
g_object_notify (G_OBJECT (op), "parent");
743
ev_mount_operation_get_parent (EvMountOperation *op)
745
g_return_val_if_fail (EV_IS_MOUNT_OPERATION (op), NULL);
747
return op->priv->parent_window;
751
ev_mount_operation_set_screen (EvMountOperation *op,
754
EvMountOperationPrivate *priv;
756
g_return_if_fail (EV_IS_MOUNT_OPERATION (op));
757
g_return_if_fail (GDK_IS_SCREEN (screen));
761
if (priv->screen == screen)
765
g_object_unref (priv->screen);
767
priv->screen = g_object_ref (screen);
770
gtk_window_set_screen (GTK_WINDOW (priv->dialog), screen);
772
g_object_notify (G_OBJECT (op), "screen");
776
ev_mount_operation_get_screen (EvMountOperation *op)
778
EvMountOperationPrivate *priv;
780
g_return_val_if_fail (EV_IS_MOUNT_OPERATION (op), NULL);
785
return gtk_window_get_screen (GTK_WINDOW (priv->dialog));
786
else if (priv->parent_window)
787
return gtk_window_get_screen (GTK_WINDOW (priv->parent_window));
788
else if (priv->screen)
791
return gdk_screen_get_default ();