456 lines
12 KiB
C
456 lines
12 KiB
C
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
|
/* e-source-selector-dialog.c
|
|
*
|
|
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
* Author: Rodrigo Moya <rodrigo@novell.com>
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
#include "e-source-selector.h"
|
|
#include "e-source-selector-dialog.h"
|
|
|
|
#define E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE(obj) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE \
|
|
((obj), E_TYPE_SOURCE_SELECTOR_DIALOG, ESourceSelectorDialogPrivate))
|
|
|
|
struct _ESourceSelectorDialogPrivate {
|
|
GtkWidget *selector;
|
|
ESourceRegistry *registry;
|
|
ESource *selected_source;
|
|
gchar *extension_name;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_EXTENSION_NAME,
|
|
PROP_REGISTRY,
|
|
PROP_SELECTOR
|
|
};
|
|
|
|
G_DEFINE_TYPE (
|
|
ESourceSelectorDialog,
|
|
e_source_selector_dialog,
|
|
GTK_TYPE_DIALOG)
|
|
|
|
static void
|
|
source_selector_dialog_row_activated_cb (GtkTreeView *tree_view,
|
|
GtkTreePath *path,
|
|
GtkTreeViewColumn *column,
|
|
GtkWidget *dialog)
|
|
{
|
|
gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
|
}
|
|
|
|
static void
|
|
primary_selection_changed_cb (ESourceSelector *selector,
|
|
ESourceSelectorDialog *dialog)
|
|
{
|
|
ESourceSelectorDialogPrivate *priv = dialog->priv;
|
|
|
|
if (priv->selected_source != NULL)
|
|
g_object_unref (priv->selected_source);
|
|
priv->selected_source =
|
|
e_source_selector_ref_primary_selection (selector);
|
|
|
|
/* FIXME Add an API for "except-source" or to
|
|
* get the ESourceSelector from outside. */
|
|
if (priv->selected_source != NULL) {
|
|
ESource *except_source;
|
|
|
|
except_source = g_object_get_data (
|
|
G_OBJECT (dialog), "except-source");
|
|
|
|
if (except_source != NULL)
|
|
if (e_source_equal (except_source, priv->selected_source)) {
|
|
g_object_unref (priv->selected_source);
|
|
priv->selected_source = NULL;
|
|
}
|
|
}
|
|
|
|
gtk_dialog_set_response_sensitive (
|
|
GTK_DIALOG (dialog), GTK_RESPONSE_OK,
|
|
(priv->selected_source != NULL));
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_set_extension_name (ESourceSelectorDialog *dialog,
|
|
const gchar *extension_name)
|
|
{
|
|
g_return_if_fail (extension_name != NULL);
|
|
g_return_if_fail (dialog->priv->extension_name == NULL);
|
|
|
|
dialog->priv->extension_name = g_strdup (extension_name);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_set_registry (ESourceSelectorDialog *dialog,
|
|
ESourceRegistry *registry)
|
|
{
|
|
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
|
|
g_return_if_fail (dialog->priv->registry == NULL);
|
|
|
|
dialog->priv->registry = g_object_ref (registry);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_EXTENSION_NAME:
|
|
source_selector_dialog_set_extension_name (
|
|
E_SOURCE_SELECTOR_DIALOG (object),
|
|
g_value_get_string (value));
|
|
return;
|
|
|
|
case PROP_REGISTRY:
|
|
source_selector_dialog_set_registry (
|
|
E_SOURCE_SELECTOR_DIALOG (object),
|
|
g_value_get_object (value));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_EXTENSION_NAME:
|
|
g_value_set_string (
|
|
value,
|
|
e_source_selector_dialog_get_extension_name (
|
|
E_SOURCE_SELECTOR_DIALOG (object)));
|
|
return;
|
|
|
|
case PROP_REGISTRY:
|
|
g_value_set_object (
|
|
value,
|
|
e_source_selector_dialog_get_registry (
|
|
E_SOURCE_SELECTOR_DIALOG (object)));
|
|
return;
|
|
|
|
case PROP_SELECTOR:
|
|
g_value_set_object (
|
|
value,
|
|
e_source_selector_dialog_get_selector (
|
|
E_SOURCE_SELECTOR_DIALOG (object)));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_dispose (GObject *object)
|
|
{
|
|
ESourceSelectorDialogPrivate *priv;
|
|
|
|
priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (object);
|
|
|
|
if (priv->registry != NULL) {
|
|
g_object_unref (priv->registry);
|
|
priv->registry = NULL;
|
|
}
|
|
|
|
if (priv->selected_source != NULL) {
|
|
g_object_unref (priv->selected_source);
|
|
priv->selected_source = NULL;
|
|
}
|
|
|
|
/* Chain up to parent's dispose() method. */
|
|
G_OBJECT_CLASS (e_source_selector_dialog_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_finalize (GObject *object)
|
|
{
|
|
ESourceSelectorDialogPrivate *priv;
|
|
|
|
priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (object);
|
|
|
|
g_free (priv->extension_name);
|
|
|
|
/* Chain up to parent's finalize() method. */
|
|
G_OBJECT_CLASS (e_source_selector_dialog_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
source_selector_dialog_constructed (GObject *object)
|
|
{
|
|
ESourceSelectorDialog *dialog;
|
|
GtkWidget *label, *hgrid;
|
|
GtkWidget *container;
|
|
GtkWidget *widget;
|
|
gchar *label_text;
|
|
|
|
dialog = E_SOURCE_SELECTOR_DIALOG (object);
|
|
|
|
container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
|
|
|
widget = g_object_new (
|
|
GTK_TYPE_GRID,
|
|
"orientation", GTK_ORIENTATION_VERTICAL,
|
|
"column-homogeneous", FALSE,
|
|
"row-spacing", 12,
|
|
NULL);
|
|
gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
|
|
gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
|
|
gtk_widget_show (widget);
|
|
|
|
container = widget;
|
|
|
|
label_text = g_strdup_printf ("<b>%s</b>", _("_Destination"));
|
|
label = gtk_label_new_with_mnemonic (label_text);
|
|
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
|
gtk_container_add (GTK_CONTAINER (container), label);
|
|
gtk_widget_show (label);
|
|
g_free (label_text);
|
|
|
|
hgrid = g_object_new (
|
|
GTK_TYPE_GRID,
|
|
"orientation", GTK_ORIENTATION_HORIZONTAL,
|
|
"row-homogeneous", FALSE,
|
|
"column-spacing", 12,
|
|
"vexpand", TRUE,
|
|
"valign", GTK_ALIGN_FILL,
|
|
NULL);
|
|
gtk_container_add (GTK_CONTAINER (container), hgrid);
|
|
gtk_widget_show (hgrid);
|
|
|
|
widget = gtk_label_new ("");
|
|
gtk_container_add (GTK_CONTAINER (hgrid), widget);
|
|
gtk_widget_show (widget);
|
|
|
|
widget = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_scrolled_window_set_policy (
|
|
GTK_SCROLLED_WINDOW (widget),
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
gtk_scrolled_window_set_shadow_type (
|
|
GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
|
|
gtk_widget_set_hexpand (widget, TRUE);
|
|
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
|
|
gtk_widget_set_vexpand (widget, TRUE);
|
|
gtk_widget_set_valign (widget, GTK_ALIGN_FILL);
|
|
gtk_container_add (GTK_CONTAINER (hgrid), widget);
|
|
gtk_widget_show (widget);
|
|
|
|
container = widget;
|
|
|
|
widget = e_source_selector_new (
|
|
dialog->priv->registry,
|
|
dialog->priv->extension_name);
|
|
e_source_selector_set_show_toggles (E_SOURCE_SELECTOR (widget), FALSE);
|
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
|
gtk_container_add (GTK_CONTAINER (container), widget);
|
|
dialog->priv->selector = widget;
|
|
gtk_widget_show (widget);
|
|
|
|
g_signal_connect (
|
|
widget, "row_activated",
|
|
G_CALLBACK (source_selector_dialog_row_activated_cb), dialog);
|
|
g_signal_connect (
|
|
widget, "primary_selection_changed",
|
|
G_CALLBACK (primary_selection_changed_cb), dialog);
|
|
}
|
|
|
|
static void
|
|
e_source_selector_dialog_class_init (ESourceSelectorDialogClass *class)
|
|
{
|
|
GObjectClass *object_class;
|
|
|
|
g_type_class_add_private (class, sizeof (ESourceSelectorDialogPrivate));
|
|
|
|
object_class = G_OBJECT_CLASS (class);
|
|
object_class->set_property = source_selector_dialog_set_property;
|
|
object_class->get_property = source_selector_dialog_get_property;
|
|
object_class->dispose = source_selector_dialog_dispose;
|
|
object_class->finalize = source_selector_dialog_finalize;
|
|
object_class->constructed = source_selector_dialog_constructed;
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_EXTENSION_NAME,
|
|
g_param_spec_string (
|
|
"extension-name",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
G_PARAM_WRITABLE |
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_REGISTRY,
|
|
g_param_spec_object (
|
|
"registry",
|
|
NULL,
|
|
NULL,
|
|
E_TYPE_SOURCE_REGISTRY,
|
|
G_PARAM_WRITABLE |
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_SELECTOR,
|
|
g_param_spec_object (
|
|
"selector",
|
|
NULL,
|
|
NULL,
|
|
E_TYPE_SOURCE_SELECTOR,
|
|
G_PARAM_READABLE));
|
|
}
|
|
|
|
static void
|
|
e_source_selector_dialog_init (ESourceSelectorDialog *dialog)
|
|
{
|
|
GtkWidget *action_area;
|
|
GtkWidget *content_area;
|
|
|
|
dialog->priv = E_SOURCE_SELECTOR_DIALOG_GET_PRIVATE (dialog);
|
|
|
|
action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
|
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
|
|
|
gtk_window_set_title (GTK_WINDOW (dialog), _("Select destination"));
|
|
gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 240);
|
|
|
|
gtk_widget_ensure_style (GTK_WIDGET (dialog));
|
|
gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
|
|
gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
|
|
|
|
gtk_dialog_add_buttons (
|
|
GTK_DIALOG (dialog),
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
|
|
gtk_dialog_set_default_response (
|
|
GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
|
gtk_dialog_set_response_sensitive (
|
|
GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
|
|
}
|
|
|
|
/**
|
|
* e_source_selector_dialog_new:
|
|
* @parent: a parent window
|
|
* @registry: an #ESourceRegistry
|
|
* @extension_name: the name of an #ESource extension
|
|
*
|
|
* Displays a list of sources from @registry having an extension named
|
|
* @extension_name in a dialog window. The sources are grouped by backend
|
|
* or groupware account, which are described by the parent source.
|
|
*
|
|
* Returns: a new #ESourceSelectorDialog
|
|
**/
|
|
GtkWidget *
|
|
e_source_selector_dialog_new (GtkWindow *parent,
|
|
ESourceRegistry *registry,
|
|
const gchar *extension_name)
|
|
{
|
|
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
|
|
g_return_val_if_fail (extension_name != NULL, NULL);
|
|
|
|
return g_object_new (
|
|
E_TYPE_SOURCE_SELECTOR_DIALOG,
|
|
"transient-for", parent,
|
|
"registry", registry,
|
|
"extension-name", extension_name,
|
|
NULL);
|
|
}
|
|
|
|
/**
|
|
* e_source_selector_dialog_get_registry:
|
|
* @dialog: an #ESourceSelectorDialog
|
|
*
|
|
* Returns the #ESourceRegistry passed to e_source_selector_dialog_new().
|
|
*
|
|
* Returns: the #ESourceRegistry for @dialog
|
|
*
|
|
* Since: 3.6
|
|
**/
|
|
ESourceRegistry *
|
|
e_source_selector_dialog_get_registry (ESourceSelectorDialog *dialog)
|
|
{
|
|
g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
|
|
|
|
return dialog->priv->registry;
|
|
}
|
|
|
|
/**
|
|
* e_source_selector_dialog_get_extension_name:
|
|
* @dialog: an #ESourceSelectorDialog
|
|
*
|
|
* Returns the extension name passed to e_source_selector_dialog_new().
|
|
*
|
|
* Returns: the extension name for @dialog
|
|
*
|
|
* Since: 3.6
|
|
**/
|
|
const gchar *
|
|
e_source_selector_dialog_get_extension_name (ESourceSelectorDialog *dialog)
|
|
{
|
|
g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
|
|
|
|
return dialog->priv->extension_name;
|
|
}
|
|
|
|
/**
|
|
* e_source_selector_dialog_get_selector:
|
|
* @dialog: an #ESourceSelectorDialog
|
|
*
|
|
* Returns the #ESourceSelector widget embedded in @dialog.
|
|
*
|
|
* Returns: the #ESourceSelector widget
|
|
*
|
|
* Since: 3.6
|
|
**/
|
|
ESourceSelector *
|
|
e_source_selector_dialog_get_selector (ESourceSelectorDialog *dialog)
|
|
{
|
|
g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
|
|
|
|
return E_SOURCE_SELECTOR (dialog->priv->selector);
|
|
}
|
|
|
|
/**
|
|
* e_source_selector_dialog_peek_primary_selection:
|
|
* @dialog: an #ESourceSelectorDialog
|
|
*
|
|
* Peek the currently selected source in the given @dialog.
|
|
*
|
|
* Returns: the selected #ESource
|
|
*/
|
|
ESource *
|
|
e_source_selector_dialog_peek_primary_selection (ESourceSelectorDialog *dialog)
|
|
{
|
|
g_return_val_if_fail (E_IS_SOURCE_SELECTOR_DIALOG (dialog), NULL);
|
|
|
|
return dialog->priv->selected_source;
|
|
}
|