Assamese translation updated
[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) 1999-2008 Novell, Inc. (www.novell.com)
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 "e-source-selector.h"
30 #include "e-source-selector-dialog.h"
31
32 #define E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE(obj) \
33         (G_TYPE_INSTANCE_GET_PRIVATE \
34         ((obj), E_TYPE_SOURCE_SELECTOR_DIALOG, ESourceSelectorDialogPrivate))
35
36 struct _ESourceSelectorDialogPrivate {
37         GtkWidget *selector;
38         ESourceRegistry *registry;
39         ESource *selected_source;
40         gchar *extension_name;
41 };
42
43 enum {
44         PROP_0,
45         PROP_EXTENSION_NAME,
46         PROP_REGISTRY,
47         PROP_SELECTOR
48 };
49
50 G_DEFINE_TYPE (
51         ESourceSelectorDialog,
52         e_source_selector_dialog,
53         GTK_TYPE_DIALOG)
54
55 static void
56 source_selector_dialog_row_activated_cb (GtkTreeView *tree_view,
57                                          GtkTreePath *path,
58                                          GtkTreeViewColumn *column,
59                                          GtkWidget *dialog)
60 {
61         gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
62 }
63
64 static void
65 primary_selection_changed_cb (ESourceSelector *selector,
66                               ESourceSelectorDialog *dialog)
67 {
68         ESourceSelectorDialogPrivate *priv = dialog->priv;
69
70         if (priv->selected_source != NULL)
71                 g_object_unref (priv->selected_source);
72         priv->selected_source =
73                 e_source_selector_ref_primary_selection (selector);
74
75         /* FIXME Add an API for "except-source" or to
76          *       get the ESourceSelector from outside. */
77         if (priv->selected_source != NULL) {
78                 ESource *except_source;
79
80                 except_source = g_object_get_data (
81                         G_OBJECT (dialog), "except-source");
82
83                 if (except_source != NULL)
84                         if (e_source_equal (except_source, priv->selected_source)) {
85                                 g_object_unref (priv->selected_source);
86                                 priv->selected_source = NULL;
87                         }
88         }
89
90         gtk_dialog_set_response_sensitive (
91                 GTK_DIALOG (dialog), GTK_RESPONSE_OK,
92                 (priv->selected_source != NULL));
93 }
94
95 static void
96 source_selector_dialog_set_extension_name (ESourceSelectorDialog *dialog,
97                                            const gchar *extension_name)
98 {
99         g_return_if_fail (extension_name != NULL);
100         g_return_if_fail (dialog->priv->extension_name == NULL);
101
102         dialog->priv->extension_name = g_strdup (extension_name);
103 }
104
105 static void
106 source_selector_dialog_set_registry (ESourceSelectorDialog *dialog,
107                                      ESourceRegistry *registry)
108 {
109         g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
110         g_return_if_fail (dialog->priv->registry == NULL);
111
112         dialog->priv->registry = g_object_ref (registry);
113 }
114
115 static void
116 source_selector_dialog_set_property (GObject *object,
117                                      guint property_id,
118                                      const GValue *value,
119                                      GParamSpec *pspec)
120 {
121         switch (property_id) {
122                 case PROP_EXTENSION_NAME:
123                         source_selector_dialog_set_extension_name (
124                                 E_SOURCE_SELECTOR_DIALOG (object),
125                                 g_value_get_string (value));
126                         return;
127
128                 case PROP_REGISTRY:
129                         source_selector_dialog_set_registry (
130                                 E_SOURCE_SELECTOR_DIALOG (object),
131                                 g_value_get_object (value));
132                         return;
133         }
134
135         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
136 }
137
138 static void
139 source_selector_dialog_get_property (GObject *object,
140                                      guint property_id,
141                                      GValue *value,
142                                      GParamSpec *pspec)
143 {
144         switch (property_id) {
145                 case PROP_EXTENSION_NAME:
146                         g_value_set_string (
147                                 value,
148                                 e_source_selector_dialog_get_extension_name (
149                                 E_SOURCE_SELECTOR_DIALOG (object)));
150                         return;
151
152                 case PROP_REGISTRY:
153                         g_value_set_object (
154                                 value,
155                                 e_source_selector_dialog_get_registry (
156                                 E_SOURCE_SELECTOR_DIALOG (object)));
157                         return;
158
159                 case PROP_SELECTOR:
160                         g_value_set_object (
161                                 value,
162                                 e_source_selector_dialog_get_selector (
163                                 E_SOURCE_SELECTOR_DIALOG (object)));
164                         return;
165         }
166
167         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
168 }
169
170 static void
171 source_selector_dialog_dispose (GObject *object)
172 {
173         ESourceSelectorDialogPrivate *priv;
174
175         priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (object);
176
177         if (priv->registry != NULL) {
178                 g_object_unref (priv->registry);
179                 priv->registry = NULL;
180         }
181
182         if (priv->selected_source != NULL) {
183                 g_object_unref (priv->selected_source);
184                 priv->selected_source = NULL;
185         }
186
187         /* Chain up to parent's dispose() method. */
188         G_OBJECT_CLASS (e_source_selector_dialog_parent_class)->dispose (object);
189 }
190
191 static void
192 source_selector_dialog_finalize (GObject *object)
193 {
194         ESourceSelectorDialogPrivate *priv;
195
196         priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (object);
197
198         g_free (priv->extension_name);
199
200         /* Chain up to parent's finalize() method. */
201         G_OBJECT_CLASS (e_source_selector_dialog_parent_class)->finalize (object);
202 }
203
204 static void
205 source_selector_dialog_constructed (GObject *object)
206 {
207         ESourceSelectorDialog *dialog;
208         GtkWidget *label, *hgrid;
209         GtkWidget *container;
210         GtkWidget *widget;
211         gchar *label_text;
212
213         dialog = E_SOURCE_SELECTOR_DIALOG (object);
214
215         container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
216
217         widget = g_object_new (GTK_TYPE_GRID,
218                 "orientation", GTK_ORIENTATION_VERTICAL,
219                 "column-homogeneous", FALSE,
220                 "row-spacing", 12,
221                 NULL);
222         gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
223         gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
224         gtk_widget_show (widget);
225
226         container = widget;
227
228         label_text = g_strdup_printf ("<b>%s</b>", _("_Destination"));
229         label = gtk_label_new_with_mnemonic (label_text);
230         gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
231         gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
232         gtk_container_add (GTK_CONTAINER (container), label);
233         gtk_widget_show (label);
234         g_free (label_text);
235
236         hgrid = g_object_new (GTK_TYPE_GRID,
237                 "orientation", GTK_ORIENTATION_HORIZONTAL,
238                 "row-homogeneous", FALSE,
239                 "column-spacing", 12,
240                 "vexpand", TRUE,
241                 "valign", GTK_ALIGN_FILL,
242                 NULL);
243         gtk_container_add (GTK_CONTAINER (container), hgrid);
244         gtk_widget_show (hgrid);
245
246         widget = gtk_label_new ("");
247         gtk_container_add (GTK_CONTAINER (hgrid), widget);
248         gtk_widget_show (widget);
249
250         widget = gtk_scrolled_window_new (NULL, NULL);
251         gtk_scrolled_window_set_policy (
252                 GTK_SCROLLED_WINDOW (widget),
253                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
254         gtk_scrolled_window_set_shadow_type (
255                 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
256         gtk_widget_set_hexpand (widget, TRUE);
257         gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
258         gtk_widget_set_vexpand (widget, TRUE);
259         gtk_widget_set_valign (widget, GTK_ALIGN_FILL);
260         gtk_container_add (GTK_CONTAINER (hgrid), widget);
261         gtk_widget_show (widget);
262
263         container = widget;
264
265         widget = e_source_selector_new (
266                 dialog->priv->registry,
267                 dialog->priv->extension_name);
268         e_source_selector_set_show_toggles (E_SOURCE_SELECTOR (widget), FALSE);
269         gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
270         gtk_container_add (GTK_CONTAINER (container), widget);
271         dialog->priv->selector = widget;
272         gtk_widget_show (widget);
273
274         g_signal_connect (
275                 widget, "row_activated",
276                 G_CALLBACK (source_selector_dialog_row_activated_cb), dialog);
277         g_signal_connect (
278                 widget, "primary_selection_changed",
279                 G_CALLBACK (primary_selection_changed_cb), dialog);
280 }
281
282 static void
283 e_source_selector_dialog_class_init (ESourceSelectorDialogClass *class)
284 {
285         GObjectClass *object_class;
286
287         g_type_class_add_private (class, sizeof (ESourceSelectorDialogPrivate));
288
289         object_class = G_OBJECT_CLASS (class);
290         object_class->set_property = source_selector_dialog_set_property;
291         object_class->get_property = source_selector_dialog_get_property;
292         object_class->dispose = source_selector_dialog_dispose;
293         object_class->finalize = source_selector_dialog_finalize;
294         object_class->constructed = source_selector_dialog_constructed;
295
296         g_object_class_install_property (
297                 object_class,
298                 PROP_EXTENSION_NAME,
299                 g_param_spec_string (
300                         "extension-name",
301                         NULL,
302                         NULL,
303                         NULL,
304                         G_PARAM_WRITABLE |
305                         G_PARAM_CONSTRUCT_ONLY));
306
307         g_object_class_install_property (
308                 object_class,
309                 PROP_REGISTRY,
310                 g_param_spec_object (
311                         "registry",
312                         NULL,
313                         NULL,
314                         E_TYPE_SOURCE_REGISTRY,
315                         G_PARAM_WRITABLE |
316                         G_PARAM_CONSTRUCT_ONLY));
317
318         g_object_class_install_property (
319                 object_class,
320                 PROP_SELECTOR,
321                 g_param_spec_object (
322                         "selector",
323                         NULL,
324                         NULL,
325                         E_TYPE_SOURCE_SELECTOR,
326                         G_PARAM_READABLE));
327 }
328
329 static void
330 e_source_selector_dialog_init (ESourceSelectorDialog *dialog)
331 {
332         GtkWidget *action_area;
333         GtkWidget *content_area;
334
335         dialog->priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (dialog);
336
337         action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
338         content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
339
340         gtk_window_set_title (GTK_WINDOW (dialog), _("Select destination"));
341         gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 240);
342
343         gtk_widget_ensure_style (GTK_WIDGET (dialog));
344         gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
345         gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
346
347         gtk_dialog_add_buttons (
348                 GTK_DIALOG (dialog),
349                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
350                 GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
351         gtk_dialog_set_default_response (
352                 GTK_DIALOG (dialog), GTK_RESPONSE_OK);
353         gtk_dialog_set_response_sensitive (
354                 GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
355 }
356
357 /**
358  * e_source_selector_dialog_new:
359  * @parent: a parent window
360  * @registry: an #ESourceRegistry
361  * @extension_name: the name of an #ESource extension
362  *
363  * Displays a list of sources from @registry having an extension named
364  * @extension_name in a dialog window.  The sources are grouped by backend
365  * or groupware account, which are described by the parent source.
366  *
367  * Returns: a new #ESourceSelectorDialog
368  **/
369 GtkWidget *
370 e_source_selector_dialog_new (GtkWindow *parent,
371                               ESourceRegistry *registry,
372                               const gchar *extension_name)
373 {
374         g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
375         g_return_val_if_fail (extension_name != NULL, NULL);
376
377         return g_object_new (
378                 E_TYPE_SOURCE_SELECTOR_DIALOG,
379                 "transient-for", parent,
380                 "registry", registry,
381                 "extension-name", extension_name,
382                 NULL);
383 }
384
385 /**
386  * e_source_selector_dialog_get_registry:
387  * @dialog: an #ESourceSelectorDialog
388  *
389  * Returns the #ESourceRegistry passed to e_source_selector_dialog_new().
390  *
391  * Returns: the #ESourceRegistry for @dialog
392  *
393  * Since: 3.6
394  **/
395 ESourceRegistry *
396 e_source_selector_dialog_get_registry (ESourceSelectorDialog *dialog)
397 {
398         g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
399
400         return dialog->priv->registry;
401 }
402
403 /**
404  * e_source_selector_dialog_get_extension_name:
405  * @dialog: an #ESourceSelectorDialog
406  *
407  * Returns the extension name passed to e_source_selector_dialog_new().
408  *
409  * Returns: the extension name for @dialog
410  *
411  * Since: 3.6
412  **/
413 const gchar *
414 e_source_selector_dialog_get_extension_name (ESourceSelectorDialog *dialog)
415 {
416         g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
417
418         return dialog->priv->extension_name;
419 }
420
421 /**
422  * e_source_selector_dialog_get_selector:
423  * @dialog: an #ESourceSelectorDialog
424  *
425  * Returns the #ESourceSelector widget embedded in @dialog.
426  *
427  * Returns: the #ESourceSelector widget
428  *
429  * Since: 3.6
430  **/
431 ESourceSelector *
432 e_source_selector_dialog_get_selector (ESourceSelectorDialog *dialog)
433 {
434         g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
435
436         return E_SOURCE_SELECTOR (dialog->priv->selector);
437 }
438
439 /**
440  * e_source_selector_dialog_peek_primary_selection:
441  * @dialog: an #ESourceSelectorDialog
442  *
443  * Peek the currently selected source in the given @dialog.
444  *
445  * Returns: the selected #ESource
446  */
447 ESource *
448 e_source_selector_dialog_peek_primary_selection (ESourceSelectorDialog *dialog)
449 {
450         g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
451
452         return dialog->priv->selected_source;
453 }