Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / libedataserverui / e-source-selector-dialog.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* e-source-selector-dialog.c
3  *
4  * Copyright (C) 2004  Novell, Inc.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * Author: Rodrigo Moya <rodrigo@novell.com>
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <glib/gi18n-lib.h>
29 #include <glib-object.h>
30 #include <gtk/gtkhbox.h>
31 #include <gtk/gtklabel.h>
32 #include <gtk/gtkscrolledwindow.h>
33 #include <gtk/gtkstock.h>
34 #include <gtk/gtktreeview.h>
35 #include <gtk/gtkvbox.h>
36 #include "e-source-selector.h"
37 #include "e-source-selector-dialog.h"
38
39 struct _ESourceSelectorDialogPrivate {
40         GtkWidget *source_selector;
41         ESourceList *source_list;
42         ESource *selected_source;
43 };
44
45 static GObjectClass *parent_class = NULL;
46
47 /* GObject methods */
48
49 G_DEFINE_TYPE (ESourceSelectorDialog, e_source_selector_dialog, GTK_TYPE_DIALOG)
50
51 static void
52 e_source_selector_dialog_dispose (GObject *object)
53 {
54         ESourceSelectorDialogPrivate *priv = E_SOURCE_SELECTOR_DIALOG (object)->priv;
55
56         if (priv->source_list) {
57                 g_object_unref (priv->source_list);
58                 priv->source_list = NULL;
59         }
60
61         if (priv->selected_source) {
62                 g_object_unref (priv->selected_source);
63                 priv->selected_source = NULL;
64         }
65
66         (*G_OBJECT_CLASS (parent_class)->dispose) (object);
67 }
68
69 static void
70 e_source_selector_dialog_finalize (GObject *object)
71 {
72         ESourceSelectorDialogPrivate *priv = E_SOURCE_SELECTOR_DIALOG (object)->priv;
73
74         g_free (priv);
75         E_SOURCE_SELECTOR_DIALOG (object)->priv = NULL;
76
77         (* G_OBJECT_CLASS (parent_class)->finalize) (object);
78 }
79
80 static void
81 e_source_selector_dialog_class_init (ESourceSelectorDialogClass *klass)
82 {
83         GObjectClass *object_class = G_OBJECT_CLASS (klass);
84
85         object_class->dispose = e_source_selector_dialog_dispose;
86         object_class->finalize = e_source_selector_dialog_finalize;
87
88         parent_class = g_type_class_peek_parent (klass);
89 }
90
91 static void
92 e_source_selector_dialog_init (ESourceSelectorDialog *dialog)
93 {
94         ESourceSelectorDialogPrivate *priv;
95
96         priv = g_new0 (ESourceSelectorDialogPrivate, 1);
97         priv->selected_source = NULL;
98         dialog->priv = priv;
99
100         /* prepare the dialog */
101         gtk_window_set_title (GTK_WINDOW (dialog), _("Select destination"));
102         gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 240);
103         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
104         gtk_widget_ensure_style (GTK_WIDGET (dialog));
105         gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0);
106         gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12);
107         gtk_dialog_add_buttons (GTK_DIALOG (dialog),
108                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
109                                 GTK_STOCK_OK, GTK_RESPONSE_OK,
110                                 NULL);
111         gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
112         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
113 }
114
115 /* Public API */
116
117 static void
118 row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path,
119                   GtkTreeViewColumn *column, GtkWidget *dialog)
120 {
121         gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
122 }
123
124 static void
125 primary_selection_changed_cb (ESourceSelector *selector, gpointer user_data)
126 {
127         ESourceSelectorDialog *dialog = user_data;
128         ESourceSelectorDialogPrivate *priv = dialog->priv;
129
130         if (priv->selected_source)
131                 g_object_unref (priv->selected_source);
132         priv->selected_source = e_source_selector_peek_primary_selection (selector);
133         if (priv->selected_source) {
134                 g_object_ref (priv->selected_source);
135                 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE);
136         } else
137                 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
138 }
139
140 static GtkWidget *
141 setup_dialog (GtkWindow *parent, ESourceSelectorDialog *dialog, ESourceList *source_list)
142 {
143         GtkWidget *vbox, *label, *scroll, *hbox, *spacer;
144         char *label_text;
145         ESourceSelectorDialogPrivate *priv = dialog->priv;
146
147         priv->source_list = g_object_ref (source_list);
148
149         vbox = gtk_vbox_new (FALSE, 12);
150         gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
151         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
152         gtk_widget_show (vbox);
153
154         label_text = g_strdup_printf ("<b>%s</b>", _("_Destination"));
155         label = gtk_label_new_with_mnemonic (label_text);
156         gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
157         gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
158         g_free (label_text);
159         gtk_widget_show (label);
160         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
161
162         hbox = gtk_hbox_new (FALSE, 12);
163         gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
164         gtk_widget_show (hbox);
165
166         spacer = gtk_label_new ("");
167         gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
168         gtk_widget_show (spacer);
169
170         scroll = gtk_scrolled_window_new (NULL, NULL);
171         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
172                                         GTK_POLICY_AUTOMATIC,
173                                         GTK_POLICY_AUTOMATIC);
174         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
175                                              GTK_SHADOW_IN);
176         gtk_widget_show (scroll);
177         priv->source_selector = e_source_selector_new (source_list);
178         e_source_selector_show_selection (E_SOURCE_SELECTOR (priv->source_selector), FALSE);
179         g_signal_connect (G_OBJECT (priv->source_selector), "row_activated",
180                           G_CALLBACK (row_activated_cb), dialog);
181         g_signal_connect (G_OBJECT (priv->source_selector), "primary_selection_changed",
182                           G_CALLBACK (primary_selection_changed_cb), dialog);
183         gtk_widget_show (priv->source_selector);
184         gtk_container_add (GTK_CONTAINER (scroll), priv->source_selector);
185         gtk_box_pack_start (GTK_BOX (hbox), scroll, TRUE, TRUE, 0);
186
187         gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->source_selector);
188
189         return GTK_WIDGET (dialog);
190 }
191
192 /**
193  * e_source_selector_dialog_new:
194  * @parent: Parent window.
195  * @source_list: A source list.
196  *
197  * Create a new source selector dialog for the given @list.
198  *
199  * Return value: The newly created widget.
200  */
201 GtkWidget *
202 e_source_selector_dialog_new (GtkWindow *parent, ESourceList *source_list)
203 {
204         ESourceSelectorDialog *dialog;
205
206         g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
207
208         dialog = g_object_new (E_TYPE_SOURCE_SELECTOR_DIALOG, NULL);
209
210         return setup_dialog (parent, dialog, source_list);
211 }
212
213 /**
214  * e_source_selector_dialog_peek_primary_selection:
215  * @dialog: An #ESourceSelectorDialog widget.
216  *
217  * Peek the currently selected source in the given @dialog.
218  *
219  * Return value: the selected ESource.
220  */
221 ESource *
222 e_source_selector_dialog_peek_primary_selection (ESourceSelectorDialog *dialog)
223 {
224         ESourceSelectorDialogPrivate *priv;
225
226         g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
227
228         priv = dialog->priv;
229         return priv->selected_source;
230 }