diff options
Diffstat (limited to 'community/almanah')
-rw-r--r-- | community/almanah/PKGBUILD | 40 | ||||
-rw-r--r-- | community/almanah/almanah.install | 12 | ||||
-rw-r--r-- | community/almanah/eds-3.8.patch | 2609 | ||||
-rw-r--r-- | community/almanah/update-gtkspell3-support.patch | 90 |
4 files changed, 0 insertions, 2751 deletions
diff --git a/community/almanah/PKGBUILD b/community/almanah/PKGBUILD deleted file mode 100644 index 709f26825..000000000 --- a/community/almanah/PKGBUILD +++ /dev/null @@ -1,40 +0,0 @@ -# $Id: PKGBUILD 90849 2013-05-14 21:40:34Z andrea $ -# Maintainer: Balló György <ballogyor+arch at gmail dot com> - -pkgname=almanah -pkgver=0.10.1 -pkgrel=3 -pkgdesc="Small GTK+ application to allow you to keep a diary of your life" -arch=('i686' 'x86_64') -url="http://live.gnome.org/Almanah_Diary" -license=('GPL') -depends=('evolution-data-server' 'gtkspell3' 'libcryptui' 'xdg-utils') -makedepends=('intltool') -install=$pkgname.install -source=(http://ftp.gnome.org/pub/GNOME/sources/$pkgname/${pkgver%.*}/$pkgname-$pkgver.tar.xz - eds-3.8.patch - update-gtkspell3-support.patch) -sha256sums=('122789c1baea1713102b200c0401d25395ec177a66ae22635d3ae2fecc1f08bd' - '2407cb2cc11e61b7863bf20fc13d4614a3384e8cb7c5b534f1e3ce7a3afb2d2d' - '60fedd6be05ef2619c3b50539b9fdc717480e4f03a2920d8b68b09e63dc7e7db') - -build() { - cd "$srcdir/$pkgname-$pkgver" - - # Port to evolution-data-server 3.8 - patch -Np1 -i "$srcdir/eds-3.8.patch" - - # Port to the new gtkspell3 - patch -Np1 -i "$srcdir/update-gtkspell3-support.patch" - - autoreconf -fi - ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \ - --disable-static --disable-schemas-compile - make -} - -package() { - cd "$srcdir/$pkgname-$pkgver" - - make DESTDIR="$pkgdir/" install -} diff --git a/community/almanah/almanah.install b/community/almanah/almanah.install deleted file mode 100644 index 6ce7836d2..000000000 --- a/community/almanah/almanah.install +++ /dev/null @@ -1,12 +0,0 @@ -post_install() { - glib-compile-schemas usr/share/glib-2.0/schemas - xdg-icon-resource forceupdate -} - -post_upgrade() { - post_install $1 -} - -post_remove() { - post_install $1 -} diff --git a/community/almanah/eds-3.8.patch b/community/almanah/eds-3.8.patch deleted file mode 100644 index dea51eb74..000000000 --- a/community/almanah/eds-3.8.patch +++ /dev/null @@ -1,2609 +0,0 @@ -From e481f5abdb46d41ac00ee3393332e92f605b55e7 Mon Sep 17 00:00:00 2001 -From: Matthew Barnes <mbarnes@redhat.com> -Date: Thu, 13 Dec 2012 14:16:58 +0000 -Subject: Bug 687229 - Embed ESourceSelector widget from libedataserverui - -Evolution developers are merging libedataserverui back into Evolution. -Drop the libedataserverui dependency and embed the ECellRendererColor -and ESourceSelector widgets from libedataserverui in event-factories. - -See also: -https://mail.gnome.org/archives/distributor-list/2012-December/msg00000.html ---- -diff --git a/configure.ac b/configure.ac -index a529568..b89ba74 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -83,7 +83,7 @@ AC_SUBST(STANDARD_CFLAGS) - AC_SUBST(STANDARD_LIBS) - - dnl Evolution --PKG_CHECK_MODULES(EVO, libecal-1.2 libedataserver-1.2 libedataserverui-3.0, have_evo=yes, have_evo=no) -+PKG_CHECK_MODULES(EVO, libecal-1.2 >= 3.5.91 libedataserver-1.2, have_evo=yes, have_evo=no) - if test "x$have_evo" = "xyes"; then - AC_DEFINE(HAVE_EVO, 1, [Defined if libecal-1.2 is installed]) - fi -diff --git a/src/Makefile.am b/src/Makefile.am -index 0de37e3..740c9f2 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -52,6 +52,10 @@ almanah_SOURCES += \ - event-factories/calendar-debug.h \ - event-factories/calendar-sources.c \ - event-factories/calendar-sources.h \ -+ event-factories/e-cell-renderer-color.c \ -+ event-factories/e-cell-renderer-color.h \ -+ event-factories/e-source-selector.c \ -+ event-factories/e-source-selector.h \ - events/calendar-appointment.c \ - events/calendar-appointment.h \ - events/calendar-task.c \ -diff --git a/src/event-factories/calendar-sources.c b/src/event-factories/calendar-sources.c -index 217327d..9451a0d 100644 ---- a/src/event-factories/calendar-sources.c -+++ b/src/event-factories/calendar-sources.c -@@ -32,7 +32,8 @@ - #define HANDLE_LIBICAL_MEMORY - #include <libecal/libecal.h> - #include <libedataserver/libedataserver.h> --#include <libedataserverui/libedataserverui.h> -+ -+#include "e-source-selector.h" - - #undef CALENDAR_ENABLE_DEBUG - #include "calendar-debug.h" -diff --git a/src/event-factories/e-cell-renderer-color.c b/src/event-factories/e-cell-renderer-color.c -new file mode 100644 -index 0000000..748bea5 ---- /dev/null -+++ b/src/event-factories/e-cell-renderer-color.c -@@ -0,0 +1,237 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -+/* e-cell-renderer-color.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 version 2 of the GNU Lesser General Public -+ * License as published by the Free Software Foundation. -+ * -+ * 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., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include "e-cell-renderer-color.h" -+ -+#include <string.h> -+#include <glib/gi18n-lib.h> -+ -+#define E_CELL_RENDERER_COLOR_GET_PRIVATE(obj) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE \ -+ ((obj), E_TYPE_CELL_RENDERER_COLOR, ECellRendererColorPrivate)) -+ -+enum { -+ PROP_0, -+ PROP_COLOR -+}; -+ -+struct _ECellRendererColorPrivate { -+ GdkColor *color; -+}; -+ -+G_DEFINE_TYPE ( -+ ECellRendererColor, -+ e_cell_renderer_color, -+ GTK_TYPE_CELL_RENDERER) -+ -+static void -+cell_renderer_color_get_size (GtkCellRenderer *cell, -+ GtkWidget *widget, -+ const GdkRectangle *cell_area, -+ gint *x_offset, -+ gint *y_offset, -+ gint *width, -+ gint *height) -+{ -+ gint color_width = 16; -+ gint color_height = 16; -+ gint calc_width; -+ gint calc_height; -+ gfloat xalign; -+ gfloat yalign; -+ guint xpad; -+ guint ypad; -+ -+ g_object_get ( -+ cell, "xalign", &xalign, "yalign", &yalign, -+ "xpad", &xpad, "ypad", &ypad, NULL); -+ -+ calc_width = (gint) xpad * 2 + color_width; -+ calc_height = (gint) ypad * 2 + color_height; -+ -+ if (cell_area && color_width > 0 && color_height > 0) { -+ if (x_offset) { -+ *x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? -+ (1.0 - xalign) : xalign) * -+ (cell_area->width - calc_width)); -+ *x_offset = MAX (*x_offset, 0); -+ } -+ -+ if (y_offset) { -+ *y_offset =(yalign * -+ (cell_area->height - calc_height)); -+ *y_offset = MAX (*y_offset, 0); -+ } -+ } else { -+ if (x_offset) *x_offset = 0; -+ if (y_offset) *y_offset = 0; -+ } -+ -+ if (width) -+ *width = calc_width; -+ -+ if (height) -+ *height = calc_height; -+} -+ -+static void -+cell_renderer_color_render (GtkCellRenderer *cell, -+ cairo_t *cr, -+ GtkWidget *widget, -+ const GdkRectangle *background_area, -+ const GdkRectangle *cell_area, -+ GtkCellRendererState flags) -+{ -+ ECellRendererColorPrivate *priv; -+ GdkRectangle pix_rect; -+ GdkRectangle draw_rect; -+ guint xpad; -+ guint ypad; -+ -+ priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (cell); -+ -+ if (priv->color == NULL) -+ return; -+ -+ cell_renderer_color_get_size ( -+ cell, widget, cell_area, -+ &pix_rect.x, &pix_rect.y, -+ &pix_rect.width, &pix_rect.height); -+ -+ g_object_get (cell, "xpad", &xpad, "ypad", &ypad, NULL); -+ -+ pix_rect.x += cell_area->x + xpad; -+ pix_rect.y += cell_area->y + ypad; -+ pix_rect.width -= xpad * 2; -+ pix_rect.height -= ypad * 2; -+ -+ if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect)) -+ return; -+ -+ gdk_cairo_set_source_color (cr, priv->color); -+ cairo_rectangle (cr, pix_rect.x, pix_rect.y, draw_rect.width, draw_rect.height); -+ -+ cairo_fill (cr); -+} -+ -+static void -+cell_renderer_color_set_property (GObject *object, -+ guint property_id, -+ const GValue *value, -+ GParamSpec *pspec) -+{ -+ ECellRendererColorPrivate *priv; -+ -+ priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (object); -+ -+ switch (property_id) { -+ case PROP_COLOR: -+ if (priv->color != NULL) -+ gdk_color_free (priv->color); -+ priv->color = g_value_dup_boxed (value); -+ return; -+ } -+ -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+} -+ -+static void -+cell_renderer_color_get_property (GObject *object, -+ guint property_id, -+ GValue *value, -+ GParamSpec *pspec) -+{ -+ ECellRendererColorPrivate *priv; -+ -+ priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (object); -+ -+ switch (property_id) { -+ case PROP_COLOR: -+ g_value_set_boxed (value, priv->color); -+ return; -+ } -+ -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+} -+ -+static void -+cell_renderer_color_finalize (GObject *object) -+{ -+ ECellRendererColorPrivate *priv; -+ -+ priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (object); -+ -+ if (priv->color != NULL) -+ gdk_color_free (priv->color); -+ -+ /* Chain up to parent's finalize() method. */ -+ G_OBJECT_CLASS (e_cell_renderer_color_parent_class)->finalize (object); -+} -+ -+static void -+e_cell_renderer_color_class_init (ECellRendererColorClass *class) -+{ -+ GObjectClass *object_class; -+ GtkCellRendererClass *cell_class; -+ -+ g_type_class_add_private (class, sizeof (ECellRendererColorPrivate)); -+ -+ object_class = G_OBJECT_CLASS (class); -+ object_class->set_property = cell_renderer_color_set_property; -+ object_class->get_property = cell_renderer_color_get_property; -+ object_class->finalize = cell_renderer_color_finalize; -+ -+ cell_class = GTK_CELL_RENDERER_CLASS (class); -+ cell_class->get_size = cell_renderer_color_get_size; -+ cell_class->render = cell_renderer_color_render; -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_COLOR, -+ g_param_spec_boxed ( -+ "color", -+ "Color Info", -+ "The color to render", -+ GDK_TYPE_COLOR, -+ G_PARAM_READWRITE)); -+} -+ -+static void -+e_cell_renderer_color_init (ECellRendererColor *cellcolor) -+{ -+ cellcolor->priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (cellcolor); -+ -+ g_object_set (cellcolor, "xpad", 4, NULL); -+} -+ -+/** -+ * e_cell_renderer_color_new: -+ * -+ * Since: 2.22 -+ **/ -+GtkCellRenderer * -+e_cell_renderer_color_new (void) -+{ -+ return g_object_new (E_TYPE_CELL_RENDERER_COLOR, NULL); -+} -diff --git a/src/event-factories/e-cell-renderer-color.h b/src/event-factories/e-cell-renderer-color.h -new file mode 100644 -index 0000000..0e0da70 ---- /dev/null -+++ b/src/event-factories/e-cell-renderer-color.h -@@ -0,0 +1,75 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -+/* e-cell-renderer-color.h -+ * -+ * 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 version 2 of the GNU Lesser General Public -+ * License as published by the Free Software Foundation. -+ * -+ * 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., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+ -+#ifndef _E_CELL_RENDERER_COLOR_H_ -+#define _E_CELL_RENDERER_COLOR_H_ -+ -+#include <gtk/gtk.h> -+ -+/* Standard GObject macros */ -+#define E_TYPE_CELL_RENDERER_COLOR \ -+ (e_cell_renderer_color_get_type ()) -+#define E_CELL_RENDERER_COLOR(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST \ -+ ((obj), E_TYPE_CELL_RENDERER_COLOR, ECellRendererColor)) -+#define E_CELL_RENDERER_COLOR_CLASS(cls) \ -+ (G_TYPE_CHECK_CLASS_CAST \ -+ ((cls), E_TYPE_CELL_RENDERER_COLOR, ECellRendererColorClass)) -+#define E_IS_CELL_RENDERER_COLOR(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE \ -+ ((obj), E_TYPE_CELL_RENDERER_COLOR)) -+#define E_IS_CELL_RENDERER_COLOR_CLASS(cls) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((cls), E_TYPE_CELL_RENDERER_COLOR)) -+#define E_CELL_RENDERER_COLOR_GET_CLASS(obj) \ -+ (G_TYPE_INSTANCE_GET_CLASS \ -+ ((obj), E_TYPE_CELL_RENDERER_COLOR, ECellRendererColorClass)) -+ -+G_BEGIN_DECLS -+ -+typedef struct _ECellRendererColor ECellRendererColor; -+typedef struct _ECellRendererColorClass ECellRendererColorClass; -+typedef struct _ECellRendererColorPrivate ECellRendererColorPrivate; -+ -+/** -+ * ECellRendererColor: -+ * -+ * Since: 2.22 -+ **/ -+struct _ECellRendererColor { -+ GtkCellRenderer parent; -+ ECellRendererColorPrivate *priv; -+}; -+ -+struct _ECellRendererColorClass { -+ GtkCellRendererClass parent_class; -+ -+ /* Padding for future expansion */ -+ void (*_gtk_reserved1) (void); -+ void (*_gtk_reserved2) (void); -+ void (*_gtk_reserved3) (void); -+ void (*_gtk_reserved4) (void); -+}; -+ -+GType e_cell_renderer_color_get_type (void); -+GtkCellRenderer *e_cell_renderer_color_new (void); -+ -+G_END_DECLS -+ -+#endif /* _E_CELL_RENDERER_COLOR_H_ */ -diff --git a/src/event-factories/e-source-selector.c b/src/event-factories/e-source-selector.c -new file mode 100644 -index 0000000..925d9cd ---- /dev/null -+++ b/src/event-factories/e-source-selector.c -@@ -0,0 +1,2080 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -+/* e-source-selector.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: Ettore Perazzoli <ettore@ximian.com> -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include <string.h> -+ -+#include "e-cell-renderer-color.h" -+#include "e-source-selector.h" -+ -+#define E_SOURCE_SELECTOR_GET_PRIVATE(obj) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE \ -+ ((obj), E_TYPE_SOURCE_SELECTOR, ESourceSelectorPrivate)) -+ -+typedef struct _AsyncContext AsyncContext; -+ -+struct _ESourceSelectorPrivate { -+ ESourceRegistry *registry; -+ GHashTable *source_index; -+ gchar *extension_name; -+ -+ GtkTreeRowReference *saved_primary_selection; -+ -+ /* ESource -> GSource */ -+ GHashTable *pending_writes; -+ GMainContext *main_context; -+ -+ gboolean toggled_last; -+ gboolean select_new; -+ gboolean show_colors; -+ gboolean show_toggles; -+}; -+ -+struct _AsyncContext { -+ ESourceSelector *selector; -+ ESource *source; -+}; -+ -+enum { -+ PROP_0, -+ PROP_EXTENSION_NAME, -+ PROP_PRIMARY_SELECTION, -+ PROP_REGISTRY, -+ PROP_SHOW_COLORS, -+ PROP_SHOW_TOGGLES -+}; -+ -+enum { -+ SELECTION_CHANGED, -+ PRIMARY_SELECTION_CHANGED, -+ POPUP_EVENT, -+ DATA_DROPPED, -+ NUM_SIGNALS -+}; -+ -+enum { -+ COLUMN_NAME, -+ COLUMN_COLOR, -+ COLUMN_ACTIVE, -+ COLUMN_SHOW_COLOR, -+ COLUMN_SHOW_TOGGLE, -+ COLUMN_WEIGHT, -+ COLUMN_SOURCE, -+ NUM_COLUMNS -+}; -+ -+static guint signals[NUM_SIGNALS]; -+ -+G_DEFINE_TYPE (ESourceSelector, e_source_selector, GTK_TYPE_TREE_VIEW) -+ -+/* ESafeToggleRenderer does not emit 'toggled' signal -+ * on 'activate' when mouse is not over the toggle. */ -+ -+typedef GtkCellRendererToggle ECellRendererSafeToggle; -+typedef GtkCellRendererToggleClass ECellRendererSafeToggleClass; -+ -+/* Forward Declarations */ -+GType e_cell_renderer_safe_toggle_get_type (void); -+ -+G_DEFINE_TYPE ( -+ ECellRendererSafeToggle, -+ e_cell_renderer_safe_toggle, -+ GTK_TYPE_CELL_RENDERER_TOGGLE) -+ -+static gboolean -+safe_toggle_activate (GtkCellRenderer *cell, -+ GdkEvent *event, -+ GtkWidget *widget, -+ const gchar *path, -+ const GdkRectangle *background_area, -+ const GdkRectangle *cell_area, -+ GtkCellRendererState flags) -+{ -+ gboolean point_in_cell_area = TRUE; -+ -+ if (event->type == GDK_BUTTON_PRESS && cell_area != NULL) { -+ cairo_region_t *region; -+ -+ region = cairo_region_create_rectangle (cell_area); -+ point_in_cell_area = cairo_region_contains_point ( -+ region, event->button.x, event->button.y); -+ cairo_region_destroy (region); -+ } -+ -+ if (!point_in_cell_area) -+ return FALSE; -+ -+ return GTK_CELL_RENDERER_CLASS ( -+ e_cell_renderer_safe_toggle_parent_class)->activate ( -+ cell, event, widget, path, background_area, cell_area, flags); -+} -+ -+static void -+e_cell_renderer_safe_toggle_class_init (ECellRendererSafeToggleClass *class) -+{ -+ GtkCellRendererClass *cell_renderer_class; -+ -+ cell_renderer_class = GTK_CELL_RENDERER_CLASS (class); -+ cell_renderer_class->activate = safe_toggle_activate; -+} -+ -+static void -+e_cell_renderer_safe_toggle_init (ECellRendererSafeToggle *obj) -+{ -+} -+ -+static GtkCellRenderer * -+e_cell_renderer_safe_toggle_new (void) -+{ -+ return g_object_new (e_cell_renderer_safe_toggle_get_type (), NULL); -+} -+ -+static void -+clear_saved_primary_selection (ESourceSelector *selector) -+{ -+ gtk_tree_row_reference_free (selector->priv->saved_primary_selection); -+ selector->priv->saved_primary_selection = NULL; -+} -+ -+static void -+async_context_free (AsyncContext *async_context) -+{ -+ if (async_context->selector != NULL) -+ g_object_unref (async_context->selector); -+ -+ if (async_context->source != NULL) -+ g_object_unref (async_context->source); -+ -+ g_slice_free (AsyncContext, async_context); -+} -+ -+static void -+pending_writes_destroy_source (GSource *source) -+{ -+ g_source_destroy (source); -+ g_source_unref (source); -+} -+ -+static void -+source_selector_write_done_cb (GObject *source_object, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ ESource *source; -+ ESourceSelector *selector; -+ GError *error = NULL; -+ -+ source = E_SOURCE (source_object); -+ selector = E_SOURCE_SELECTOR (user_data); -+ -+ e_source_write_finish (source, result, &error); -+ -+ /* FIXME Display the error in the selector somehow? */ -+ if (error != NULL) { -+ g_warning ("%s: %s", G_STRFUNC, error->message); -+ g_error_free (error); -+ } -+ -+ g_object_unref (selector); -+} -+ -+static gboolean -+source_selector_write_idle_cb (gpointer user_data) -+{ -+ AsyncContext *async_context = user_data; -+ GHashTable *pending_writes; -+ -+ /* XXX This operation is not cancellable. */ -+ e_source_write ( -+ async_context->source, NULL, -+ source_selector_write_done_cb, -+ g_object_ref (async_context->selector)); -+ -+ pending_writes = async_context->selector->priv->pending_writes; -+ g_hash_table_remove (pending_writes, async_context->source); -+ -+ return FALSE; -+} -+ -+static void -+source_selector_cancel_write (ESourceSelector *selector, -+ ESource *source) -+{ -+ GHashTable *pending_writes; -+ -+ /* Cancel any pending writes for this ESource so as not -+ * to overwrite whatever change we're being notified of. */ -+ pending_writes = selector->priv->pending_writes; -+ g_hash_table_remove (pending_writes, source); -+} -+ -+static void -+source_selector_update_row (ESourceSelector *selector, -+ ESource *source) -+{ -+ GHashTable *source_index; -+ ESourceExtension *extension = NULL; -+ GtkTreeRowReference *reference; -+ GtkTreeModel *model; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ const gchar *extension_name; -+ const gchar *display_name; -+ gboolean selected; -+ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ -+ /* This function runs when ANY ESource in the registry changes. -+ * If the ESource is not in our tree model then return silently. */ -+ if (reference == NULL) -+ return; -+ -+ /* If we do have a row reference, it should be valid. */ -+ g_return_if_fail (gtk_tree_row_reference_valid (reference)); -+ -+ model = gtk_tree_row_reference_get_model (reference); -+ path = gtk_tree_row_reference_get_path (reference); -+ gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_path_free (path); -+ -+ display_name = e_source_get_display_name (source); -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ selected = e_source_selector_source_is_selected (selector, source); -+ -+ if (e_source_has_extension (source, extension_name)) -+ extension = e_source_get_extension (source, extension_name); -+ -+ if (extension != NULL) { -+ GdkColor color; -+ const gchar *color_spec = NULL; -+ gboolean show_color = FALSE; -+ gboolean show_toggle; -+ -+ show_color = -+ E_IS_SOURCE_SELECTABLE (extension) && -+ e_source_selector_get_show_colors (selector); -+ -+ if (show_color) -+ color_spec = e_source_selectable_get_color ( -+ E_SOURCE_SELECTABLE (extension)); -+ -+ if (color_spec != NULL && *color_spec != '\0') -+ show_color = gdk_color_parse (color_spec, &color); -+ -+ show_toggle = e_source_selector_get_show_toggles (selector); -+ -+ gtk_tree_store_set ( -+ GTK_TREE_STORE (model), &iter, -+ COLUMN_NAME, display_name, -+ COLUMN_COLOR, show_color ? &color : NULL, -+ COLUMN_ACTIVE, selected, -+ COLUMN_SHOW_COLOR, show_color, -+ COLUMN_SHOW_TOGGLE, show_toggle, -+ COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -+ COLUMN_SOURCE, source, -+ -1); -+ } else { -+ gtk_tree_store_set ( -+ GTK_TREE_STORE (model), &iter, -+ COLUMN_NAME, display_name, -+ COLUMN_COLOR, NULL, -+ COLUMN_ACTIVE, FALSE, -+ COLUMN_SHOW_COLOR, FALSE, -+ COLUMN_SHOW_TOGGLE, FALSE, -+ COLUMN_WEIGHT, PANGO_WEIGHT_BOLD, -+ COLUMN_SOURCE, source, -+ -1); -+ } -+} -+ -+static gboolean -+source_selector_traverse (GNode *node, -+ ESourceSelector *selector) -+{ -+ ESource *source; -+ GHashTable *source_index; -+ GtkTreeRowReference *reference = NULL; -+ GtkTreeModel *model; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ -+ /* Skip the root node. */ -+ if (G_NODE_IS_ROOT (node)) -+ return FALSE; -+ -+ source_index = selector->priv->source_index; -+ -+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector)); -+ -+ if (node->parent != NULL && node->parent->data != NULL) -+ reference = g_hash_table_lookup ( -+ source_index, node->parent->data); -+ -+ if (gtk_tree_row_reference_valid (reference)) { -+ GtkTreeIter parent; -+ -+ path = gtk_tree_row_reference_get_path (reference); -+ gtk_tree_model_get_iter (model, &parent, path); -+ gtk_tree_path_free (path); -+ -+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent); -+ } else -+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL); -+ -+ source = E_SOURCE (node->data); -+ -+ path = gtk_tree_model_get_path (model, &iter); -+ reference = gtk_tree_row_reference_new (model, path); -+ g_hash_table_insert (source_index, g_object_ref (source), reference); -+ gtk_tree_path_free (path); -+ -+ source_selector_update_row (selector, source); -+ -+ return FALSE; -+} -+ -+static void -+source_selector_save_expanded (GtkTreeView *tree_view, -+ GtkTreePath *path, -+ GQueue *queue) -+{ -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ ESource *source; -+ -+ model = gtk_tree_view_get_model (tree_view); -+ gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ g_queue_push_tail (queue, source); -+} -+ -+static void -+source_selector_build_model (ESourceSelector *selector) -+{ -+ ESourceRegistry *registry; -+ GQueue queue = G_QUEUE_INIT; -+ GHashTable *source_index; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ ESource *selected; -+ const gchar *extension_name; -+ GNode *root; -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ -+ registry = e_source_selector_get_registry (selector); -+ extension_name = e_source_selector_get_extension_name (selector); -+ -+ /* Make sure we have what we need to build the model, since -+ * this can get called early in the initialization phase. */ -+ if (registry == NULL || extension_name == NULL) -+ return; -+ -+ source_index = selector->priv->source_index; -+ selected = e_source_selector_ref_primary_selection (selector); -+ -+ /* Save expanded sources to restore later. */ -+ gtk_tree_view_map_expanded_rows ( -+ tree_view, (GtkTreeViewMappingFunc) -+ source_selector_save_expanded, &queue); -+ -+ model = gtk_tree_view_get_model (tree_view); -+ gtk_tree_store_clear (GTK_TREE_STORE (model)); -+ -+ g_hash_table_remove_all (source_index); -+ -+ root = e_source_registry_build_display_tree (registry, extension_name); -+ -+ g_node_traverse ( -+ root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, -+ (GNodeTraverseFunc) source_selector_traverse, -+ selector); -+ -+ e_source_registry_free_display_tree (root); -+ -+ /* Restore previously expanded sources. */ -+ while (!g_queue_is_empty (&queue)) { -+ GtkTreeRowReference *reference; -+ ESource *source; -+ -+ source = g_queue_pop_head (&queue); -+ reference = g_hash_table_lookup (source_index, source); -+ -+ if (gtk_tree_row_reference_valid (reference)) { -+ GtkTreePath *path; -+ -+ path = gtk_tree_row_reference_get_path (reference); -+ gtk_tree_view_expand_to_path (tree_view, path); -+ gtk_tree_path_free (path); -+ } -+ -+ g_object_unref (source); -+ } -+ -+ /* Restore the primary selection. */ -+ if (selected != NULL) { -+ e_source_selector_set_primary_selection (selector, selected); -+ g_object_unref (selected); -+ } -+ -+ /* Make sure we have a primary selection. If not, pick one. */ -+ selected = e_source_selector_ref_primary_selection (selector); -+ if (selected == NULL) { -+ selected = e_source_registry_ref_default_for_extension_name ( -+ registry, extension_name); -+ e_source_selector_set_primary_selection (selector, selected); -+ } -+ g_object_unref (selected); -+} -+ -+static void -+source_selector_expand_to_source (ESourceSelector *selector, -+ ESource *source) -+{ -+ GHashTable *source_index; -+ GtkTreeRowReference *reference; -+ GtkTreePath *path; -+ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ -+ /* If the ESource is not in our tree model then return silently. */ -+ if (reference == NULL) -+ return; -+ -+ /* If we do have a row reference, it should be valid. */ -+ g_return_if_fail (gtk_tree_row_reference_valid (reference)); -+ -+ /* Expand the tree view to the path containing the ESource */ -+ path = gtk_tree_row_reference_get_path (reference); -+ gtk_tree_view_expand_to_path (GTK_TREE_VIEW (selector), path); -+ gtk_tree_path_free (path); -+} -+ -+static void -+source_selector_source_added_cb (ESourceRegistry *registry, -+ ESource *source, -+ ESourceSelector *selector) -+{ -+ source_selector_build_model (selector); -+ -+ source_selector_expand_to_source (selector, source); -+} -+ -+static void -+source_selector_source_changed_cb (ESourceRegistry *registry, -+ ESource *source, -+ ESourceSelector *selector) -+{ -+ source_selector_cancel_write (selector, source); -+ -+ source_selector_update_row (selector, source); -+} -+ -+static void -+source_selector_source_removed_cb (ESourceRegistry *registry, -+ ESource *source, -+ ESourceSelector *selector) -+{ -+ source_selector_build_model (selector); -+} -+ -+static void -+source_selector_source_enabled_cb (ESourceRegistry *registry, -+ ESource *source, -+ ESourceSelector *selector) -+{ -+ source_selector_build_model (selector); -+ -+ source_selector_expand_to_source (selector, source); -+} -+ -+static void -+source_selector_source_disabled_cb (ESourceRegistry *registry, -+ ESource *source, -+ ESourceSelector *selector) -+{ -+ source_selector_build_model (selector); -+} -+ -+static gboolean -+same_source_name_exists (ESourceSelector *selector, -+ const gchar *display_name) -+{ -+ GHashTable *source_index; -+ GHashTableIter iter; -+ gpointer key; -+ -+ source_index = selector->priv->source_index; -+ g_hash_table_iter_init (&iter, source_index); -+ -+ while (g_hash_table_iter_next (&iter, &key, NULL)) { -+ ESource *source = E_SOURCE (key); -+ const gchar *source_name; -+ -+ source_name = e_source_get_display_name (source); -+ if (g_strcmp0 (display_name, source_name) == 0) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+static gboolean -+selection_func (GtkTreeSelection *selection, -+ GtkTreeModel *model, -+ GtkTreePath *path, -+ gboolean path_currently_selected, -+ ESourceSelector *selector) -+{ -+ ESource *source; -+ GtkTreeIter iter; -+ const gchar *extension_name; -+ -+ if (selector->priv->toggled_last) { -+ selector->priv->toggled_last = FALSE; -+ return FALSE; -+ } -+ -+ if (path_currently_selected) -+ return TRUE; -+ -+ if (!gtk_tree_model_get_iter (model, &iter, path)) -+ return FALSE; -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ if (!e_source_has_extension (source, extension_name)) { -+ g_object_unref (source); -+ return FALSE; -+ } -+ -+ clear_saved_primary_selection (selector); -+ -+ g_object_unref (source); -+ -+ return TRUE; -+} -+ -+static void -+text_cell_edited_cb (ESourceSelector *selector, -+ const gchar *path_string, -+ const gchar *new_name) -+{ -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ ESource *source; -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ model = gtk_tree_view_get_model (tree_view); -+ path = gtk_tree_path_new_from_string (path_string); -+ -+ gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ gtk_tree_path_free (path); -+ -+ if (new_name == NULL || *new_name == '\0') -+ return; -+ -+ if (same_source_name_exists (selector, new_name)) -+ return; -+ -+ e_source_set_display_name (source, new_name); -+ -+ e_source_selector_queue_write (selector, source); -+} -+ -+static void -+cell_toggled_callback (GtkCellRendererToggle *renderer, -+ const gchar *path_string, -+ ESourceSelector *selector) -+{ -+ ESource *source; -+ GtkTreeModel *model; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ -+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector)); -+ path = gtk_tree_path_new_from_string (path_string); -+ -+ if (!gtk_tree_model_get_iter (model, &iter, path)) { -+ gtk_tree_path_free (path); -+ return; -+ } -+ -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ if (e_source_selector_source_is_selected (selector, source)) -+ e_source_selector_unselect_source (selector, source); -+ else -+ e_source_selector_select_source (selector, source); -+ -+ selector->priv->toggled_last = TRUE; -+ -+ gtk_tree_path_free (path); -+ -+ g_object_unref (source); -+} -+ -+static void -+selection_changed_callback (GtkTreeSelection *selection, -+ ESourceSelector *selector) -+{ -+ g_signal_emit (selector, signals[PRIMARY_SELECTION_CHANGED], 0); -+ g_object_notify (G_OBJECT (selector), "primary-selection"); -+} -+ -+static void -+source_selector_set_extension_name (ESourceSelector *selector, -+ const gchar *extension_name) -+{ -+ g_return_if_fail (extension_name != NULL); -+ g_return_if_fail (selector->priv->extension_name == NULL); -+ -+ selector->priv->extension_name = g_strdup (extension_name); -+} -+ -+static void -+source_selector_set_registry (ESourceSelector *selector, -+ ESourceRegistry *registry) -+{ -+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); -+ g_return_if_fail (selector->priv->registry == NULL); -+ -+ selector->priv->registry = g_object_ref (registry); -+} -+ -+static void -+source_selector_set_property (GObject *object, -+ guint property_id, -+ const GValue *value, -+ GParamSpec *pspec) -+{ -+ switch (property_id) { -+ case PROP_EXTENSION_NAME: -+ source_selector_set_extension_name ( -+ E_SOURCE_SELECTOR (object), -+ g_value_get_string (value)); -+ return; -+ -+ case PROP_PRIMARY_SELECTION: -+ e_source_selector_set_primary_selection ( -+ E_SOURCE_SELECTOR (object), -+ g_value_get_object (value)); -+ return; -+ -+ case PROP_REGISTRY: -+ source_selector_set_registry ( -+ E_SOURCE_SELECTOR (object), -+ g_value_get_object (value)); -+ return; -+ -+ case PROP_SHOW_COLORS: -+ e_source_selector_set_show_colors ( -+ E_SOURCE_SELECTOR (object), -+ g_value_get_boolean (value)); -+ return; -+ -+ case PROP_SHOW_TOGGLES: -+ e_source_selector_set_show_toggles ( -+ E_SOURCE_SELECTOR (object), -+ g_value_get_boolean (value)); -+ return; -+ } -+ -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+} -+ -+static void -+source_selector_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_get_extension_name ( -+ E_SOURCE_SELECTOR (object))); -+ return; -+ -+ case PROP_PRIMARY_SELECTION: -+ g_value_take_object ( -+ value, -+ e_source_selector_ref_primary_selection ( -+ E_SOURCE_SELECTOR (object))); -+ return; -+ -+ case PROP_REGISTRY: -+ g_value_set_object ( -+ value, -+ e_source_selector_get_registry ( -+ E_SOURCE_SELECTOR (object))); -+ return; -+ -+ case PROP_SHOW_COLORS: -+ g_value_set_boolean ( -+ value, -+ e_source_selector_get_show_colors ( -+ E_SOURCE_SELECTOR (object))); -+ return; -+ -+ case PROP_SHOW_TOGGLES: -+ g_value_set_boolean ( -+ value, -+ e_source_selector_get_show_toggles ( -+ E_SOURCE_SELECTOR (object))); -+ return; -+ } -+ -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+} -+ -+static void -+source_selector_dispose (GObject *object) -+{ -+ ESourceSelectorPrivate *priv; -+ -+ priv = E_SOURCE_SELECTOR_GET_PRIVATE (object); -+ -+ if (priv->registry != NULL) { -+ g_signal_handlers_disconnect_matched ( -+ priv->registry, -+ G_SIGNAL_MATCH_DATA, -+ 0, 0, NULL, NULL, object); -+ g_object_unref (priv->registry); -+ priv->registry = NULL; -+ } -+ -+ g_hash_table_remove_all (priv->source_index); -+ g_hash_table_remove_all (priv->pending_writes); -+ -+ clear_saved_primary_selection (E_SOURCE_SELECTOR (object)); -+ -+ /* Chain up to parent's dispose() method. */ -+ G_OBJECT_CLASS (e_source_selector_parent_class)->dispose (object); -+} -+ -+static void -+source_selector_finalize (GObject *object) -+{ -+ ESourceSelectorPrivate *priv; -+ -+ priv = E_SOURCE_SELECTOR_GET_PRIVATE (object); -+ -+ g_hash_table_destroy (priv->source_index); -+ g_hash_table_destroy (priv->pending_writes); -+ -+ g_free (priv->extension_name); -+ -+ if (priv->main_context != NULL) -+ g_main_context_unref (priv->main_context); -+ -+ /* Chain up to parent's finalize() method. */ -+ G_OBJECT_CLASS (e_source_selector_parent_class)->finalize (object); -+} -+ -+static void -+source_selector_constructed (GObject *object) -+{ -+ ESourceRegistry *registry; -+ ESourceSelector *selector; -+ -+ selector = E_SOURCE_SELECTOR (object); -+ registry = e_source_selector_get_registry (selector); -+ -+ g_signal_connect ( -+ registry, "source-added", -+ G_CALLBACK (source_selector_source_added_cb), selector); -+ -+ g_signal_connect ( -+ registry, "source-changed", -+ G_CALLBACK (source_selector_source_changed_cb), selector); -+ -+ g_signal_connect ( -+ registry, "source-removed", -+ G_CALLBACK (source_selector_source_removed_cb), selector); -+ -+ g_signal_connect ( -+ registry, "source-enabled", -+ G_CALLBACK (source_selector_source_enabled_cb), selector); -+ -+ g_signal_connect ( -+ registry, "source-disabled", -+ G_CALLBACK (source_selector_source_disabled_cb), selector); -+ -+ source_selector_build_model (selector); -+ -+ gtk_tree_view_expand_all (GTK_TREE_VIEW (selector)); -+} -+ -+static gboolean -+source_selector_button_press_event (GtkWidget *widget, -+ GdkEventButton *event) -+{ -+ ESourceSelector *selector; -+ GtkWidgetClass *widget_class; -+ GtkTreePath *path; -+ ESource *source = NULL; -+ ESource *primary; -+ gboolean right_click = FALSE; -+ gboolean triple_click = FALSE; -+ gboolean row_exists; -+ gboolean res = FALSE; -+ -+ selector = E_SOURCE_SELECTOR (widget); -+ -+ selector->priv->toggled_last = FALSE; -+ -+ /* Triple-clicking a source selects it exclusively. */ -+ -+ if (event->button == 3 && event->type == GDK_BUTTON_PRESS) -+ right_click = TRUE; -+ else if (event->button == 1 && event->type == GDK_3BUTTON_PRESS) -+ triple_click = TRUE; -+ else -+ goto chainup; -+ -+ row_exists = gtk_tree_view_get_path_at_pos ( -+ GTK_TREE_VIEW (widget), event->x, event->y, -+ &path, NULL, NULL, NULL); -+ -+ /* Get the source/group */ -+ if (row_exists) { -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ -+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); -+ -+ gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ } -+ -+ if (source == NULL) -+ goto chainup; -+ -+ primary = e_source_selector_ref_primary_selection (selector); -+ if (source != primary) -+ e_source_selector_set_primary_selection (selector, source); -+ if (primary != NULL) -+ g_object_unref (primary); -+ -+ if (right_click) -+ g_signal_emit ( -+ widget, signals[POPUP_EVENT], 0, source, event, &res); -+ -+ if (triple_click) { -+ e_source_selector_select_exclusive (selector, source); -+ res = TRUE; -+ } -+ -+ g_object_unref (source); -+ -+ return res; -+ -+chainup: -+ -+ /* Chain up to parent's button_press_event() method. */ -+ widget_class = GTK_WIDGET_CLASS (e_source_selector_parent_class); -+ return widget_class->button_press_event (widget, event); -+} -+ -+static void -+source_selector_drag_leave (GtkWidget *widget, -+ GdkDragContext *context, -+ guint time_) -+{ -+ GtkTreeView *tree_view; -+ GtkTreeViewDropPosition pos; -+ -+ tree_view = GTK_TREE_VIEW (widget); -+ pos = GTK_TREE_VIEW_DROP_BEFORE; -+ -+ gtk_tree_view_set_drag_dest_row (tree_view, NULL, pos); -+} -+ -+static gboolean -+source_selector_drag_motion (GtkWidget *widget, -+ GdkDragContext *context, -+ gint x, -+ gint y, -+ guint time_) -+{ -+ ESource *source = NULL; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreePath *path = NULL; -+ GtkTreeIter iter; -+ GtkTreeViewDropPosition pos; -+ GdkDragAction action = 0; -+ -+ tree_view = GTK_TREE_VIEW (widget); -+ model = gtk_tree_view_get_model (tree_view); -+ -+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL)) -+ goto exit; -+ -+ if (!gtk_tree_model_get_iter (model, &iter, path)) -+ goto exit; -+ -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ if (!e_source_get_writable (source)) -+ goto exit; -+ -+ pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE; -+ gtk_tree_view_set_drag_dest_row (tree_view, path, pos); -+ -+ if (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) -+ action = GDK_ACTION_MOVE; -+ else -+ action = gdk_drag_context_get_suggested_action (context); -+ -+exit: -+ if (path != NULL) -+ gtk_tree_path_free (path); -+ -+ if (source != NULL) -+ g_object_unref (source); -+ -+ gdk_drag_status (context, action, time_); -+ -+ return TRUE; -+} -+ -+static gboolean -+source_selector_drag_drop (GtkWidget *widget, -+ GdkDragContext *context, -+ gint x, -+ gint y, -+ guint time_) -+{ -+ ESource *source; -+ ESourceSelector *selector; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ const gchar *extension_name; -+ gboolean drop_zone; -+ gboolean valid; -+ -+ tree_view = GTK_TREE_VIEW (widget); -+ model = gtk_tree_view_get_model (tree_view); -+ -+ if (!gtk_tree_view_get_path_at_pos ( -+ tree_view, x, y, &path, NULL, NULL, NULL)) -+ return FALSE; -+ -+ valid = gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_path_free (path); -+ g_return_val_if_fail (valid, FALSE); -+ -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ selector = E_SOURCE_SELECTOR (widget); -+ extension_name = e_source_selector_get_extension_name (selector); -+ drop_zone = e_source_has_extension (source, extension_name); -+ -+ g_object_unref (source); -+ -+ return drop_zone; -+} -+ -+static void -+source_selector_drag_data_received (GtkWidget *widget, -+ GdkDragContext *context, -+ gint x, -+ gint y, -+ GtkSelectionData *selection_data, -+ guint info, -+ guint time_) -+{ -+ ESource *source = NULL; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreePath *path = NULL; -+ GtkTreeIter iter; -+ GdkDragAction action; -+ gboolean delete; -+ gboolean success = FALSE; -+ -+ tree_view = GTK_TREE_VIEW (widget); -+ model = gtk_tree_view_get_model (tree_view); -+ -+ action = gdk_drag_context_get_selected_action (context); -+ delete = (action == GDK_ACTION_MOVE); -+ -+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL)) -+ goto exit; -+ -+ if (!gtk_tree_model_get_iter (model, &iter, path)) -+ goto exit; -+ -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ if (!e_source_get_writable (source)) -+ goto exit; -+ -+ g_signal_emit ( -+ widget, signals[DATA_DROPPED], 0, selection_data, -+ source, gdk_drag_context_get_selected_action (context), -+ info, &success); -+ -+exit: -+ if (path != NULL) -+ gtk_tree_path_free (path); -+ -+ if (source != NULL) -+ g_object_unref (source); -+ -+ gtk_drag_finish (context, success, delete, time_); -+} -+ -+static gboolean -+source_selector_popup_menu (GtkWidget *widget) -+{ -+ ESourceSelector *selector; -+ ESource *source; -+ gboolean res = FALSE; -+ -+ selector = E_SOURCE_SELECTOR (widget); -+ source = e_source_selector_ref_primary_selection (selector); -+ g_signal_emit (selector, signals[POPUP_EVENT], 0, source, NULL, &res); -+ -+ if (source != NULL) -+ g_object_unref (source); -+ -+ return res; -+} -+ -+static gboolean -+source_selector_test_collapse_row (GtkTreeView *tree_view, -+ GtkTreeIter *iter, -+ GtkTreePath *path) -+{ -+ ESourceSelectorPrivate *priv; -+ GtkTreeSelection *selection; -+ GtkTreeModel *model; -+ GtkTreeIter child_iter; -+ -+ priv = E_SOURCE_SELECTOR_GET_PRIVATE (tree_view); -+ -+ /* Clear this because something else has been clicked on now */ -+ priv->toggled_last = FALSE; -+ -+ if (priv->saved_primary_selection) -+ return FALSE; -+ -+ selection = gtk_tree_view_get_selection (tree_view); -+ -+ if (!gtk_tree_selection_get_selected (selection, &model, &child_iter)) -+ return FALSE; -+ -+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), iter, &child_iter)) { -+ GtkTreeRowReference *reference; -+ GtkTreePath *child_path; -+ -+ child_path = gtk_tree_model_get_path (model, &child_iter); -+ reference = gtk_tree_row_reference_new (model, child_path); -+ priv->saved_primary_selection = reference; -+ gtk_tree_path_free (child_path); -+ } -+ -+ return FALSE; -+} -+ -+static void -+source_selector_row_expanded (GtkTreeView *tree_view, -+ GtkTreeIter *iter, -+ GtkTreePath *path) -+{ -+ ESourceSelectorPrivate *priv; -+ GtkTreeModel *model; -+ GtkTreePath *child_path; -+ GtkTreeIter child_iter; -+ -+ priv = E_SOURCE_SELECTOR_GET_PRIVATE (tree_view); -+ -+ if (!priv->saved_primary_selection) -+ return; -+ -+ model = gtk_tree_view_get_model (tree_view); -+ -+ child_path = gtk_tree_row_reference_get_path ( -+ priv->saved_primary_selection); -+ gtk_tree_model_get_iter (model, &child_iter, child_path); -+ -+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), iter, &child_iter)) { -+ GtkTreeSelection *selection; -+ -+ selection = gtk_tree_view_get_selection (tree_view); -+ gtk_tree_selection_select_iter (selection, &child_iter); -+ -+ clear_saved_primary_selection (E_SOURCE_SELECTOR (tree_view)); -+ } -+ -+ gtk_tree_path_free (child_path); -+} -+ -+static gboolean -+source_selector_get_source_selected (ESourceSelector *selector, -+ ESource *source) -+{ -+ ESourceSelectable *extension; -+ const gchar *extension_name; -+ gboolean selected = TRUE; -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ -+ if (!e_source_has_extension (source, extension_name)) -+ return FALSE; -+ -+ extension = e_source_get_extension (source, extension_name); -+ -+ if (E_IS_SOURCE_SELECTABLE (extension)) -+ selected = e_source_selectable_get_selected (extension); -+ -+ return selected; -+} -+ -+static void -+source_selector_set_source_selected (ESourceSelector *selector, -+ ESource *source, -+ gboolean selected) -+{ -+ ESourceSelectable *extension; -+ const gchar *extension_name; -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ -+ if (!e_source_has_extension (source, extension_name)) -+ return; -+ -+ extension = e_source_get_extension (source, extension_name); -+ -+ if (!E_IS_SOURCE_SELECTABLE (extension)) -+ return; -+ -+ if (selected != e_source_selectable_get_selected (extension)) { -+ e_source_selectable_set_selected (extension, selected); -+ e_source_selector_queue_write (selector, source); -+ } -+} -+ -+static gboolean -+ess_bool_accumulator (GSignalInvocationHint *ihint, -+ GValue *out, -+ const GValue *in, -+ gpointer data) -+{ -+ gboolean v_boolean; -+ -+ v_boolean = g_value_get_boolean (in); -+ g_value_set_boolean (out, v_boolean); -+ -+ return !v_boolean; -+} -+ -+static void -+e_source_selector_class_init (ESourceSelectorClass *class) -+{ -+ GObjectClass *object_class; -+ GtkWidgetClass *widget_class; -+ GtkTreeViewClass *tree_view_class; -+ -+ g_type_class_add_private (class, sizeof (ESourceSelectorPrivate)); -+ -+ object_class = G_OBJECT_CLASS (class); -+ object_class->set_property = source_selector_set_property; -+ object_class->get_property = source_selector_get_property; -+ object_class->dispose = source_selector_dispose; -+ object_class->finalize = source_selector_finalize; -+ object_class->constructed = source_selector_constructed; -+ -+ widget_class = GTK_WIDGET_CLASS (class); -+ widget_class->button_press_event = source_selector_button_press_event; -+ widget_class->drag_leave = source_selector_drag_leave; -+ widget_class->drag_motion = source_selector_drag_motion; -+ widget_class->drag_drop = source_selector_drag_drop; -+ widget_class->drag_data_received = source_selector_drag_data_received; -+ widget_class->popup_menu = source_selector_popup_menu; -+ -+ tree_view_class = GTK_TREE_VIEW_CLASS (class); -+ tree_view_class->test_collapse_row = source_selector_test_collapse_row; -+ tree_view_class->row_expanded = source_selector_row_expanded; -+ -+ class->get_source_selected = source_selector_get_source_selected; -+ class->set_source_selected = source_selector_set_source_selected; -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_EXTENSION_NAME, -+ g_param_spec_string ( -+ "extension-name", -+ NULL, -+ NULL, -+ NULL, -+ G_PARAM_READWRITE | -+ G_PARAM_CONSTRUCT_ONLY | -+ G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_PRIMARY_SELECTION, -+ g_param_spec_object ( -+ "primary-selection", -+ NULL, -+ NULL, -+ E_TYPE_SOURCE, -+ G_PARAM_READWRITE | -+ G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_REGISTRY, -+ g_param_spec_object ( -+ "registry", -+ NULL, -+ NULL, -+ E_TYPE_SOURCE_REGISTRY, -+ G_PARAM_READWRITE | -+ G_PARAM_CONSTRUCT_ONLY | -+ G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_SHOW_COLORS, -+ g_param_spec_boolean ( -+ "show-colors", -+ NULL, -+ NULL, -+ TRUE, -+ G_PARAM_READWRITE | -+ G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property ( -+ object_class, -+ PROP_SHOW_TOGGLES, -+ g_param_spec_boolean ( -+ "show-toggles", -+ NULL, -+ NULL, -+ TRUE, -+ G_PARAM_READWRITE | -+ G_PARAM_STATIC_STRINGS)); -+ -+ signals[SELECTION_CHANGED] = g_signal_new ( -+ "selection-changed", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_LAST, -+ G_STRUCT_OFFSET (ESourceSelectorClass, selection_changed), -+ NULL, NULL, NULL, -+ G_TYPE_NONE, 0); -+ -+ /* XXX Consider this signal deprecated. Connect -+ * to "notify::primary-selection" instead. */ -+ signals[PRIMARY_SELECTION_CHANGED] = g_signal_new ( -+ "primary-selection-changed", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_LAST, -+ G_STRUCT_OFFSET (ESourceSelectorClass, primary_selection_changed), -+ NULL, NULL, NULL, -+ G_TYPE_NONE, 0); -+ -+ signals[POPUP_EVENT] = g_signal_new ( -+ "popup-event", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_LAST, -+ G_STRUCT_OFFSET (ESourceSelectorClass, popup_event), -+ ess_bool_accumulator, NULL, NULL, -+ G_TYPE_BOOLEAN, 2, G_TYPE_OBJECT, -+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); -+ -+ signals[DATA_DROPPED] = g_signal_new ( -+ "data-dropped", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_LAST, -+ G_STRUCT_OFFSET (ESourceSelectorClass, data_dropped), -+ NULL, NULL, NULL, -+ G_TYPE_BOOLEAN, 4, -+ GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE, -+ E_TYPE_SOURCE, -+ GDK_TYPE_DRAG_ACTION, -+ G_TYPE_UINT); -+} -+ -+static void -+e_source_selector_init (ESourceSelector *selector) -+{ -+ GHashTable *pending_writes; -+ GtkTreeViewColumn *column; -+ GtkTreeSelection *selection; -+ GtkCellRenderer *renderer; -+ GtkTreeStore *tree_store; -+ GtkTreeView *tree_view; -+ -+ pending_writes = g_hash_table_new_full ( -+ (GHashFunc) g_direct_hash, -+ (GEqualFunc) g_direct_equal, -+ (GDestroyNotify) g_object_unref, -+ (GDestroyNotify) pending_writes_destroy_source); -+ -+ selector->priv = E_SOURCE_SELECTOR_GET_PRIVATE (selector); -+ -+ selector->priv->pending_writes = pending_writes; -+ -+ selector->priv->main_context = g_main_context_get_thread_default (); -+ if (selector->priv->main_context != NULL) -+ g_main_context_ref (selector->priv->main_context); -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ -+ gtk_tree_view_set_search_column (tree_view, COLUMN_SOURCE); -+ gtk_tree_view_set_enable_search (tree_view, TRUE); -+ -+ selector->priv->toggled_last = FALSE; -+ selector->priv->select_new = FALSE; -+ selector->priv->show_colors = TRUE; -+ selector->priv->show_toggles = TRUE; -+ -+ selector->priv->source_index = g_hash_table_new_full ( -+ (GHashFunc) e_source_hash, -+ (GEqualFunc) e_source_equal, -+ (GDestroyNotify) g_object_unref, -+ (GDestroyNotify) gtk_tree_row_reference_free); -+ -+ tree_store = gtk_tree_store_new ( -+ NUM_COLUMNS, -+ G_TYPE_STRING, /* COLUMN_NAME */ -+ GDK_TYPE_COLOR, /* COLUMN_COLOR */ -+ G_TYPE_BOOLEAN, /* COLUMN_ACTIVE */ -+ G_TYPE_BOOLEAN, /* COLUMN_SHOW_COLOR */ -+ G_TYPE_BOOLEAN, /* COLUMN_SHOW_TOGGLE */ -+ G_TYPE_INT, /* COLUMN_WEIGHT */ -+ E_TYPE_SOURCE); /* COLUMN_SOURCE */ -+ -+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (tree_store)); -+ -+ column = gtk_tree_view_column_new (); -+ gtk_tree_view_append_column (tree_view, column); -+ -+ renderer = e_cell_renderer_color_new (); -+ g_object_set ( -+ G_OBJECT (renderer), "mode", -+ GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); -+ gtk_tree_view_column_pack_start (column, renderer, FALSE); -+ gtk_tree_view_column_add_attribute ( -+ column, renderer, "color", COLUMN_COLOR); -+ gtk_tree_view_column_add_attribute ( -+ column, renderer, "visible", COLUMN_SHOW_COLOR); -+ -+ renderer = e_cell_renderer_safe_toggle_new (); -+ gtk_tree_view_column_pack_start (column, renderer, FALSE); -+ gtk_tree_view_column_add_attribute ( -+ column, renderer, "active", COLUMN_ACTIVE); -+ gtk_tree_view_column_add_attribute ( -+ column, renderer, "visible", COLUMN_SHOW_TOGGLE); -+ g_signal_connect ( -+ renderer, "toggled", -+ G_CALLBACK (cell_toggled_callback), selector); -+ -+ renderer = gtk_cell_renderer_text_new (); -+ g_object_set ( -+ G_OBJECT (renderer), -+ "ellipsize", PANGO_ELLIPSIZE_END, NULL); -+ g_signal_connect_swapped ( -+ renderer, "edited", -+ G_CALLBACK (text_cell_edited_cb), selector); -+ gtk_tree_view_column_pack_start (column, renderer, TRUE); -+ gtk_tree_view_column_set_attributes ( -+ column, renderer, -+ "text", COLUMN_NAME, -+ "weight", COLUMN_WEIGHT, -+ NULL); -+ -+ selection = gtk_tree_view_get_selection (tree_view); -+ gtk_tree_selection_set_select_function ( -+ selection, (GtkTreeSelectionFunc) -+ selection_func, selector, NULL); -+ g_signal_connect_object ( -+ selection, "changed", -+ G_CALLBACK (selection_changed_callback), -+ G_OBJECT (selector), 0); -+ -+ gtk_tree_view_set_headers_visible (tree_view, FALSE); -+} -+ -+/** -+ * e_source_selector_new: -+ * @registry: an #ESourceRegistry -+ * @extension_name: the name of an #ESource extension -+ * -+ * Displays a list of sources from @registry having an extension named -+ * @extension_name. The sources are grouped by backend or groupware -+ * account, which are described by the parent source. -+ * -+ * Returns: a new #ESourceSelector -+ **/ -+GtkWidget * -+e_source_selector_new (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, "registry", registry, -+ "extension-name", extension_name, NULL); -+} -+ -+/** -+ * e_source_selector_get_registry: -+ * @selector: an #ESourceSelector -+ * -+ * Returns the #ESourceRegistry that @selector is getting sources from. -+ * -+ * Returns: an #ESourceRegistry -+ * -+ * Since: 3.6 -+ **/ -+ESourceRegistry * -+e_source_selector_get_registry (ESourceSelector *selector) -+{ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), NULL); -+ -+ return selector->priv->registry; -+} -+ -+/** -+ * e_source_selector_get_extension_name: -+ * @selector: an #ESourceSelector -+ * -+ * Returns the extension name used to filter which sources are displayed. -+ * -+ * Returns: the #ESource extension name -+ * -+ * Since: 3.6 -+ **/ -+const gchar * -+e_source_selector_get_extension_name (ESourceSelector *selector) -+{ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), NULL); -+ -+ return selector->priv->extension_name; -+} -+ -+/** -+ * e_source_selector_get_show_colors: -+ * @selector: an #ESourceSelector -+ * -+ * Returns whether colors are shown next to data sources. -+ * -+ * Returns: %TRUE if colors are being shown -+ * -+ * Since: 3.6 -+ **/ -+gboolean -+e_source_selector_get_show_colors (ESourceSelector *selector) -+{ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), FALSE); -+ -+ return selector->priv->show_colors; -+} -+ -+/** -+ * e_source_selector_set_show_colors: -+ * @selector: an #ESourceSelector -+ * @show_colors: whether to show colors -+ * -+ * Sets whether to show colors next to data sources. -+ * -+ * Since: 3.6 -+ **/ -+void -+e_source_selector_set_show_colors (ESourceSelector *selector, -+ gboolean show_colors) -+{ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ -+ if ((show_colors ? 1 : 0) == (selector->priv->show_colors ? 1 : 0)) -+ return; -+ -+ selector->priv->show_colors = show_colors; -+ -+ g_object_notify (G_OBJECT (selector), "show-colors"); -+ -+ source_selector_build_model (selector); -+} -+ -+/** -+ * e_source_selector_get_show_toggles: -+ * @selector: an #ESourceSelector -+ * -+ * Returns whether toggles are shown next to data sources. -+ * -+ * Returns: %TRUE if toggles are being shown -+ * -+ * Since: 3.6 -+ **/ -+gboolean -+e_source_selector_get_show_toggles (ESourceSelector *selector) -+{ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), FALSE); -+ -+ return selector->priv->show_toggles; -+} -+ -+/** -+ * e_source_selector_set_show_toggles: -+ * @selector: an #ESourceSelector -+ * @show_toggles: whether to show toggles -+ * -+ * Sets whether to show toggles next to data sources. -+ * -+ * Since: 3.6 -+ **/ -+void -+e_source_selector_set_show_toggles (ESourceSelector *selector, -+ gboolean show_toggles) -+{ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ -+ if ((show_toggles ? 1 : 0) == (selector->priv->show_toggles ? 1 : 0)) -+ return; -+ -+ selector->priv->show_toggles = show_toggles; -+ -+ g_object_notify (G_OBJECT (selector), "show-toggles"); -+ -+ source_selector_build_model (selector); -+} -+ -+/* Helper for e_source_selector_get_selection() */ -+static gboolean -+source_selector_check_selected (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer user_data) -+{ -+ ESource *source; -+ -+ struct { -+ ESourceSelector *selector; -+ GSList *list; -+ } *closure = user_data; -+ -+ gtk_tree_model_get (model, iter, COLUMN_SOURCE, &source, -1); -+ -+ if (e_source_selector_source_is_selected (closure->selector, source)) -+ closure->list = g_slist_prepend (closure->list, source); -+ else -+ g_object_unref (source); -+ -+ return FALSE; -+} -+ -+/** -+ * e_source_selector_get_selection: -+ * @selector: an #ESourceSelector -+ * -+ * Get the list of selected sources, i.e. those that were enabled through the -+ * corresponding checkboxes in the tree. -+ * -+ * Returns: A list of the ESources currently selected. The sources will -+ * be in the same order as they appear on the screen, and the list should be -+ * freed using e_source_selector_free_selection(). -+ **/ -+GSList * -+e_source_selector_get_selection (ESourceSelector *selector) -+{ -+ struct { -+ ESourceSelector *selector; -+ GSList *list; -+ } closure; -+ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), NULL); -+ -+ closure.selector = selector; -+ closure.list = NULL; -+ -+ gtk_tree_model_foreach ( -+ gtk_tree_view_get_model (GTK_TREE_VIEW (selector)), -+ (GtkTreeModelForeachFunc) source_selector_check_selected, -+ &closure); -+ -+ return g_slist_reverse (closure.list); -+} -+ -+/** -+ * e_source_list_free_selection: -+ * @list: A selection list returned by e_source_selector_get_selection(). -+ * -+ * Free the selection list. -+ **/ -+void -+e_source_selector_free_selection (GSList *list) -+{ -+ g_slist_foreach (list, (GFunc) g_object_unref, NULL); -+ g_slist_free (list); -+} -+ -+/** -+ * e_source_selector_set_select_new: -+ * @selector: An #ESourceSelector widget -+ * @state: A gboolean -+ * -+ * Set whether or not to select new sources added to @selector. -+ **/ -+void -+e_source_selector_set_select_new (ESourceSelector *selector, -+ gboolean state) -+{ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ -+ selector->priv->select_new = state; -+} -+ -+/** -+ * e_source_selector_select_source: -+ * @selector: An #ESourceSelector widget -+ * @source: An #ESource. -+ * -+ * Select @source in @selector. -+ **/ -+void -+e_source_selector_select_source (ESourceSelector *selector, -+ ESource *source) -+{ -+ ESourceSelectorClass *class; -+ GtkTreeRowReference *reference; -+ GHashTable *source_index; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ g_return_if_fail (E_IS_SOURCE (source)); -+ -+ /* Make sure the ESource is in our tree model. */ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ g_return_if_fail (gtk_tree_row_reference_valid (reference)); -+ -+ class = E_SOURCE_SELECTOR_GET_CLASS (selector); -+ g_return_if_fail (class->set_source_selected != NULL); -+ -+ class->set_source_selected (selector, source, TRUE); -+ -+ g_signal_emit (selector, signals[SELECTION_CHANGED], 0); -+} -+ -+/** -+ * e_source_selector_unselect_source: -+ * @selector: An #ESourceSelector widget -+ * @source: An #ESource. -+ * -+ * Unselect @source in @selector. -+ **/ -+void -+e_source_selector_unselect_source (ESourceSelector *selector, -+ ESource *source) -+{ -+ ESourceSelectorClass *class; -+ GtkTreeRowReference *reference; -+ GHashTable *source_index; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ g_return_if_fail (E_IS_SOURCE (source)); -+ -+ /* Make sure the ESource is in our tree model. */ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ g_return_if_fail (gtk_tree_row_reference_valid (reference)); -+ -+ class = E_SOURCE_SELECTOR_GET_CLASS (selector); -+ g_return_if_fail (class->set_source_selected != NULL); -+ -+ class->set_source_selected (selector, source, FALSE); -+ -+ g_signal_emit (selector, signals[SELECTION_CHANGED], 0); -+} -+ -+/** -+ * e_source_selector_select_exclusive: -+ * @selector: An #ESourceSelector widget -+ * @source: An #ESource. -+ * -+ * Select @source in @selector and unselect all others. -+ * -+ * Since: 2.30 -+ **/ -+void -+e_source_selector_select_exclusive (ESourceSelector *selector, -+ ESource *source) -+{ -+ ESourceSelectorClass *class; -+ GHashTable *source_index; -+ GHashTableIter iter; -+ gpointer key; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ g_return_if_fail (E_IS_SOURCE (source)); -+ -+ class = E_SOURCE_SELECTOR_GET_CLASS (selector); -+ g_return_if_fail (class->set_source_selected != NULL); -+ -+ source_index = selector->priv->source_index; -+ g_hash_table_iter_init (&iter, source_index); -+ -+ while (g_hash_table_iter_next (&iter, &key, NULL)) { -+ gboolean selected = e_source_equal (key, source); -+ class->set_source_selected (selector, key, selected); -+ } -+ -+ g_signal_emit (selector, signals[SELECTION_CHANGED], 0); -+} -+ -+/** -+ * e_source_selector_source_is_selected: -+ * @selector: An #ESourceSelector widget -+ * @source: An #ESource. -+ * -+ * Check whether @source is selected in @selector. -+ * -+ * Returns: %TRUE if @source is currently selected, %FALSE otherwise. -+ **/ -+gboolean -+e_source_selector_source_is_selected (ESourceSelector *selector, -+ ESource *source) -+{ -+ ESourceSelectorClass *class; -+ GtkTreeRowReference *reference; -+ GHashTable *source_index; -+ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), FALSE); -+ g_return_val_if_fail (E_IS_SOURCE (source), FALSE); -+ -+ /* Make sure the ESource is in our tree model. */ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ g_return_val_if_fail (gtk_tree_row_reference_valid (reference), FALSE); -+ -+ class = E_SOURCE_SELECTOR_GET_CLASS (selector); -+ g_return_val_if_fail (class->get_source_selected != NULL, FALSE); -+ -+ return class->get_source_selected (selector, source); -+} -+ -+/** -+ * e_source_selector_edit_primary_selection: -+ * @selector: An #ESourceSelector widget -+ * -+ * Allows the user to rename the primary selected source by opening an -+ * entry box directly in @selector. -+ * -+ * Since: 2.26 -+ **/ -+void -+e_source_selector_edit_primary_selection (ESourceSelector *selector) -+{ -+ GtkTreeRowReference *reference; -+ GtkTreeSelection *selection; -+ GtkTreeViewColumn *column; -+ GtkCellRenderer *renderer; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreePath *path = NULL; -+ GtkTreeIter iter; -+ GList *list; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ column = gtk_tree_view_get_column (tree_view, 0); -+ reference = selector->priv->saved_primary_selection; -+ selection = gtk_tree_view_get_selection (tree_view); -+ -+ if (reference != NULL) -+ path = gtk_tree_row_reference_get_path (reference); -+ else if (gtk_tree_selection_get_selected (selection, &model, &iter)) -+ path = gtk_tree_model_get_path (model, &iter); -+ -+ if (path == NULL) -+ return; -+ -+ /* XXX Because we stuff three renderers in a single column, -+ * we have to manually hunt for the text renderer. */ -+ renderer = NULL; -+ list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column)); -+ while (list != NULL) { -+ renderer = list->data; -+ if (GTK_IS_CELL_RENDERER_TEXT (renderer)) -+ break; -+ list = g_list_delete_link (list, list); -+ } -+ g_list_free (list); -+ -+ /* Make the text cell renderer editable, but only temporarily. -+ * We don't want editing to be activated by simply clicking on -+ * the source name. Too easy for accidental edits to occur. */ -+ g_object_set (renderer, "editable", TRUE, NULL); -+ gtk_tree_view_expand_to_path (tree_view, path); -+ gtk_tree_view_set_cursor_on_cell ( -+ tree_view, path, column, renderer, TRUE); -+ g_object_set (renderer, "editable", FALSE, NULL); -+ -+ gtk_tree_path_free (path); -+} -+ -+/** -+ * e_source_selector_ref_primary_selection: -+ * @selector: An #ESourceSelector widget -+ * -+ * Get the primary selected source. The primary selection is the one that is -+ * highlighted through the normal #GtkTreeView selection mechanism (as opposed -+ * to the "normal" selection, which is the set of source whose checkboxes are -+ * checked). -+ * -+ * The returned #ESource is referenced for thread-safety and must be -+ * unreferenced with g_object_unref() when finished with it. -+ * -+ * Returns: The selected source. -+ * -+ * Since: 3.6 -+ **/ -+ESource * -+e_source_selector_ref_primary_selection (ESourceSelector *selector) -+{ -+ ESource *source; -+ GtkTreeRowReference *reference; -+ GtkTreeSelection *selection; -+ GtkTreeView *tree_view; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ const gchar *extension_name; -+ gboolean have_iter = FALSE; -+ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), NULL); -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ model = gtk_tree_view_get_model (tree_view); -+ selection = gtk_tree_view_get_selection (tree_view); -+ -+ reference = selector->priv->saved_primary_selection; -+ -+ if (gtk_tree_row_reference_valid (reference)) { -+ GtkTreePath *path; -+ -+ path = gtk_tree_row_reference_get_path (reference); -+ have_iter = gtk_tree_model_get_iter (model, &iter, path); -+ gtk_tree_path_free (path); -+ } -+ -+ if (!have_iter) -+ have_iter = gtk_tree_selection_get_selected ( -+ selection, NULL, &iter); -+ -+ if (!have_iter) -+ return NULL; -+ -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ -+ if (!e_source_has_extension (source, extension_name)) { -+ g_object_unref (source); -+ return NULL; -+ } -+ -+ return source; -+} -+ -+/** -+ * e_source_selector_set_primary_selection: -+ * @selector: an #ESourceSelector widget -+ * @source: an #ESource to select -+ * -+ * Highlights @source in @selector. The highlighted #ESource is called -+ * the primary selection. -+ * -+ * Do not confuse this function with e_source_selector_select_source(), -+ * which activates the check box next to an #ESource's display name in -+ * @selector. This function does not alter the check box. -+ **/ -+void -+e_source_selector_set_primary_selection (ESourceSelector *selector, -+ ESource *source) -+{ -+ GHashTable *source_index; -+ GtkTreeRowReference *reference; -+ GtkTreeSelection *selection; -+ GtkTreeView *tree_view; -+ GtkTreePath *child_path; -+ GtkTreePath *parent_path; -+ const gchar *extension_name; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ g_return_if_fail (E_IS_SOURCE (source)); -+ -+ tree_view = GTK_TREE_VIEW (selector); -+ selection = gtk_tree_view_get_selection (tree_view); -+ -+ source_index = selector->priv->source_index; -+ reference = g_hash_table_lookup (source_index, source); -+ -+ /* XXX Maybe we should return a success/fail boolean? */ -+ if (!gtk_tree_row_reference_valid (reference)) -+ return; -+ -+ extension_name = e_source_selector_get_extension_name (selector); -+ -+ /* Return silently if attempting to select a parent node -+ * lacking the expected extension (e.g. On This Computer). */ -+ if (!e_source_has_extension (source, extension_name)) -+ return; -+ -+ /* We block the signal because this all needs to be atomic */ -+ g_signal_handlers_block_matched ( -+ selection, G_SIGNAL_MATCH_FUNC, -+ 0, 0, NULL, selection_changed_callback, NULL); -+ gtk_tree_selection_unselect_all (selection); -+ g_signal_handlers_unblock_matched ( -+ selection, G_SIGNAL_MATCH_FUNC, -+ 0, 0, NULL, selection_changed_callback, NULL); -+ -+ clear_saved_primary_selection (selector); -+ -+ child_path = gtk_tree_row_reference_get_path (reference); -+ -+ parent_path = gtk_tree_path_copy (child_path); -+ gtk_tree_path_up (parent_path); -+ -+ if (gtk_tree_view_row_expanded (tree_view, parent_path)) { -+ gtk_tree_selection_select_path (selection, child_path); -+ } else { -+ selector->priv->saved_primary_selection = -+ gtk_tree_row_reference_copy (reference); -+ g_signal_emit (selector, signals[PRIMARY_SELECTION_CHANGED], 0); -+ g_object_notify (G_OBJECT (selector), "primary-selection"); -+ } -+ -+ gtk_tree_path_free (child_path); -+ gtk_tree_path_free (parent_path); -+} -+ -+/** -+ * e_source_selector_ref_source_by_path: -+ * @selector: an #ESourceSelector -+ * @path: a #GtkTreePath -+ * -+ * Returns the #ESource object at @path, or %NULL if @path is invalid. -+ * -+ * The returned #ESource is referenced for thread-safety and must be -+ * unreferenced with g_object_unref() when finished with it. -+ * -+ * Returns: the #ESource object at @path, or %NULL -+ * -+ * Since: 3.6 -+ **/ -+ESource * -+e_source_selector_ref_source_by_path (ESourceSelector *selector, -+ GtkTreePath *path) -+{ -+ ESource *source = NULL; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ -+ g_return_val_if_fail (E_IS_SOURCE_SELECTOR (selector), NULL); -+ g_return_val_if_fail (path != NULL, NULL); -+ -+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector)); -+ -+ if (gtk_tree_model_get_iter (model, &iter, path)) -+ gtk_tree_model_get (model, &iter, COLUMN_SOURCE, &source, -1); -+ -+ return source; -+} -+ -+/** -+ * e_source_selector_queue_write: -+ * @selector: an #ESourceSelecetor -+ * @source: an #ESource with changes to be written -+ * -+ * Queues a main loop idle callback to write changes to @source back to -+ * the D-Bus registry service. -+ * -+ * Since: 3.6 -+ **/ -+void -+e_source_selector_queue_write (ESourceSelector *selector, -+ ESource *source) -+{ -+ GSource *idle_source; -+ GHashTable *pending_writes; -+ GMainContext *main_context; -+ AsyncContext *async_context; -+ -+ g_return_if_fail (E_IS_SOURCE_SELECTOR (selector)); -+ g_return_if_fail (E_IS_SOURCE (source)); -+ -+ main_context = selector->priv->main_context; -+ pending_writes = selector->priv->pending_writes; -+ -+ idle_source = g_hash_table_lookup (pending_writes, source); -+ if (idle_source != NULL && !g_source_is_destroyed (idle_source)) -+ return; -+ -+ async_context = g_slice_new0 (AsyncContext); -+ async_context->selector = g_object_ref (selector); -+ async_context->source = g_object_ref (source); -+ -+ /* Set a higher priority so this idle source runs before our -+ * source_selector_cancel_write() signal handler, which will -+ * cancel this idle source. Cancellation is the right thing -+ * to do when receiving changes from OTHER registry clients, -+ * but we don't want to cancel our own changes. -+ * -+ * XXX This might be an argument for using etags. -+ */ -+ idle_source = g_idle_source_new (); -+ g_hash_table_insert ( -+ pending_writes, -+ g_object_ref (source), -+ g_source_ref (idle_source)); -+ g_source_set_callback ( -+ idle_source, -+ source_selector_write_idle_cb, -+ async_context, -+ (GDestroyNotify) async_context_free); -+ g_source_set_priority (idle_source, G_PRIORITY_HIGH_IDLE); -+ g_source_attach (idle_source, main_context); -+ g_source_unref (idle_source); -+} -+ -diff --git a/src/event-factories/e-source-selector.h b/src/event-factories/e-source-selector.h -new file mode 100644 -index 0000000..b6d3770 ---- /dev/null -+++ b/src/event-factories/e-source-selector.h -@@ -0,0 +1,137 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -+/* e-source-selector.h -+ * -+ * 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: Ettore Perazzoli <ettore@ximian.com> -+ */ -+ -+#ifndef E_SOURCE_SELECTOR_H -+#define E_SOURCE_SELECTOR_H -+ -+#include <gtk/gtk.h> -+#include <libedataserver/libedataserver.h> -+ -+/* Standard GObject macros */ -+#define E_TYPE_SOURCE_SELECTOR \ -+ (e_source_selector_get_type ()) -+#define E_SOURCE_SELECTOR(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST \ -+ ((obj), E_TYPE_SOURCE_SELECTOR, ESourceSelector)) -+#define E_SOURCE_SELECTOR_CLASS(cls) \ -+ (G_TYPE_CHECK_CLASS_CAST \ -+ ((cls), E_TYPE_SOURCE_SELECTOR, ESourceSelectorClass)) -+#define E_IS_SOURCE_SELECTOR(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE \ -+ ((obj), E_TYPE_SOURCE_SELECTOR)) -+#define E_IS_SOURCE_SELECTOR_CLASS(cls) \ -+ (G_TYPE_CHECK_CLASS_TYPE \ -+ ((cls), E_TYPE_SOURCE_SELECTOR)) -+#define E_SOURCE_SELECTOR_GET_CLASS(obj) \ -+ (G_TYPE_INSTANCE_GET_CLASS \ -+ ((obj), E_TYPE_SOURCE_SELECTOR, ESourceSelectorClass)) -+ -+G_BEGIN_DECLS -+ -+typedef struct _ESourceSelector ESourceSelector; -+typedef struct _ESourceSelectorClass ESourceSelectorClass; -+typedef struct _ESourceSelectorPrivate ESourceSelectorPrivate; -+ -+struct _ESourceSelector { -+ GtkTreeView parent; -+ ESourceSelectorPrivate *priv; -+}; -+ -+struct _ESourceSelectorClass { -+ GtkTreeViewClass parent_class; -+ -+ /* Methods */ -+ gboolean (*get_source_selected) (ESourceSelector *selector, -+ ESource *source); -+ void (*set_source_selected) (ESourceSelector *selector, -+ ESource *source, -+ gboolean selected); -+ -+ /* Signals */ -+ void (*selection_changed) (ESourceSelector *selector); -+ void (*primary_selection_changed) -+ (ESourceSelector *selector); -+ gboolean (*popup_event) (ESourceSelector *selector, -+ ESource *primary, -+ GdkEventButton *event); -+ gboolean (*data_dropped) (ESourceSelector *selector, -+ GtkSelectionData *data, -+ ESource *destination, -+ GdkDragAction action, -+ guint target_info); -+ -+ gpointer padding1; -+ gpointer padding2; -+ gpointer padding3; -+}; -+ -+GType e_source_selector_get_type (void); -+GtkWidget * e_source_selector_new (ESourceRegistry *registry, -+ const gchar *extension_name); -+ESourceRegistry * -+ e_source_selector_get_registry (ESourceSelector *selector); -+const gchar * e_source_selector_get_extension_name -+ (ESourceSelector *selector); -+gboolean e_source_selector_get_show_colors -+ (ESourceSelector *selector); -+void e_source_selector_set_show_colors -+ (ESourceSelector *selector, -+ gboolean show_colors); -+gboolean e_source_selector_get_show_toggles -+ (ESourceSelector *selector); -+void e_source_selector_set_show_toggles -+ (ESourceSelector *selector, -+ gboolean show_toggles); -+void e_source_selector_select_source (ESourceSelector *selector, -+ ESource *source); -+void e_source_selector_unselect_source -+ (ESourceSelector *selector, -+ ESource *source); -+void e_source_selector_select_exclusive -+ (ESourceSelector *selector, -+ ESource *source); -+gboolean e_source_selector_source_is_selected -+ (ESourceSelector *selector, -+ ESource *source); -+GSList * e_source_selector_get_selection (ESourceSelector *selector); -+void e_source_selector_free_selection -+ (GSList *list); -+void e_source_selector_set_select_new -+ (ESourceSelector *selector, -+ gboolean state); -+void e_source_selector_edit_primary_selection -+ (ESourceSelector *selector); -+ESource * e_source_selector_ref_primary_selection -+ (ESourceSelector *selector); -+void e_source_selector_set_primary_selection -+ (ESourceSelector *selector, -+ ESource *source); -+ESource * e_source_selector_ref_source_by_path -+ (ESourceSelector *selector, -+ GtkTreePath *path); -+void e_source_selector_queue_write (ESourceSelector *selector, -+ ESource *source); -+ -+G_END_DECLS -+ -+#endif /* E_SOURCE_SELECTOR_H */ --- -cgit v0.9.1 diff --git a/community/almanah/update-gtkspell3-support.patch b/community/almanah/update-gtkspell3-support.patch deleted file mode 100644 index aa2a81159..000000000 --- a/community/almanah/update-gtkspell3-support.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 114c4f78ac9882be51c4154751760bd4fea48403 Mon Sep 17 00:00:00 2001 -From: Álvaro Peña <alvaropg@gmail.com> -Date: Wed, 06 Feb 2013 10:12:54 +0000 -Subject: Update GtkSpell 3 support - ---- -diff --git a/configure.ac b/configure.ac -index b89ba74..fbe6889 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -95,7 +95,7 @@ AC_SUBST(EVO_LIBS) - - dnl Spell checking - if test $spell_checking = "true"; then -- PKG_CHECK_MODULES(SPELL_CHECKING, gtkspell-3.0) -+ PKG_CHECK_MODULES(SPELL_CHECKING, gtkspell3-3.0) - AC_SUBST(SPELL_CHECKING_CFLAGS) - AC_SUBST(SPELL_CHECKING_LIBS) - fi -diff --git a/src/main-window.c b/src/main-window.c -index fb931e1..2fe01ef 100644 ---- a/src/main-window.c -+++ b/src/main-window.c -@@ -1109,7 +1109,7 @@ mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar_button, AlmanahMain - AlmanahEventManager *event_manager; - GDate calendar_date; - #ifdef ENABLE_SPELL_CHECKING -- GtkSpell *gtkspell; -+ GtkSpellChecker *gtkspell; - #endif /* ENABLE_SPELL_CHECKING */ - AlmanahMainWindowPrivate *priv = main_window->priv; - AlmanahEntry *entry; -@@ -1166,9 +1166,9 @@ mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar_button, AlmanahMain - - #ifdef ENABLE_SPELL_CHECKING - /* Ensure the spell-checking is updated */ -- gtkspell = gtkspell_get_from_text_view (priv->entry_view); -+ gtkspell = gtk_spell_checker_get_from_text_view (priv->entry_view); - if (gtkspell != NULL) { -- gtkspell_recheck_all (gtkspell); -+ gtk_spell_checker_recheck_all (gtkspell); - gtk_widget_queue_draw (GTK_WIDGET (priv->entry_view)); - } - #endif /* ENABLE_SPELL_CHECKING */ -@@ -1326,13 +1326,13 @@ enable_spell_checking (AlmanahMainWindow *self, GError **error) - { - AlmanahApplication *application; - GSettings *settings; -- GtkSpell *gtkspell; -+ GtkSpellChecker *gtkspell; - gchar *spelling_language; - GtkTextTagTable *table; - GtkTextTag *tag; - - /* Bail out if spell checking's already enabled */ -- if (gtkspell_get_from_text_view (self->priv->entry_view) != NULL) -+ if (gtk_spell_checker_get_from_text_view (self->priv->entry_view) != NULL) - return TRUE; - - /* If spell checking wasn't already enabled, we have a dummy gtkspell-misspelled text tag to destroy */ -@@ -1353,7 +1353,9 @@ enable_spell_checking (AlmanahMainWindow *self, GError **error) - spelling_language = NULL; - } - -- gtkspell = gtkspell_new_attach (self->priv->entry_view, spelling_language, error); -+ gtkspell = gtk_spell_checker_new (); -+ gtk_spell_checker_set_language (gtkspell, spelling_language, error); -+ gtk_spell_checker_attach (gtkspell, self->priv->entry_view); - g_free (spelling_language); - - if (gtkspell == NULL) -@@ -1364,13 +1366,13 @@ enable_spell_checking (AlmanahMainWindow *self, GError **error) - static void - disable_spell_checking (AlmanahMainWindow *self) - { -- GtkSpell *gtkspell; -+ GtkSpellChecker *gtkspell; - GtkTextTagTable *table; - GtkTextTag *tag; - -- gtkspell = gtkspell_get_from_text_view (self->priv->entry_view); -+ gtkspell = gtk_spell_checker_get_from_text_view (self->priv->entry_view); - if (gtkspell != NULL) -- gtkspell_detach (gtkspell); -+ gtk_spell_checker_detach (gtkspell); - - /* Remove the old gtkspell-misspelling text tag */ - table = gtk_text_buffer_get_tag_table (self->priv->entry_buffer); --- -cgit v0.9.1 |