diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2012-12-10 21:09:59 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2012-12-13 03:33:43 +0800 |
commit | d09d8de870b6697c8a8b262e7e077b871a69b315 (patch) | |
tree | 3b718882e7a0bb0a996daf2967a033d91714c9b5 /widgets | |
parent | b61331ed03ac1c7a9b8614e25510040b9c60ae02 (diff) | |
download | gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.gz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.zst gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.zip |
Consolidate base utility libraries into libeutil.
Evolution consists of entirely too many small utility libraries, which
increases linking and loading time, places a burden on higher layers of
the application (e.g. modules) which has to remember to link to all the
small in-tree utility libraries, and makes it difficult to generate API
documentation for these utility libraries in one Gtk-Doc module.
Merge the following utility libraries under the umbrella of libeutil,
and enforce a single-include policy on libeutil so we can reorganize
the files as desired without disrupting its pseudo-public API.
libemail-utils/libemail-utils.la
libevolution-utils/libevolution-utils.la
filter/libfilter.la
widgets/e-timezone-dialog/libetimezonedialog.la
widgets/menus/libmenus.la
widgets/misc/libemiscwidgets.la
widgets/table/libetable.la
widgets/text/libetext.la
This also merges libedataserverui from the Evolution-Data-Server module,
since Evolution is its only consumer nowadays, and I'd like to make some
improvements to those APIs without concern for backward-compatibility.
And finally, start a Gtk-Doc module for libeutil. It's going to be a
project just getting all the symbols _listed_ much less _documented_.
But the skeletal structure is in place and I'm off to a good start.
Diffstat (limited to 'widgets')
356 files changed, 0 insertions, 134663 deletions
diff --git a/widgets/LICENSE b/widgets/LICENSE deleted file mode 100644 index b1f6ae08a4..0000000000 --- a/widgets/LICENSE +++ /dev/null @@ -1 +0,0 @@ -This code is released under the terms of the GNU GPL. diff --git a/widgets/Makefile.am b/widgets/Makefile.am deleted file mode 100644 index 137446c00e..0000000000 --- a/widgets/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -SUBDIRS = \ - misc \ - text \ - e-timezone-dialog \ - table \ - menus - --include $(top_srcdir)/git.mk diff --git a/widgets/e-timezone-dialog/Makefile.am b/widgets/e-timezone-dialog/Makefile.am deleted file mode 100644 index 4ae74a24f5..0000000000 --- a/widgets/e-timezone-dialog/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -privsolib_LTLIBRARIES = libetimezonedialog.la - -libetimezonedialog_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_UIDIR=\""$(uidir)"\" \ - -DG_LOG_DOMAIN=__FILE__ \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -libetimezonedialog_la_SOURCES = \ - e-timezone-dialog.c \ - e-timezone-dialog.h - -libetimezonedialog_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libetimezonedialog_la_LIBADD = \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -ui_DATA = e-timezone-dialog.ui - -EXTRA_DIST = $(ui_DATA) - --include $(top_srcdir)/git.mk diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.c b/widgets/e-timezone-dialog/e-timezone-dialog.c deleted file mode 100644 index 32194b4871..0000000000 --- a/widgets/e-timezone-dialog/e-timezone-dialog.c +++ /dev/null @@ -1,870 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> -#include <string.h> -#include <glib/gi18n.h> -#include <misc/e-map.h> - -#include <libecal/libecal.h> - -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" - -#include "e-timezone-dialog.h" - -#ifdef G_OS_WIN32 -#ifdef gmtime_r -#undef gmtime_r -#endif -#ifdef localtime_r -#undef localtime_r -#endif - -/* The gmtime() and localtime() in Microsoft's C library are MT-safe */ -#define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0) -#define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0) -#endif - -#define E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA 0xc070a0ff -#define E_TIMEZONE_DIALOG_MAP_POINT_HOVER_RGBA 0xffff60ff -#define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_1_RGBA 0xff60e0ff -#define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_2_RGBA 0x000000ff - -#define E_TIMEZONE_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TIMEZONE_DIALOG, ETimezoneDialogPrivate)) - -struct _ETimezoneDialogPrivate { - /* The selected timezone. May be NULL for a 'local time' (i.e. when - * the displayed name is ""). */ - icaltimezone *zone; - - GtkBuilder *builder; - - EMapPoint *point_selected; - EMapPoint *point_hover; - - EMap *map; - - /* The timeout used to flash the nearest point. */ - guint timeout_id; - - /* Widgets from the UI file */ - GtkWidget *app; - GtkWidget *table; - GtkWidget *map_window; - GtkWidget *timezone_combo; - GtkWidget *preview_label; -}; - -static void e_timezone_dialog_dispose (GObject *object); - -static gboolean get_widgets (ETimezoneDialog *etd); -static gboolean on_map_timeout (gpointer data); -static gboolean on_map_motion (GtkWidget *widget, - GdkEventMotion *event, - gpointer data); -static gboolean on_map_leave (GtkWidget *widget, - GdkEventCrossing *event, - gpointer data); -static gboolean on_map_visibility_changed (GtkWidget *w, - GdkEventVisibility *event, - gpointer data); -static gboolean on_map_button_pressed (GtkWidget *w, - GdkEvent *button_event, - gpointer data); - -static icaltimezone * get_zone_from_point (ETimezoneDialog *etd, - EMapPoint *point); -static void set_map_timezone (ETimezoneDialog *etd, - icaltimezone *zone); -static void on_combo_changed (GtkComboBox *combo, - ETimezoneDialog *etd); - -static void timezone_combo_get_active_text (GtkComboBox *combo, - gchar **zone_name); -static gboolean timezone_combo_set_active_text (GtkComboBox *combo, - const gchar *zone_name); - -static void map_destroy_cb (gpointer data, - GObject *where_object_was); - -G_DEFINE_TYPE (ETimezoneDialog, e_timezone_dialog, G_TYPE_OBJECT) - -/* Class initialization function for the event editor */ -static void -e_timezone_dialog_class_init (ETimezoneDialogClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ETimezoneDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = e_timezone_dialog_dispose; -} - -/* Object initialization function for the event editor */ -static void -e_timezone_dialog_init (ETimezoneDialog *etd) -{ - etd->priv = E_TIMEZONE_DIALOG_GET_PRIVATE (etd); -} - -/* Dispose handler for the event editor */ -static void -e_timezone_dialog_dispose (GObject *object) -{ - ETimezoneDialogPrivate *priv; - - priv = E_TIMEZONE_DIALOG_GET_PRIVATE (object); - - /* Destroy the actual dialog. */ - if (priv->app != NULL) { - gtk_widget_destroy (priv->app); - priv->app = NULL; - } - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - if (priv->builder) { - g_object_unref (priv->builder); - priv->builder = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_timezone_dialog_parent_class)->dispose (object); -} - -static void -e_timezone_dialog_add_timezones (ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - icalarray *zones; - GtkComboBox *combo; - GList *l, *list_items = NULL; - GtkListStore *list_store; - GtkTreeIter iter; - GtkCellRenderer *cell; - GtkCssProvider *css_provider; - GtkStyleContext *style_context; - GHashTable *index; - const gchar *css; - gint i; - GError *error = NULL; - - priv = etd->priv; - - /* Get the array of builtin timezones. */ - zones = icaltimezone_get_builtin_timezones (); - - for (i = 0; i < zones->num_elements; i++) { - icaltimezone *zone; - gchar *location; - - zone = icalarray_element_at (zones, i); - - location = _(icaltimezone_get_location (zone)); - - e_map_add_point ( - priv->map, location, - icaltimezone_get_longitude (zone), - icaltimezone_get_latitude (zone), - E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); - - list_items = g_list_prepend (list_items, location); - } - - list_items = g_list_sort (list_items, (GCompareFunc) g_utf8_collate); - - /* Put the "UTC" entry at the top of the combo's list. */ - list_items = g_list_prepend (list_items, _("UTC")); - - combo = GTK_COMBO_BOX (priv->timezone_combo); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start ((GtkCellLayout *) combo, cell, TRUE); - gtk_cell_layout_set_attributes ((GtkCellLayout *) combo, cell, "text", 0, NULL); - - list_store = gtk_list_store_new (1, G_TYPE_STRING); - index = g_hash_table_new (g_str_hash, g_str_equal); - for (l = list_items, i = 0; l != NULL; l = l->next, ++i) { - gtk_list_store_append (list_store, &iter); - gtk_list_store_set (list_store, &iter, 0, (gchar *)(l->data), -1); - g_hash_table_insert (index, (gchar *)(l->data), GINT_TO_POINTER (i)); - } - - g_object_set_data_full ( - G_OBJECT (list_store), "index", index, - (GDestroyNotify) g_hash_table_destroy); - - gtk_combo_box_set_model (combo, (GtkTreeModel *) list_store); - - css_provider = gtk_css_provider_new (); - css = "GtkComboBox { -GtkComboBox-appears-as-list: 1; }"; - gtk_css_provider_load_from_data (css_provider, css, -1, &error); - style_context = gtk_widget_get_style_context (priv->timezone_combo); - if (error == NULL) { - gtk_style_context_add_provider ( - style_context, - GTK_STYLE_PROVIDER (css_provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - } else { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - g_object_unref (css_provider); - - g_list_free (list_items); -} - -ETimezoneDialog * -e_timezone_dialog_construct (ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - GtkWidget *widget; - GtkWidget *map; - - g_return_val_if_fail (etd != NULL, NULL); - g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), NULL); - - priv = etd->priv; - - /* Load the content widgets */ - - priv->builder = gtk_builder_new (); - e_load_ui_builder_definition (priv->builder, "e-timezone-dialog.ui"); - - if (!get_widgets (etd)) { - g_message ( - "%s(): Could not find all widgets in the XML file!", - G_STRFUNC); - goto error; - } - - widget = gtk_dialog_get_content_area (GTK_DIALOG (priv->app)); - gtk_container_set_border_width (GTK_CONTAINER (widget), 0); - - widget = gtk_dialog_get_action_area (GTK_DIALOG (priv->app)); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - - priv->map = e_map_new (); - map = GTK_WIDGET (priv->map); - - g_object_weak_ref (G_OBJECT (map), map_destroy_cb, priv); - - gtk_widget_set_events ( - map, - gtk_widget_get_events (map) | - GDK_LEAVE_NOTIFY_MASK | - GDK_VISIBILITY_NOTIFY_MASK); - - e_timezone_dialog_add_timezones (etd); - - gtk_container_add (GTK_CONTAINER (priv->map_window), map); - gtk_widget_show (map); - - /* Ensure a reasonable minimum amount of map is visible */ - gtk_widget_set_size_request (priv->map_window, 200, 200); - - g_signal_connect ( - map, "motion-notify-event", - G_CALLBACK (on_map_motion), etd); - g_signal_connect ( - map, "leave-notify-event", - G_CALLBACK (on_map_leave), etd); - g_signal_connect ( - map, "visibility-notify-event", - G_CALLBACK (on_map_visibility_changed), etd); - g_signal_connect ( - map, "button-press-event", - G_CALLBACK (on_map_button_pressed), etd); - - g_signal_connect ( - priv->timezone_combo, "changed", - G_CALLBACK (on_combo_changed), etd); - - return etd; - - error: - - g_object_unref (etd); - return NULL; -} - -#if 0 -static gint -get_local_offset (void) -{ - time_t now = time (NULL), t_gmt, t_local; - struct tm gmt, local; - gint diff; - - gmtime_r (&now, &gmt); - localtime_r (&now, &local); - t_gmt = mktime (&gmt); - t_local = mktime (&local); - diff = t_local - t_gmt; - - return diff; -} -#endif - -static icaltimezone * -get_local_timezone (void) -{ - icaltimezone *zone; - gchar *location; - - tzset (); - location = e_cal_system_timezone_get_location (); - - if (location) - zone = icaltimezone_get_builtin_timezone (location); - else - zone = icaltimezone_get_utc_timezone (); - - g_free (location); - - return zone; -} - -/* Gets the widgets from the XML file and returns if they are all available. - * For the widgets whose values can be simply set with e-dialog-utils, it does - * that as well. - */ -static gboolean -get_widgets (ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - GtkBuilder *builder; - - priv = etd->priv; - builder = etd->priv->builder; - - priv->app = e_builder_get_widget (builder, "timezone-dialog"); - priv->map_window = e_builder_get_widget (builder, "map-window"); - priv->timezone_combo = e_builder_get_widget (builder, "timezone-combo"); - priv->table = e_builder_get_widget (builder, "timezone-table"); - priv->preview_label = e_builder_get_widget (builder, "preview-label"); - - return (priv->app - && priv->map_window - && priv->timezone_combo - && priv->table - && priv->preview_label); -} - -/** - * e_timezone_dialog_new: - * - * Creates a new event editor dialog. - * - * Return value: A newly-created event editor dialog, or NULL if the event - * editor could not be created. - **/ -ETimezoneDialog * -e_timezone_dialog_new (void) -{ - ETimezoneDialog *etd; - - etd = E_TIMEZONE_DIALOG (g_object_new (E_TYPE_TIMEZONE_DIALOG, NULL)); - return e_timezone_dialog_construct (E_TIMEZONE_DIALOG (etd)); -} - -static void -format_utc_offset (gint utc_offset, - gchar *buffer) -{ - const gchar *sign = "+"; - gint hours, minutes, seconds; - - if (utc_offset < 0) { - utc_offset = -utc_offset; - sign = "-"; - } - - hours = utc_offset / 3600; - minutes = (utc_offset % 3600) / 60; - seconds = utc_offset % 60; - - /* Sanity check. Standard timezone offsets shouldn't be much more - * than 12 hours, and daylight saving shouldn't change it by more - * than a few hours. (The maximum offset is 15 hours 56 minutes - * at present.) */ - if (hours < 0 || hours >= 24 || minutes < 0 || minutes >= 60 - || seconds < 0 || seconds >= 60) { - fprintf ( - stderr, "Warning: Strange timezone offset: " - "H:%i M:%i S:%i\n", hours, minutes, seconds); - } - - if (hours == 0 && minutes == 0 && seconds == 0) - strcpy (buffer, _("UTC")); - else if (seconds == 0) - sprintf ( - buffer, "%s %s%02i:%02i", - _("UTC"), sign, hours, minutes); - else - sprintf ( - buffer, "%s %s%02i:%02i:%02i", - _("UTC"), sign, hours, minutes, seconds); -} - -static gchar * -zone_display_name_with_offset (icaltimezone *zone) -{ - const gchar *display_name; - struct tm local; - struct icaltimetype tt; - gint offset; - gchar buffer[100]; - time_t now = time (NULL); - - gmtime_r ((const time_t *) &now, &local); - tt = tm_to_icaltimetype (&local, TRUE); - offset = icaltimezone_get_utc_offset (zone, &tt, NULL); - - format_utc_offset (offset, buffer); - - display_name = icaltimezone_get_display_name (zone); - if (icaltimezone_get_builtin_timezone (display_name)) - display_name = _(display_name); - - return g_strdup_printf ("%s (%s)", display_name, buffer); -} - -static const gchar * -zone_display_name (icaltimezone *zone) -{ - const gchar *display_name; - - display_name = icaltimezone_get_display_name (zone); - if (icaltimezone_get_builtin_timezone (display_name)) - display_name = _(display_name); - - return display_name; -} - -/* This flashes the currently selected timezone in the map. */ -static gboolean -on_map_timeout (gpointer data) -{ - ETimezoneDialog *etd; - ETimezoneDialogPrivate *priv; - - etd = E_TIMEZONE_DIALOG (data); - priv = etd->priv; - - if (!priv->point_selected) - return TRUE; - - if (e_map_point_get_color_rgba (priv->point_selected) - == E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_1_RGBA) - e_map_point_set_color_rgba ( - priv->map, priv->point_selected, - E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_2_RGBA); - else - e_map_point_set_color_rgba ( - priv->map, priv->point_selected, - E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_1_RGBA); - - return TRUE; -} - -static gboolean -on_map_motion (GtkWidget *widget, - GdkEventMotion *event, - gpointer data) -{ - ETimezoneDialog *etd; - ETimezoneDialogPrivate *priv; - gdouble longitude, latitude; - icaltimezone *new_zone; - gchar *display = NULL; - - etd = E_TIMEZONE_DIALOG (data); - priv = etd->priv; - - e_map_window_to_world ( - priv->map, (gdouble) event->x, (gdouble) event->y, - &longitude, &latitude); - - if (priv->point_hover && priv->point_hover != priv->point_selected) - e_map_point_set_color_rgba ( - priv->map, priv->point_hover, - E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); - - priv->point_hover = e_map_get_closest_point ( - priv->map, longitude, - latitude, TRUE); - - if (priv->point_hover != priv->point_selected) - e_map_point_set_color_rgba ( - priv->map, priv->point_hover, - E_TIMEZONE_DIALOG_MAP_POINT_HOVER_RGBA); - - new_zone = get_zone_from_point (etd, priv->point_hover); - - display = zone_display_name_with_offset (new_zone); - gtk_label_set_text (GTK_LABEL (priv->preview_label), display); - - g_free (display); - - return TRUE; -} - -static gboolean -on_map_leave (GtkWidget *widget, - GdkEventCrossing *event, - gpointer data) -{ - ETimezoneDialog *etd; - ETimezoneDialogPrivate *priv; - - etd = E_TIMEZONE_DIALOG (data); - priv = etd->priv; - - /* We only want to reset the hover point if this is a normal leave - * event. For some reason we are getting leave events when the - * button is pressed in the map, which causes problems. */ - if (event->mode != GDK_CROSSING_NORMAL) - return FALSE; - - if (priv->point_hover && priv->point_hover != priv->point_selected) - e_map_point_set_color_rgba ( - priv->map, priv->point_hover, - E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); - - timezone_combo_set_active_text ( - GTK_COMBO_BOX (priv->timezone_combo), - zone_display_name (priv->zone)); - gtk_label_set_text (GTK_LABEL (priv->preview_label), ""); - - priv->point_hover = NULL; - - return FALSE; -} - -static gboolean -on_map_visibility_changed (GtkWidget *w, - GdkEventVisibility *event, - gpointer data) -{ - ETimezoneDialog *etd; - ETimezoneDialogPrivate *priv; - - etd = E_TIMEZONE_DIALOG (data); - priv = etd->priv; - - if (event->state != GDK_VISIBILITY_FULLY_OBSCURED) { - /* Map is visible, at least partly, so make sure we flash the - * selected point. */ - if (!priv->timeout_id) - priv->timeout_id = g_timeout_add (100, on_map_timeout, etd); - } else { - /* Map is invisible, so don't waste resources on the timeout.*/ - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - } - - return FALSE; -} - -static gboolean -on_map_button_pressed (GtkWidget *w, - GdkEvent *button_event, - gpointer data) -{ - ETimezoneDialog *etd; - ETimezoneDialogPrivate *priv; - guint event_button = 0; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - gdouble longitude, latitude; - - etd = E_TIMEZONE_DIALOG (data); - priv = etd->priv; - - gdk_event_get_button (button_event, &event_button); - gdk_event_get_coords (button_event, &event_x_win, &event_y_win); - - e_map_window_to_world ( - priv->map, event_x_win, event_y_win, &longitude, &latitude); - - if (event_button != 1) { - e_map_zoom_out (priv->map); - } else { - if (e_map_get_magnification (priv->map) <= 1.0) - e_map_zoom_to_location ( - priv->map, longitude, latitude); - - if (priv->point_selected) - e_map_point_set_color_rgba ( - priv->map, - priv->point_selected, - E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); - priv->point_selected = priv->point_hover; - - priv->zone = get_zone_from_point (etd, priv->point_selected); - timezone_combo_set_active_text ( - GTK_COMBO_BOX (priv->timezone_combo), - zone_display_name (priv->zone)); - } - - return TRUE; -} - -/* Returns the translated timezone location of the given EMapPoint, - * e.g. "Europe/London". */ -static icaltimezone * -get_zone_from_point (ETimezoneDialog *etd, - EMapPoint *point) -{ - icalarray *zones; - gdouble longitude, latitude; - gint i; - - if (point == NULL) - return NULL; - - e_map_point_get_location (point, &longitude, &latitude); - - /* Get the array of builtin timezones. */ - zones = icaltimezone_get_builtin_timezones (); - - for (i = 0; i < zones->num_elements; i++) { - icaltimezone *zone; - gdouble zone_longitude, zone_latitude; - - zone = icalarray_element_at (zones, i); - zone_longitude = icaltimezone_get_longitude (zone); - zone_latitude = icaltimezone_get_latitude (zone); - - if (zone_longitude - 0.005 <= longitude && - zone_longitude + 0.005 >= longitude && - zone_latitude - 0.005 <= latitude && - zone_latitude + 0.005 >= latitude) - { - return zone; - } - } - - g_return_val_if_reached (NULL); -} - -/** - * e_timezone_dialog_get_timezone: - * @etd: the timezone dialog - * - * Return value: the currently-selected timezone, or %NULL if no timezone - * is selected. - **/ -icaltimezone * -e_timezone_dialog_get_timezone (ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - - g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), NULL); - - priv = etd->priv; - - return priv->zone; -} - -/** - * e_timezone_dialog_set_timezone: - * @etd: the timezone dialog - * @zone: the timezone - * - * Sets the timezone of @etd to @zone. Updates the display name and - * selected location. The caller must ensure that @zone is not freed - * before @etd is destroyed. - **/ - -void -e_timezone_dialog_set_timezone (ETimezoneDialog *etd, - icaltimezone *zone) -{ - ETimezoneDialogPrivate *priv; - gchar *display = NULL; - - g_return_if_fail (E_IS_TIMEZONE_DIALOG (etd)); - - if (!zone) - zone = get_local_timezone (); - - if (zone) - display = zone_display_name_with_offset (zone); - - priv = etd->priv; - - priv->zone = zone; - - gtk_label_set_text ( - GTK_LABEL (priv->preview_label), - zone ? display : ""); - timezone_combo_set_active_text ( - GTK_COMBO_BOX (priv->timezone_combo), - zone ? zone_display_name (zone) : ""); - - set_map_timezone (etd, zone); - g_free (display); -} - -GtkWidget * -e_timezone_dialog_get_toplevel (ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - - g_return_val_if_fail (etd != NULL, NULL); - g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), NULL); - - priv = etd->priv; - - return priv->app; -} - -static void -set_map_timezone (ETimezoneDialog *etd, - icaltimezone *zone) -{ - ETimezoneDialogPrivate *priv; - EMapPoint *point; - gdouble zone_longitude, zone_latitude; - - priv = etd->priv; - - if (zone) { - zone_longitude = icaltimezone_get_longitude (zone); - zone_latitude = icaltimezone_get_latitude (zone); - point = e_map_get_closest_point ( - priv->map, - zone_longitude, - zone_latitude, - FALSE); - } else - point = NULL; - - if (priv->point_selected) - e_map_point_set_color_rgba ( - priv->map, priv->point_selected, - E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); - - priv->point_selected = point; -} - -static void -on_combo_changed (GtkComboBox *combo_box, - ETimezoneDialog *etd) -{ - ETimezoneDialogPrivate *priv; - gchar *new_zone_name; - icalarray *zones; - icaltimezone *map_zone = NULL; - gchar *location; - gint i; - - priv = etd->priv; - - timezone_combo_get_active_text ( - GTK_COMBO_BOX (priv->timezone_combo), &new_zone_name); - - if (!new_zone_name || !*new_zone_name) - priv->zone = NULL; - else if (!g_utf8_collate (new_zone_name, _("UTC"))) - priv->zone = icaltimezone_get_utc_timezone (); - else { - priv->zone = NULL; - - zones = icaltimezone_get_builtin_timezones (); - for (i = 0; i < zones->num_elements; i++) { - map_zone = icalarray_element_at (zones, i); - location = _(icaltimezone_get_location (map_zone)); - if (!g_utf8_collate (new_zone_name, location)) { - priv->zone = map_zone; - break; - } - } - } - - set_map_timezone (etd, map_zone); - - g_free (new_zone_name); -} - -static void -timezone_combo_get_active_text (GtkComboBox *combo, - gchar **zone_name) -{ - GtkTreeModel *list_store; - GtkTreeIter iter; - - list_store = gtk_combo_box_get_model (combo); - - /* Get the active iter in the list */ - if (gtk_combo_box_get_active_iter (combo, &iter)) - gtk_tree_model_get (list_store, &iter, 0, zone_name, -1); - else - *zone_name = NULL; -} - -static gboolean -timezone_combo_set_active_text (GtkComboBox *combo, - const gchar *zone_name) -{ - GtkTreeModel *list_store; - GHashTable *index; - gpointer id = NULL; - - list_store = gtk_combo_box_get_model (combo); - index = (GHashTable *) g_object_get_data (G_OBJECT (list_store), "index"); - - if (zone_name && *zone_name) - id = g_hash_table_lookup (index, zone_name); - - gtk_combo_box_set_active (combo, GPOINTER_TO_INT (id)); - - return (id != NULL); -} - -static void -map_destroy_cb (gpointer data, - GObject *where_object_was) -{ - - ETimezoneDialogPrivate *priv = data; - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - return; -} diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.h b/widgets/e-timezone-dialog/e-timezone-dialog.h deleted file mode 100644 index fa10098675..0000000000 --- a/widgets/e-timezone-dialog/e-timezone-dialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Evolution calendar - Timezone selector dialog - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TIMEZONE_DIALOG_H -#define E_TIMEZONE_DIALOG_H - -#include <gtk/gtk.h> -#include <libical/ical.h> - -/* Standard GObject macros */ -#define E_TYPE_TIMEZONE_DIALOG \ - (e_timezone_dialog_get_type ()) -#define E_TIMEZONE_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TIMEZONE_DIALOG, ETimezoneDialog)) -#define E_TIMEZONE_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TIMEZONE_DIALOG, ETimezoneDialogClass)) -#define E_IS_TIMEZONE_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TIMEZONE_DIALOG)) -#define E_IS_TIMEZONE_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TIMEZONE_DIALOG)) -#define E_TIMEZONE_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TIMEZONE_DIALOG, ETimezoneDialogClass)) - -typedef struct _ETimezoneDialog ETimezoneDialog; -typedef struct _ETimezoneDialogClass ETimezoneDialogClass; -typedef struct _ETimezoneDialogPrivate ETimezoneDialogPrivate; - -struct _ETimezoneDialog { - GObject object; - ETimezoneDialogPrivate *priv; -}; - -struct _ETimezoneDialogClass { - GObjectClass parent_class; -}; - -GType e_timezone_dialog_get_type (void); -ETimezoneDialog * - e_timezone_dialog_construct (ETimezoneDialog *etd); -ETimezoneDialog * - e_timezone_dialog_new (void); -icaltimezone * e_timezone_dialog_get_timezone (ETimezoneDialog *etd); -void e_timezone_dialog_set_timezone (ETimezoneDialog *etd, - icaltimezone *zone); -GtkWidget * e_timezone_dialog_get_toplevel (ETimezoneDialog *etd); - -#endif /* E_TIMEZONE_DIALOG_H */ diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.ui b/widgets/e-timezone-dialog/e-timezone-dialog.ui deleted file mode 100644 index 5a23ec180e..0000000000 --- a/widgets/e-timezone-dialog/e-timezone-dialog.ui +++ /dev/null @@ -1,312 +0,0 @@ -<?xml version="1.0"?> -<!--*- mode: xml -*--> -<interface> - <object class="GtkDialog" id="timezone-dialog"> - <property name="title" translatable="yes">Select a Time Zone</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="default_width">500</property> - <property name="default_height">400</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="decorated">True</property> - <property name="skip_taskbar_hint">False</property> - <property name="skip_pager_hint">False</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox1"> - <property name="orientation">vertical</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <object class="GtkButton" id="cancel-button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - </object> - </child> - <child> - <object class="GtkButton" id="ok-button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - </object> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - <child> - <object class="GtkBox" id="timezone-table"> - <property name="orientation">vertical</property> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkBox" id="hbox3"> - <property name="orientation">horizontal</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-dialog-info</property> - <property name="icon_size">6</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Use the left mouse button to zoom in on an area of the map and select a time zone. -Use the right mouse button to zoom out.</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Time Zones</property> - <property name="use_underline">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkBox" id="hbox2"> - <property name="orientation">horizontal</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label5"> - <property name="visible">True</property> - <property name="label" translatable="no"> </property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkBox" id="vbox1"> - <property name="orientation">vertical</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="map-window"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> - <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="preview-label"> - <property name="visible">True</property> - <property name="label" translatable="no">America/New_York</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Selection</property> - <property name="use_underline">True</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">timezone-combo</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkBox" id="hbox1"> - <property name="orientation">horizontal</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label6"> - <property name="visible">True</property> - <property name="label" translatable="no"> </property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="timezone-combo"> - <property name="visible">True</property> - <property name="add_tearoffs">False</property> - <property name="focus_on_click">True</property> - <accessibility> - - </accessibility> - <child internal-child="accessible"> - <object class="AtkObject" id="a11y-timezone-combo1"> - <property name="AtkObject::accessible_name" translatable="yes">Timezone drop-down combination box</property> - </object> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-2">cancel-button</action-widget> - <action-widget response="-3">ok-button</action-widget> - </action-widgets> - </object> -</interface> diff --git a/widgets/menus/Makefile.am b/widgets/menus/Makefile.am deleted file mode 100644 index aa3bb75b73..0000000000 --- a/widgets/menus/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -privsolib_LTLIBRARIES = libmenus.la - -libmenus_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_UIDIR=\""$(uidir)"\" \ - -DG_LOG_DOMAIN=\"menus\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -libmenus_la_SOURCES = \ - gal-define-views-dialog.c \ - gal-define-views-model.c \ - gal-view-collection.c \ - gal-view-etable.c \ - gal-view-factory-etable.c \ - gal-view-factory.c \ - gal-view-instance-save-as-dialog.c \ - gal-view-instance.c \ - gal-view-new-dialog.c \ - gal-view.c - -ui_DATA = \ - gal-define-views.ui \ - gal-view-new-dialog.ui \ - gal-view-instance-save-as-dialog.ui - -libmenusincludedir = $(privincludedir)/menus - -libmenusinclude_HEADERS = \ - gal-define-views-dialog.h \ - gal-define-views-model.h \ - gal-view-collection.h \ - gal-view-etable.h \ - gal-view-factory-etable.h \ - gal-view-factory.h \ - gal-view-instance-save-as-dialog.h \ - gal-view-instance.h \ - gal-view-new-dialog.h \ - gal-view.h - -libmenus_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libmenus_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/widgets/table/libetable.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -icons = -EXTRA_DIST = \ - $(icons) \ - $(ui_DATA) - --include $(top_srcdir)/git.mk diff --git a/widgets/menus/gal-define-views-dialog.c b/widgets/menus/gal-define-views-dialog.c deleted file mode 100644 index 974cdad323..0000000000 --- a/widgets/menus/gal-define-views-dialog.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> - -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" - -#include "gal-define-views-dialog.h" -#include "gal-define-views-model.h" -#include "gal-view-new-dialog.h" - -static void gal_define_views_dialog_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void gal_define_views_dialog_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void gal_define_views_dialog_dispose (GObject *object); - -/* The properties we support */ -enum { - PROP_0, - PROP_COLLECTION -}; - -enum { - COL_GALVIEW_NAME, - COL_GALVIEW_DATA -}; - -typedef struct { - gchar *title; - - GtkTreeView *treeview; - GtkTreeModel *model; - - GalDefineViewsDialog *names; -} GalDefineViewsDialogChild; - -G_DEFINE_TYPE (GalDefineViewsDialog, gal_define_views_dialog, GTK_TYPE_DIALOG) - -static void -gal_define_views_dialog_class_init (GalDefineViewsDialogClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - object_class->set_property = gal_define_views_dialog_set_property; - object_class->get_property = gal_define_views_dialog_get_property; - object_class->dispose = gal_define_views_dialog_dispose; - - g_object_class_install_property ( - object_class, - PROP_COLLECTION, - g_param_spec_object ( - "collection", - "Collection", - NULL, - GAL_VIEW_COLLECTION_TYPE, - G_PARAM_READWRITE)); -} - -/* Button callbacks */ - -static void -gdvd_button_new_dialog_callback (GtkWidget *widget, - gint id, - GalDefineViewsDialog *dialog) -{ - gchar *name; - GtkTreeIter iter; - GalView *view; - GalViewCollectionItem *item; - GalViewFactory *factory; - - switch (id) { - case GTK_RESPONSE_OK: - g_object_get ( - widget, - "name", &name, - "factory", &factory, - NULL); - - if (name && factory) { - g_strchomp (name); - if (*name != '\0') { - view = gal_view_factory_new_view (factory, name); - gal_view_collection_append (dialog->collection, view); - - item = dialog->collection->view_data[dialog->collection->view_count - 1]; - gtk_list_store_append (GTK_LIST_STORE (dialog->model), &iter); - gtk_list_store_set ( - GTK_LIST_STORE (dialog->model), &iter, - COL_GALVIEW_NAME, name, - COL_GALVIEW_DATA, item, - -1); - - if (view && GAL_VIEW_GET_CLASS (view)->edit) - gal_view_edit (view, GTK_WINDOW (dialog)); - g_object_unref (view); - } - } - g_object_unref (factory); - g_free (name); - break; - } - gtk_widget_destroy (widget); -} - -static void -gdvd_button_new_callback (GtkWidget *widget, - GalDefineViewsDialog *dialog) -{ - GtkWidget *view_new_dialog = gal_view_new_dialog_new (dialog->collection); - gtk_window_set_transient_for (GTK_WINDOW (view_new_dialog), GTK_WINDOW (dialog)); - g_signal_connect ( - view_new_dialog, "response", - G_CALLBACK (gdvd_button_new_dialog_callback), dialog); - gtk_widget_show (view_new_dialog); -} - -static void -gdvd_button_modify_callback (GtkWidget *widget, - GalDefineViewsDialog *dialog) -{ - GtkTreeIter iter; - GalViewCollectionItem *item; - - if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (dialog->treeview), - &dialog->model, - &iter)) { - gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1); - - g_return_if_fail (item && !item->built_in); - - gal_view_edit (item->view, GTK_WINDOW (dialog)); - } -} - -static void -gdvd_button_delete_callback (GtkWidget *widget, - GalDefineViewsDialog *dialog) -{ - gint row; - GtkTreeIter iter; - GtkTreePath *path; - GtkTreeSelection *selection; - GalViewCollectionItem *item; - - selection = gtk_tree_view_get_selection (dialog->treeview); - - if (gtk_tree_selection_get_selected (selection, - &dialog->model, - &iter)) { - gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1); - - g_return_if_fail (item && !item->built_in); - - for (row = 0; row < dialog->collection->view_count; row++) { - if (item == dialog->collection->view_data[row]) { - gal_view_collection_delete_view (dialog->collection, row); - path = gtk_tree_model_get_path (dialog->model, &iter); - gtk_list_store_remove (GTK_LIST_STORE (dialog->model), &iter); - - if (gtk_tree_path_prev (path)) { - gtk_tree_model_get_iter (dialog->model, &iter, path); - } else { - gtk_tree_model_get_iter_first (dialog->model, &iter); - } - - gtk_tree_selection_select_iter (selection, &iter); - break; - } - } - } -} - -static void -gdvd_selection_changed_callback (GtkTreeSelection *selection, - GalDefineViewsDialog *dialog) -{ - GtkWidget *button; - GtkTreeIter iter; - GalViewCollectionItem *item = NULL; - GalViewClass *gvclass = NULL; - - if (gtk_tree_selection_get_selected (selection, &dialog->model, &iter)) { - gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1); - - if (item && item->view) - gvclass = GAL_VIEW_GET_CLASS (item->view); - } - - button = e_builder_get_widget (dialog->builder, "button-delete"); - gtk_widget_set_sensitive (GTK_WIDGET (button), item && !item->built_in); - - button = e_builder_get_widget (dialog->builder, "button-modify"); - gtk_widget_set_sensitive (GTK_WIDGET (button), item && !item->built_in && gvclass && gvclass->edit != NULL); -} - -static void -gdvd_connect_signal (GalDefineViewsDialog *dialog, - const gchar *widget_name, - const gchar *signal, - GCallback handler) -{ - GtkWidget *widget; - - widget = e_builder_get_widget (dialog->builder, widget_name); - - if (widget) - g_signal_connect (widget, signal, handler, dialog); -} - -static void -dialog_response (GalDefineViewsDialog *dialog, - gint response_id, - gpointer data) -{ - gal_view_collection_save (dialog->collection); -} - -static void -gal_define_views_dialog_init (GalDefineViewsDialog *dialog) -{ - GtkWidget *content_area; - GtkWidget *parent; - GtkWidget *widget; - GtkTreeSelection *selection; - - dialog->collection = NULL; - - dialog->builder = gtk_builder_new (); - e_load_ui_builder_definition (dialog->builder, "gal-define-views.ui"); - - widget = e_builder_get_widget (dialog->builder, "table-top"); - if (!widget) { - return; - } - - g_object_ref (widget); - - parent = gtk_widget_get_parent (widget); - gtk_container_remove (GTK_CONTAINER (parent), widget); - gtk_window_set_default_size (GTK_WINDOW (dialog), 360, 270); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 6); - gtk_container_set_border_width (GTK_CONTAINER (widget), 6); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - g_object_unref (widget); - - gtk_dialog_add_buttons ( - GTK_DIALOG (dialog), - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - dialog->treeview = GTK_TREE_VIEW (e_builder_get_widget (dialog->builder, "treeview1")); - gtk_tree_view_set_reorderable (GTK_TREE_VIEW (dialog->treeview), FALSE); - gtk_tree_view_set_headers_visible (dialog->treeview, TRUE); - - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - - gdvd_connect_signal (dialog, "button-new", "clicked", G_CALLBACK (gdvd_button_new_callback)); - gdvd_connect_signal (dialog, "button-modify", "clicked", G_CALLBACK (gdvd_button_modify_callback)); - gdvd_connect_signal (dialog, "button-delete", "clicked", G_CALLBACK (gdvd_button_delete_callback)); - g_signal_connect ( - dialog, "response", - G_CALLBACK (dialog_response), NULL); - - selection = gtk_tree_view_get_selection (dialog->treeview); - g_signal_connect ( - selection, "changed", - G_CALLBACK (gdvd_selection_changed_callback), dialog); - gdvd_selection_changed_callback (selection, dialog); - - gtk_widget_show (GTK_WIDGET (dialog)); -} - -static void -gal_define_views_dialog_dispose (GObject *object) -{ - GalDefineViewsDialog *gal_define_views_dialog = GAL_DEFINE_VIEWS_DIALOG (object); - - if (gal_define_views_dialog->builder) - g_object_unref (gal_define_views_dialog->builder); - gal_define_views_dialog->builder = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_define_views_dialog_parent_class)->dispose (object); -} - -static void -gal_define_views_dialog_set_collection (GalDefineViewsDialog *dialog, - GalViewCollection *collection) -{ - gint i; - GtkListStore *store; - GtkCellRenderer *renderer; - dialog->collection = collection; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); - - for (i = 0; i < collection->view_count; i++) { - GalViewCollectionItem *item = collection->view_data[i]; - GtkTreeIter iter; - - /* hide built in views */ - /*if (item->built_in == 1) - continue;*/ - - gchar *title = NULL; - title = e_str_without_underscores (item->title); - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - COL_GALVIEW_NAME, title, - COL_GALVIEW_DATA, item, - -1); - - g_free (title); - } - - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (store), - COL_GALVIEW_NAME, GTK_SORT_ASCENDING); - - /* attaching treeview to model */ - gtk_tree_view_set_model (dialog->treeview, GTK_TREE_MODEL (store)); - gtk_tree_view_set_search_column (dialog->treeview, COL_GALVIEW_NAME); - - dialog->model = GTK_TREE_MODEL (store); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes ( - dialog->treeview, - COL_GALVIEW_NAME, _("Name"), - renderer, "text", COL_GALVIEW_NAME, - NULL); - - /* set sort column */ - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (dialog->model), - COL_GALVIEW_NAME, GTK_SORT_ASCENDING); - - if (dialog->builder) { - GtkWidget *widget = e_builder_get_widget (dialog->builder, "label-views"); - if (widget && GTK_IS_LABEL (widget)) { - if (collection->title) { - gchar *text = g_strdup_printf ( - _("Define Views for %s"), - collection->title); - gtk_label_set_text ( - GTK_LABEL (widget), - text); - gtk_window_set_title (GTK_WINDOW (dialog), text); - g_free (text); - } else { - gtk_label_set_text ( - GTK_LABEL (widget), - _("Define Views")); - gtk_window_set_title ( - GTK_WINDOW (dialog), - _("Define Views")); - } - } - } -} - -/** - * gal_define_views_dialog_new - * - * Returns a new dialog for defining views. - * - * Returns: The GalDefineViewsDialog. - */ -GtkWidget * -gal_define_views_dialog_new (GalViewCollection *collection) -{ - GtkWidget *widget = g_object_new (GAL_TYPE_DEFINE_VIEWS_DIALOG, NULL); - gal_define_views_dialog_set_collection (GAL_DEFINE_VIEWS_DIALOG (widget), collection); - return widget; -} - -static void -gal_define_views_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GalDefineViewsDialog *dialog; - - dialog = GAL_DEFINE_VIEWS_DIALOG (object); - - switch (property_id) { - case PROP_COLLECTION: - if (g_value_get_object (value)) - gal_define_views_dialog_set_collection (dialog, GAL_VIEW_COLLECTION (g_value_get_object (value))); - else - gal_define_views_dialog_set_collection (dialog, NULL); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - return; - } -} - -static void -gal_define_views_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GalDefineViewsDialog *dialog; - - dialog = GAL_DEFINE_VIEWS_DIALOG (object); - - switch (property_id) { - case PROP_COLLECTION: - g_value_set_object (value, dialog->collection); - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} diff --git a/widgets/menus/gal-define-views-dialog.h b/widgets/menus/gal-define-views-dialog.h deleted file mode 100644 index feb349e2d3..0000000000 --- a/widgets/menus/gal-define-views-dialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_DEFINE_VIEWS_DIALOG_H -#define GAL_DEFINE_VIEWS_DIALOG_H - -#include <gtk/gtk.h> -#include <menus/gal-view-collection.h> - -/* Standard GObject macros */ -#define GAL_TYPE_DEFINE_VIEWS_DIALOG \ - (gal_define_views_dialog_get_type ()) -#define GAL_DEFINE_VIEWS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_DEFINE_VIEWS_DIALOG, GalDefineViewsDialog)) -#define GAL_DEFINE_VIEWS_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_DEFINE_VIEWS_DIALOG, GalDefineViewsDialogClass)) -#define GAL_IS_DEFINE_VIEWS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_DEFINE_VIEWS_DIALOG)) -#define GAL_IS_DEFINE_VIEWS_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_DEFINE_VIEWS_DIALOG)) -#define GAL_DEFINE_VIEWS_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_DEFINE_VIEWS_DIALOG, GalDefineViewsDialogClass)) - -G_BEGIN_DECLS - -typedef struct _GalDefineViewsDialog GalDefineViewsDialog; -typedef struct _GalDefineViewsDialogClass GalDefineViewsDialogClass; - -struct _GalDefineViewsDialog { - GtkDialog parent; - - /* item specific fields */ - GtkBuilder *builder; - GtkTreeView *treeview; - GtkTreeModel *model; - - GalViewCollection *collection; -}; - -struct _GalDefineViewsDialogClass { - GtkDialogClass parent_class; -}; - -GType gal_define_views_dialog_get_type (void); -GtkWidget * gal_define_views_dialog_new (GalViewCollection *collection); - -G_END_DECLS - -#endif /* GAL_DEFINE_VIEWS_DIALOG_H */ diff --git a/widgets/menus/gal-define-views-model.c b/widgets/menus/gal-define-views-model.c deleted file mode 100644 index d9432d24cc..0000000000 --- a/widgets/menus/gal-define-views-model.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "gal-define-views-model.h" - -G_DEFINE_TYPE (GalDefineViewsModel, gal_define_views_model, E_TYPE_TABLE_MODEL) - -enum { - PROP_0, - PROP_EDITABLE, - PROP_COLLECTION -}; - -static void -gal_define_views_model_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GalDefineViewsModel *model; - - model = GAL_DEFINE_VIEWS_MODEL (object); - - switch (property_id) { - case PROP_EDITABLE: - model->editable = g_value_get_boolean (value); - return; - - case PROP_COLLECTION: - e_table_model_pre_change (E_TABLE_MODEL (object)); - if (g_value_get_object (value)) - model->collection = GAL_VIEW_COLLECTION ( - g_value_get_object (value)); - else - model->collection = NULL; - e_table_model_changed (E_TABLE_MODEL (object)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -gal_define_views_model_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GalDefineViewsModel *model; - - model = GAL_DEFINE_VIEWS_MODEL (object); - - switch (property_id) { - case PROP_EDITABLE: - g_value_set_boolean (value, model->editable); - return; - - case PROP_COLLECTION: - g_value_set_object (value, model->collection); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -gdvm_dispose (GObject *object) -{ - GalDefineViewsModel *model = GAL_DEFINE_VIEWS_MODEL (object); - - if (model->collection) - g_object_unref (model->collection); - model->collection = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_define_views_model_parent_class)->dispose (object); -} - -/* This function returns the number of columns in our ETableModel. */ -static gint -gdvm_col_count (ETableModel *etc) -{ - return 1; -} - -/* This function returns the number of rows in our ETableModel. */ -static gint -gdvm_row_count (ETableModel *etc) -{ - GalDefineViewsModel *views = GAL_DEFINE_VIEWS_MODEL (etc); - if (views->collection) - return gal_view_collection_get_count (views->collection); - else - return 0; -} - -/* This function returns the value at a particular point in our ETableModel. */ -static gpointer -gdvm_value_at (ETableModel *etc, - gint col, - gint row) -{ - GalDefineViewsModel *views = GAL_DEFINE_VIEWS_MODEL (etc); - GalView *view; - const gchar *value; - - view = gal_view_collection_get_view (views->collection, row); - value = gal_view_get_title (view); - - return (gpointer) ((value != NULL) ? value : ""); -} - -/* This function sets the value at a particular point in our ETableModel. */ -static void -gdvm_set_value_at (ETableModel *etc, - gint col, - gint row, - gconstpointer val) -{ - GalDefineViewsModel *views = GAL_DEFINE_VIEWS_MODEL (etc); - if (views->editable) { - GalView *view; - - view = gal_view_collection_get_view (views->collection, row); - - e_table_model_pre_change (etc); - gal_view_set_title (view, val); - e_table_model_cell_changed (etc, col, row); - } -} - -/* This function returns whether a particular cell is editable. */ -static gboolean -gdvm_is_cell_editable (ETableModel *etc, - gint col, - gint row) -{ - return GAL_DEFINE_VIEWS_MODEL (etc)->editable; -} - -static void -gdvm_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ -} - -/* This function duplicates the value passed to it. */ -static gpointer -gdvm_duplicate_value (ETableModel *etc, - gint col, - gconstpointer value) -{ - return g_strdup (value); -} - -/* This function frees the value passed to it. */ -static void -gdvm_free_value (ETableModel *etc, - gint col, - gpointer value) -{ - g_free (value); -} - -static gpointer -gdvm_initialize_value (ETableModel *etc, - gint col) -{ - return g_strdup (""); -} - -static gboolean -gdvm_value_is_empty (ETableModel *etc, - gint col, - gconstpointer value) -{ - return !(value && *(gchar *) value); -} - -static gchar * -gdvm_value_to_string (ETableModel *etc, - gint col, - gconstpointer value) -{ - return g_strdup (value); -} - -/** - * gal_define_views_model_append - * @model: The model to add to. - * @view: The view to add. - * - * Adds the given view to the gal define views model. - */ -void -gal_define_views_model_append (GalDefineViewsModel *model, - GalView *view) -{ - ETableModel *etm = E_TABLE_MODEL (model); - - e_table_model_pre_change (etm); - gal_view_collection_append (model->collection, view); - e_table_model_row_inserted ( - etm, gal_view_collection_get_count (model->collection) - 1); -} - -static void -gal_define_views_model_class_init (GalDefineViewsModelClass *class) -{ - ETableModelClass *model_class = E_TABLE_MODEL_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = gdvm_dispose; - object_class->set_property = gal_define_views_model_set_property; - object_class->get_property = gal_define_views_model_get_property; - - g_object_class_install_property ( - object_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_COLLECTION, - g_param_spec_object ( - "collection", - "Collection", - NULL, - GAL_VIEW_COLLECTION_TYPE, - G_PARAM_READWRITE)); - - model_class->column_count = gdvm_col_count; - model_class->row_count = gdvm_row_count; - model_class->value_at = gdvm_value_at; - model_class->set_value_at = gdvm_set_value_at; - model_class->is_cell_editable = gdvm_is_cell_editable; - model_class->append_row = gdvm_append_row; - model_class->duplicate_value = gdvm_duplicate_value; - model_class->free_value = gdvm_free_value; - model_class->initialize_value = gdvm_initialize_value; - model_class->value_is_empty = gdvm_value_is_empty; - model_class->value_to_string = gdvm_value_to_string; -} - -static void -gal_define_views_model_init (GalDefineViewsModel *model) -{ - model->collection = NULL; -} - -/** - * gal_define_views_model_new - * - * Returns a new define views model. This is a list of views as an - * ETable for use in the GalDefineViewsDialog. - * - * Returns: The new GalDefineViewsModel. - */ -ETableModel * -gal_define_views_model_new (void) -{ - GalDefineViewsModel *et; - - et = g_object_new (GAL_DEFINE_VIEWS_MODEL_TYPE, NULL); - - return E_TABLE_MODEL (et); -} - -/** - * gal_define_views_model_get_view: - * @model: The GalDefineViewsModel. - * @n: Which view to get. - * - * Gets the nth view. - * - * Returns: The view. - */ -GalView * -gal_define_views_model_get_view (GalDefineViewsModel *model, - gint n) -{ - return gal_view_collection_get_view (model->collection, n); -} - -/** - * gal_define_views_model_delete_view: - * @model: The GalDefineViewsModel. - * @n: Which view to delete. - * - * Deletes the nth view. - */ -void -gal_define_views_model_delete_view (GalDefineViewsModel *model, - gint n) -{ - e_table_model_pre_change (E_TABLE_MODEL (model)); - gal_view_collection_delete_view (model->collection, n); - e_table_model_row_deleted (E_TABLE_MODEL (model), n); -} - -/** - * gal_define_views_model_copy_view: - * @model: The GalDefineViewsModel. - * @n: Which view to copy. - * - * Copys the nth view. - */ -void -gal_define_views_model_copy_view (GalDefineViewsModel *model, - gint n) -{ - ETableModel *etm = E_TABLE_MODEL (model); - e_table_model_pre_change (etm); - gal_view_collection_copy_view (model->collection, n); - e_table_model_row_inserted ( - etm, gal_view_collection_get_count (model->collection) - 1); -} diff --git a/widgets/menus/gal-define-views-model.h b/widgets/menus/gal-define-views-model.h deleted file mode 100644 index cc7b7a5aa4..0000000000 --- a/widgets/menus/gal-define-views-model.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _GAL_DEFINE_VIEWS_MODEL_H_ -#define _GAL_DEFINE_VIEWS_MODEL_H_ - -#include <table/e-table-model.h> -#include <widgets/menus/gal-view.h> -#include <widgets/menus/gal-view-collection.h> - -G_BEGIN_DECLS - -#define GAL_DEFINE_VIEWS_MODEL_TYPE (gal_define_views_model_get_type ()) -#define GAL_DEFINE_VIEWS_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_DEFINE_VIEWS_MODEL_TYPE, GalDefineViewsModel)) -#define GAL_DEFINE_VIEWS_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_DEFINE_VIEWS_MODEL_TYPE, GalDefineViewsModelClass)) -#define GAL_IS_DEFINE_VIEWS_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_DEFINE_VIEWS_MODEL_TYPE)) -#define GAL_IS_DEFINE_VIEWS_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_DEFINE_VIEWS_MODEL_TYPE)) - -typedef struct { - ETableModel parent; - - /* item specific fields */ - GalViewCollection *collection; - - guint editable : 1; -} GalDefineViewsModel; - -typedef struct { - ETableModelClass parent_class; -} GalDefineViewsModelClass; - -GType gal_define_views_model_get_type (void); -ETableModel *gal_define_views_model_new (void); - -void gal_define_views_model_append (GalDefineViewsModel *model, - GalView *view); -GalView *gal_define_views_model_get_view (GalDefineViewsModel *model, - gint i); -void gal_define_views_model_delete_view (GalDefineViewsModel *model, - gint i); -void gal_define_views_model_copy_view (GalDefineViewsModel *model, - gint i); - -G_END_DECLS - -#endif /* _GAL_DEFINE_VIEWS_MODEL_H_ */ diff --git a/widgets/menus/gal-define-views.ui b/widgets/menus/gal-define-views.ui deleted file mode 100644 index b3314aa4ee..0000000000 --- a/widgets/menus/gal-define-views.ui +++ /dev/null @@ -1,177 +0,0 @@ -<?xml version="1.0"?> -<!--*- mode: xml -*--> -<interface> - <object class="GtkDialog" id="dialog1"> - <property name="title" translatable="yes">Define Views for "%s"</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkTable" id="table-top"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">1</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="label-views"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Define Views for %s</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="border_width">6</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <object class="GtkTreeView" id="treeview1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="headers_clickable">True</property> - <property name="reorderable">True</property> - <property name="fixed_height_mode">True</property> - </object> - </child> - </object> - </child> - <child> - <object class="GtkVButtonBox" id="vbuttonbox1"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="spacing">6</property> - <property name="layout_style">GTK_BUTTONBOX_START</property> - <child> - <object class="GtkButton" id="button-new"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-new</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-modify"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <child> - <object class="GtkAlignment" id="alignment33"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox224"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image8"> - <property name="visible">True</property> - <property name="stock">gtk-properties</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label557"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Edit</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-delete"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-delete</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - </packing> - </child> - </object> - <packing> - <property name="padding">12</property> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <object class="GtkButton" id="button7"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-5">button7</action-widget> - </action-widgets> - </object> -</interface> diff --git a/widgets/menus/gal-view-collection.c b/widgets/menus/gal-view-collection.c deleted file mode 100644 index 85dcc32f13..0000000000 --- a/widgets/menus/gal-view-collection.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <string.h> -#include <errno.h> - -#include <libxml/parser.h> -#include <libedataserver/libedataserver.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" -#include "e-util/e-unicode.h" - -#include "gal-view-collection.h" - -G_DEFINE_TYPE (GalViewCollection, gal_view_collection, G_TYPE_OBJECT) - -#define d(x) - -enum { - DISPLAY_VIEW, - CHANGED, - LAST_SIGNAL -}; - -static guint gal_view_collection_signals[LAST_SIGNAL] = { 0, }; - -/** - * gal_view_collection_display_view: - * @collection: The GalViewCollection to send the signal on. - * @view: The view to display. - * - */ -void -gal_view_collection_display_view (GalViewCollection *collection, - GalView *view) -{ - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (GAL_IS_VIEW (view)); - - g_signal_emit ( - collection, - gal_view_collection_signals[DISPLAY_VIEW], 0, - view); -} - -static void -gal_view_collection_changed (GalViewCollection *collection) -{ - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - - g_signal_emit ( - collection, - gal_view_collection_signals[CHANGED], 0); -} - -static void -gal_view_collection_item_free (GalViewCollectionItem *item) -{ - g_free (item->id); - if (item->view) { - if (item->view_changed_id) - g_signal_handler_disconnect ( - item->view, - item->view_changed_id); - g_object_unref (item->view); - } - g_free (item); -} - -static gchar * -gal_view_generate_string (GalViewCollection *collection, - GalView *view, - gint which) -{ - gchar *ret_val; - gchar *pointer; - - if (which == 1) - ret_val = g_strdup (gal_view_get_title (view)); - else - ret_val = g_strdup_printf ("%s_%d", gal_view_get_title (view), which); - for (pointer = ret_val; *pointer; pointer = g_utf8_next_char (pointer)) { - if (!g_unichar_isalnum (g_utf8_get_char (pointer))) { - gchar *ptr = pointer; - for (; ptr < g_utf8_next_char (pointer); *ptr = '_', ptr++) - ; - } - } - return ret_val; -} - -static gint -gal_view_check_string (GalViewCollection *collection, - gchar *string) -{ - gint i; - - if (!strcmp (string, "current_view")) - return FALSE; - - for (i = 0; i < collection->view_count; i++) { - if (!strcmp (string, collection->view_data[i]->id)) - return FALSE; - } - for (i = 0; i < collection->removed_view_count; i++) { - if (!strcmp (string, collection->removed_view_data[i]->id)) - return FALSE; - } - return TRUE; -} - -static gchar * -gal_view_generate_id (GalViewCollection *collection, - GalView *view) -{ - gint i; - for (i = 1; TRUE; i++) { - gchar *try; - - try = gal_view_generate_string (collection, view, i); - if (gal_view_check_string (collection, try)) - return try; - g_free (try); - } -} - -static void -gal_view_collection_dispose (GObject *object) -{ - GalViewCollection *collection = GAL_VIEW_COLLECTION (object); - gint i; - - for (i = 0; i < collection->view_count; i++) { - gal_view_collection_item_free (collection->view_data[i]); - } - g_free (collection->view_data); - collection->view_data = NULL; - collection->view_count = 0; - - g_list_foreach ( - collection->factory_list, - (GFunc) g_object_unref, NULL); - g_list_free (collection->factory_list); - collection->factory_list = NULL; - - for (i = 0; i < collection->removed_view_count; i++) { - gal_view_collection_item_free (collection->removed_view_data[i]); - } - g_free (collection->removed_view_data); - collection->removed_view_data = NULL; - collection->removed_view_count = 0; - - g_free (collection->system_dir); - collection->system_dir = NULL; - - g_free (collection->local_dir); - collection->local_dir = NULL; - - g_free (collection->default_view); - collection->default_view = NULL; - - g_free (collection->title); - collection->title = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_collection_parent_class)->dispose (object); -} - -static void -gal_view_collection_class_init (GalViewCollectionClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = gal_view_collection_dispose; - - gal_view_collection_signals[DISPLAY_VIEW] = g_signal_new ( - "display_view", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalViewCollectionClass, display_view), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GAL_TYPE_VIEW); - - gal_view_collection_signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalViewCollectionClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - class->display_view = NULL; - class->changed = NULL; -} - -static void -gal_view_collection_init (GalViewCollection *collection) -{ - collection->view_data = NULL; - collection->view_count = 0; - collection->factory_list = NULL; - - collection->removed_view_data = NULL; - collection->removed_view_count = 0; - - collection->system_dir = NULL; - collection->local_dir = NULL; - - collection->loaded = FALSE; - collection->default_view = NULL; - collection->default_view_built_in = TRUE; - - collection->title = NULL; -} - -/** - * gal_view_collection_new: - * - * A collection of views and view factories. - */ -GalViewCollection * -gal_view_collection_new (void) -{ - return g_object_new (GAL_VIEW_COLLECTION_TYPE, NULL); -} - -void -gal_view_collection_set_title (GalViewCollection *collection, - const gchar *title) -{ - g_free (collection->title); - collection->title = g_strdup (title); -} - -/** - * gal_view_collection_set_storage_directories - * @collection: The view collection to initialize - * @system_dir: The location of the system built in views - * @local_dir: The location to store the users set up views - * - * Sets up the GalViewCollection. - */ -void -gal_view_collection_set_storage_directories (GalViewCollection *collection, - const gchar *system_dir, - const gchar *local_dir) -{ - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (system_dir != NULL); - g_return_if_fail (local_dir != NULL); - - g_free (collection->system_dir); - g_free (collection->local_dir); - - collection->system_dir = g_strdup (system_dir); - collection->local_dir = g_strdup (local_dir); -} - -/** - * gal_view_collection_add_factory - * @collection: The view collection to add a factory to - * @factory: The factory to add. The @collection will add a reference - * to the factory object, so you should unref it after calling this - * function if you no longer need it. - * - * Adds the given factory to this collection. This list is used both - * when loading views from their xml description as well as when the - * user tries to create a new view. - */ -void -gal_view_collection_add_factory (GalViewCollection *collection, - GalViewFactory *factory) -{ - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (GAL_IS_VIEW_FACTORY (factory)); - - g_object_ref (factory); - collection->factory_list = g_list_prepend (collection->factory_list, factory); -} - -static void -view_changed (GalView *view, - GalViewCollectionItem *item) -{ - item->changed = TRUE; - item->ever_changed = TRUE; - - g_signal_handler_block (item->view, item->view_changed_id); - gal_view_collection_changed (item->collection); - g_signal_handler_unblock (item->view, item->view_changed_id); -} - -/* Use factory list to load a GalView file. */ -static GalView * -gal_view_collection_real_load_view_from_file (GalViewCollection *collection, - const gchar *type, - const gchar *title, - const gchar *dir, - const gchar *filename) -{ - GalViewFactory *factory; - GList *factories; - - factory = NULL; - for (factories = collection->factory_list; factories; factories = factories->next) { - if (type && !strcmp (gal_view_factory_get_type_code (factories->data), type)) { - factory = factories->data; - break; - } - } - if (factory) { - GalView *view; - - view = gal_view_factory_new_view (factory, title); - gal_view_set_title (view, title); - gal_view_load (view, filename); - return view; - } - return NULL; -} - -GalView * -gal_view_collection_load_view_from_file (GalViewCollection *collection, - const gchar *type, - const gchar *filename) -{ - return gal_view_collection_real_load_view_from_file (collection, type, "", collection->local_dir, filename); -} - -static GalViewCollectionItem * -load_single_file (GalViewCollection *collection, - gchar *dir, - gboolean local, - xmlNode *node) -{ - GalViewCollectionItem *item; - item = g_new (GalViewCollectionItem, 1); - item->ever_changed = local; - item->changed = FALSE; - item->built_in = !local; - item->id = e_xml_get_string_prop_by_name (node, (const guchar *)"id"); - item->filename = e_xml_get_string_prop_by_name (node, (const guchar *)"filename"); - item->title = e_xml_get_translated_utf8_string_prop_by_name (node, (const guchar *)"title"); - item->type = e_xml_get_string_prop_by_name (node, (const guchar *)"type"); - item->collection = collection; - item->view_changed_id = 0; - - if (item->filename) { - gchar *fullpath; - fullpath = g_build_filename (dir, item->filename, NULL); - item->view = gal_view_collection_real_load_view_from_file (collection, item->type, item->title, dir, fullpath); - g_free (fullpath); - if (item->view) { - item->view_changed_id = g_signal_connect ( - item->view, "changed", - G_CALLBACK (view_changed), item); - } - } - return item; -} - -static void -load_single_dir (GalViewCollection *collection, - gchar *dir, - gboolean local) -{ - xmlDoc *doc = NULL; - xmlNode *root; - xmlNode *child; - gchar *filename = g_build_filename (dir, "galview.xml", NULL); - gchar *default_view; - - if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { -#ifdef G_OS_WIN32 - gchar *locale_filename = g_win32_locale_filename_from_utf8 (filename); - if (locale_filename != NULL) - doc = xmlParseFile (locale_filename); - g_free (locale_filename); -#else - doc = xmlParseFile (filename); -#endif - } - - if (!doc) { - g_free (filename); - return; - } - root = xmlDocGetRootElement (doc); - for (child = root->xmlChildrenNode; child; child = child->next) { - gchar *id; - gboolean found = FALSE; - gint i; - - if (!strcmp ((gchar *) child->name, "text")) - continue; - - id = e_xml_get_string_prop_by_name (child, (const guchar *)"id"); - for (i = 0; i < collection->view_count; i++) { - if (!strcmp (id, collection->view_data[i]->id)) { - if (!local) - collection->view_data[i]->built_in = TRUE; - found = TRUE; - break; - } - } - if (!found) { - for (i = 0; i < collection->removed_view_count; i++) { - if (!strcmp (id, collection->removed_view_data[i]->id)) { - if (!local) - collection->removed_view_data[i]->built_in = TRUE; - found = TRUE; - break; - } - } - } - - if (!found) { - GalViewCollectionItem *item = load_single_file (collection, dir, local, child); - if (item->filename && *item->filename) { - collection->view_data = g_renew (GalViewCollectionItem *, collection->view_data, collection->view_count + 1); - collection->view_data[collection->view_count] = item; - collection->view_count++; - } else { - collection->removed_view_data = g_renew (GalViewCollectionItem *, collection->removed_view_data, collection->removed_view_count + 1); - collection->removed_view_data[collection->removed_view_count] = item; - collection->removed_view_count++; - } - } - g_free (id); - } - - default_view = e_xml_get_string_prop_by_name (root, (const guchar *)"default-view"); - if (default_view) { - if (local) - collection->default_view_built_in = FALSE; - else - collection->default_view_built_in = TRUE; - g_free (collection->default_view); - collection->default_view = default_view; - } - - g_free (filename); - xmlFreeDoc (doc); -} - -/** - * gal_view_collection_load - * @collection: The view collection to load information for - * - * Loads the data from the system and user directories specified in - * set storage directories. This is primarily for internal use by - * other parts of gal_view. - */ -void -gal_view_collection_load (GalViewCollection *collection) -{ - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (collection->local_dir != NULL); - g_return_if_fail (collection->system_dir != NULL); - g_return_if_fail (!collection->loaded); - - if ((g_mkdir_with_parents (collection->local_dir, 0777) == -1) && (errno != EEXIST)) - g_warning ("Unable to create dir %s: %s", collection->local_dir, g_strerror (errno)); - - load_single_dir (collection, collection->local_dir, TRUE); - load_single_dir (collection, collection->system_dir, FALSE); - gal_view_collection_changed (collection); - - collection->loaded = TRUE; -} - -/** - * gal_view_collection_save - * @collection: The view collection to save information for - * - * Saves the data to the user directory specified in set storage - * directories. This is primarily for internal use by other parts of - * gal_view. - */ -void -gal_view_collection_save (GalViewCollection *collection) -{ - gint i; - xmlDoc *doc; - xmlNode *root; - gchar *filename; - - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (collection->local_dir != NULL); - - doc = xmlNewDoc ((const guchar *)"1.0"); - root = xmlNewNode (NULL, (const guchar *)"GalViewCollection"); - xmlDocSetRootElement (doc, root); - - if (collection->default_view && !collection->default_view_built_in) { - e_xml_set_string_prop_by_name (root, (const guchar *)"default-view", collection->default_view); - } - - for (i = 0; i < collection->view_count; i++) { - xmlNode *child; - GalViewCollectionItem *item; - - item = collection->view_data[i]; - if (item->ever_changed) { - child = xmlNewChild (root, NULL, (const guchar *)"GalView", NULL); - e_xml_set_string_prop_by_name (child, (const guchar *)"id", item->id); - e_xml_set_string_prop_by_name (child, (const guchar *)"title", item->title); - e_xml_set_string_prop_by_name (child, (const guchar *)"filename", item->filename); - e_xml_set_string_prop_by_name (child, (const guchar *)"type", item->type); - - if (item->changed) { - filename = g_build_filename (collection->local_dir, item->filename, NULL); - gal_view_save (item->view, filename); - g_free (filename); - } - } - } - for (i = 0; i < collection->removed_view_count; i++) { - xmlNode *child; - GalViewCollectionItem *item; - - item = collection->removed_view_data[i]; - - child = xmlNewChild (root, NULL, (const guchar *)"GalView", NULL); - e_xml_set_string_prop_by_name (child, (const guchar *)"id", item->id); - e_xml_set_string_prop_by_name (child, (const guchar *)"title", item->title); - e_xml_set_string_prop_by_name (child, (const guchar *)"type", item->type); - } - filename = g_build_filename (collection->local_dir, "galview.xml", NULL); - if (e_xml_save_file (filename, doc) == -1) - g_warning ("Unable to save view to %s - %s", filename, g_strerror (errno)); - xmlFreeDoc (doc); - g_free (filename); -} - -/** - * gal_view_collection_get_count - * @collection: The view collection to count - * - * Calculates the number of views in the given collection. - * - * Returns: The number of views in the collection. - */ -gint -gal_view_collection_get_count (GalViewCollection *collection) -{ - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), -1); - - return collection->view_count; -} - -/** - * gal_view_collection_get_view - * @collection: The view collection to query - * @n: The view to get. - * - * Returns: The nth view in the collection - */ -GalView * -gal_view_collection_get_view (GalViewCollection *collection, - gint n) -{ - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); - g_return_val_if_fail (n < collection->view_count, NULL); - g_return_val_if_fail (n >= 0, NULL); - - return collection->view_data[n]->view; -} - -/** - * gal_view_collection_get_view_item - * @collection: The view collection to query - * @n: The view item to get. - * - * Returns: The nth view item in the collection - */ -GalViewCollectionItem * -gal_view_collection_get_view_item (GalViewCollection *collection, - gint n) -{ - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); - g_return_val_if_fail (n < collection->view_count, NULL); - g_return_val_if_fail (n >= 0, NULL); - - return collection->view_data[n]; -} - -gint -gal_view_collection_get_view_index_by_id (GalViewCollection *collection, - const gchar *view_id) -{ - gint i; - for (i = 0; i < collection->view_count; i++) { - if (!strcmp (collection->view_data[i]->id, view_id)) - return i; - } - return -1; -} - -gchar * -gal_view_collection_get_view_id_by_index (GalViewCollection *collection, - gint n) -{ - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); - g_return_val_if_fail (n < collection->view_count, NULL); - g_return_val_if_fail (n >= 0, NULL); - - return g_strdup (collection->view_data[n]->id); -} - -void -gal_view_collection_append (GalViewCollection *collection, - GalView *view) -{ - GalViewCollectionItem *item; - - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (GAL_IS_VIEW (view)); - - item = g_new (GalViewCollectionItem, 1); - item->ever_changed = TRUE; - item->changed = TRUE; - item->built_in = FALSE; - item->title = g_strdup (gal_view_get_title (view)); - item->type = g_strdup (gal_view_get_type_code (view)); - item->id = gal_view_generate_id (collection, view); - item->filename = g_strdup_printf ("%s.galview", item->id); - item->view = view; - item->collection = collection; - g_object_ref (view); - - item->view_changed_id = g_signal_connect ( - item->view, "changed", - G_CALLBACK (view_changed), item); - - collection->view_data = g_renew (GalViewCollectionItem *, collection->view_data, collection->view_count + 1); - collection->view_data[collection->view_count] = item; - collection->view_count++; - - gal_view_collection_changed (collection); -} - -void -gal_view_collection_delete_view (GalViewCollection *collection, - gint i) -{ - GalViewCollectionItem *item; - - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (i >= 0 && i < collection->view_count); - - item = collection->view_data[i]; - memmove (collection->view_data + i, collection->view_data + i + 1, (collection->view_count - i - 1) * sizeof (GalViewCollectionItem *)); - collection->view_count--; - if (item->built_in) { - g_free (item->filename); - item->filename = NULL; - - collection->removed_view_data = g_renew (GalViewCollectionItem *, collection->removed_view_data, collection->removed_view_count + 1); - collection->removed_view_data[collection->removed_view_count] = item; - collection->removed_view_count++; - } else { - gal_view_collection_item_free (item); - } - - gal_view_collection_changed (collection); -} - -void -gal_view_collection_copy_view (GalViewCollection *collection, - gint i) -{ - GalViewCollectionItem *item; - GalView *view; - - g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); - g_return_if_fail (i >= 0 && i < collection->view_count); - - view = collection->view_data[i]->view; - - item = g_new (GalViewCollectionItem, 1); - item->ever_changed = TRUE; - item->changed = FALSE; - item->built_in = FALSE; - item->title = g_strdup (gal_view_get_title (view)); - item->type = g_strdup (gal_view_get_type_code (view)); - item->id = gal_view_generate_id (collection, view); - item->filename = g_strdup_printf ("%s.galview", item->id); - item->view = gal_view_clone (view); - item->collection = collection; - - item->view_changed_id = g_signal_connect ( - item->view, "changed", - G_CALLBACK (view_changed), item); - - collection->view_data = g_renew (GalViewCollectionItem *, collection->view_data, collection->view_count + 1); - collection->view_data[collection->view_count] = item; - collection->view_count++; - - gal_view_collection_changed (collection); -} - -gboolean -gal_view_collection_loaded (GalViewCollection *collection) -{ - return collection->loaded; -} - -const gchar * -gal_view_collection_append_with_title (GalViewCollection *collection, - const gchar *title, - GalView *view) -{ - GalViewCollectionItem *item; - - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); - g_return_val_if_fail (GAL_IS_VIEW (view), NULL); - - gal_view_set_title (view, title); - - d (g_print ("%s: %p\n", G_STRFUNC, view)); - - item = g_new (GalViewCollectionItem, 1); - item->ever_changed = TRUE; - item->changed = TRUE; - item->built_in = FALSE; - item->title = g_strdup (gal_view_get_title (view)); - item->type = g_strdup (gal_view_get_type_code (view)); - item->id = gal_view_generate_id (collection, view); - item->filename = g_strdup_printf ("%s.galview", item->id); - item->view = view; - item->collection = collection; - g_object_ref (view); - - item->view_changed_id = g_signal_connect ( - item->view, "changed", - G_CALLBACK (view_changed), item); - - collection->view_data = g_renew (GalViewCollectionItem *, collection->view_data, collection->view_count + 1); - collection->view_data[collection->view_count] = item; - collection->view_count++; - - gal_view_collection_changed (collection); - return item->id; -} - -const gchar * -gal_view_collection_set_nth_view (GalViewCollection *collection, - gint i, - GalView *view) -{ - GalViewCollectionItem *item; - - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); - g_return_val_if_fail (GAL_IS_VIEW (view), NULL); - g_return_val_if_fail (i >= 0, NULL); - g_return_val_if_fail (i < collection->view_count, NULL); - - d (g_print ("%s: %p\n", G_STRFUNC, view)); - - item = collection->view_data[i]; - - gal_view_set_title (view, item->title); - g_object_ref (view); - if (item->view) { - g_signal_handler_disconnect ( - item->view, - item->view_changed_id); - g_object_unref (item->view); - } - item->view = view; - - item->ever_changed = TRUE; - item->changed = TRUE; - item->type = g_strdup (gal_view_get_type_code (view)); - - item->view_changed_id = g_signal_connect ( - item->view, "changed", - G_CALLBACK (view_changed), item); - - gal_view_collection_changed (collection); - return item->id; -} - -const gchar * -gal_view_collection_get_default_view (GalViewCollection *collection) -{ - return collection->default_view; -} - -void -gal_view_collection_set_default_view (GalViewCollection *collection, - const gchar *id) -{ - g_free (collection->default_view); - collection->default_view = g_strdup (id); - gal_view_collection_changed (collection); - collection->default_view_built_in = FALSE; -} - diff --git a/widgets/menus/gal-view-collection.h b/widgets/menus/gal-view-collection.h deleted file mode 100644 index 143bee53d1..0000000000 --- a/widgets/menus/gal-view-collection.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _GAL_VIEW_SET_H_ -#define _GAL_VIEW_SET_H_ - -#include <menus/gal-view-factory.h> - -G_BEGIN_DECLS - -#define GAL_VIEW_COLLECTION_TYPE (gal_view_collection_get_type ()) -#define GAL_VIEW_COLLECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_VIEW_COLLECTION_TYPE, GalViewCollection)) -#define GAL_VIEW_COLLECTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_VIEW_COLLECTION_TYPE, GalViewCollectionClass)) -#define GAL_IS_VIEW_COLLECTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_VIEW_COLLECTION_TYPE)) -#define GAL_IS_VIEW_COLLECTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_VIEW_COLLECTION_TYPE)) -#define GAL_VIEW_COLLECTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GAL_VIEW_COLLECTION_TYPE, GalViewCollectionClass)) - -typedef struct GalViewCollectionItem GalViewCollectionItem; - -typedef struct { - GObject base; - - GalViewCollectionItem **view_data; - gint view_count; - - GList *factory_list; - - GalViewCollectionItem **removed_view_data; - gint removed_view_count; - - guint loaded : 1; - guint default_view_built_in : 1; - - gchar *system_dir; - gchar *local_dir; - - gchar *default_view; - - gchar *title; -} GalViewCollection; - -typedef struct { - GObjectClass parent_class; - - /* - * Signals - */ - void (*display_view) (GalViewCollection *collection, - GalView *view); - void (*changed) (GalViewCollection *collection); -} GalViewCollectionClass; - -struct GalViewCollectionItem { - GalView *view; - gchar *id; - guint changed : 1; - guint ever_changed : 1; - guint built_in : 1; - gchar *filename; - gchar *title; - gchar *type; - GalViewCollection *collection; - guint view_changed_id; -}; - -/* Standard functions */ -GType gal_view_collection_get_type (void); -GalViewCollection *gal_view_collection_new (void); - -void gal_view_collection_set_title (GalViewCollection *collection, - const gchar *title); -/* Set up the view collection. Call these two functions before ever doing load or save and never call them again. */ -void gal_view_collection_set_storage_directories (GalViewCollection *collection, - const gchar *system_dir, - const gchar *local_dir); -void gal_view_collection_add_factory (GalViewCollection *collection, - GalViewFactory *factory); - -/* Send the display view signal. This function is deprecated. */ -void gal_view_collection_display_view (GalViewCollection *collection, - GalView *view); - -/* Query the view collection. */ -gint gal_view_collection_get_count (GalViewCollection *collection); -GalView *gal_view_collection_get_view (GalViewCollection *collection, - gint n); -GalViewCollectionItem *gal_view_collection_get_view_item (GalViewCollection *collection, - gint n); -gint gal_view_collection_get_view_index_by_id (GalViewCollection *collection, - const gchar *view_id); -gchar *gal_view_collection_get_view_id_by_index (GalViewCollection *collection, - gint n); - -/* Manipulate the view collection */ -void gal_view_collection_append (GalViewCollection *collection, - GalView *view); -void gal_view_collection_delete_view (GalViewCollection *collection, - gint i); -void gal_view_collection_copy_view (GalViewCollection *collection, - gint i); -/* Call set_storage_directories and add factories for anything that - * might be found there before doing either of these. */ -void gal_view_collection_load (GalViewCollection *collection); -void gal_view_collection_save (GalViewCollection *collection); -gboolean gal_view_collection_loaded (GalViewCollection *collection); - -/* Use factory list to load a GalView file. */ -GalView *gal_view_collection_load_view_from_file (GalViewCollection *collection, - const gchar *type, - const gchar *filename); - -/* Returns id of the new view. These functions are used for - * GalViewInstanceSaveAsDialog. */ -const gchar *gal_view_collection_append_with_title (GalViewCollection *collection, - const gchar *title, - GalView *view); -const gchar *gal_view_collection_set_nth_view (GalViewCollection *collection, - gint i, - GalView *view); - -const gchar *gal_view_collection_get_default_view (GalViewCollection *collection); -void gal_view_collection_set_default_view (GalViewCollection *collection, - const gchar *id); - -G_END_DECLS - -#endif /* _GAL_VIEW_COLLECTION_H_ */ diff --git a/widgets/menus/gal-view-etable.c b/widgets/menus/gal-view-etable.c deleted file mode 100644 index c259cc9004..0000000000 --- a/widgets/menus/gal-view-etable.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "table/e-table-config.h" - -#include "gal-view-etable.h" - -G_DEFINE_TYPE (GalViewEtable, gal_view_etable, GAL_TYPE_VIEW) - -static void -detach_table (GalViewEtable *view) -{ - if (view->table == NULL) - return; - if (view->table_state_changed_id) { - g_signal_handler_disconnect ( - view->table, - view->table_state_changed_id); - view->table_state_changed_id = 0; - } - g_object_unref (view->table); - view->table = NULL; -} - -static void -detach_tree (GalViewEtable *view) -{ - if (view->tree == NULL) - return; - if (view->tree_state_changed_id) { - g_signal_handler_disconnect ( - view->tree, - view->tree_state_changed_id); - view->tree_state_changed_id = 0; - } - g_object_unref (view->tree); - view->tree = NULL; -} - -static void -config_changed (ETableConfig *config, - GalViewEtable *view) -{ - ETableState *state; - if (view->state) - g_object_unref (view->state); - g_object_get ( - config, - "state", &state, - NULL); - view->state = e_table_state_duplicate (state); - g_object_unref (state); - - gal_view_changed (GAL_VIEW (view)); -} - -static void -gal_view_etable_edit (GalView *view, - GtkWindow *parent) -{ - GalViewEtable *etable_view = GAL_VIEW_ETABLE (view); - ETableConfig *config; - - config = e_table_config_new ( - etable_view->title, - etable_view->spec, - etable_view->state, - parent); - - g_signal_connect ( - config, "changed", - G_CALLBACK (config_changed), view); -} - -static void -gal_view_etable_load (GalView *view, - const gchar *filename) -{ - e_table_state_load_from_file (GAL_VIEW_ETABLE (view)->state, filename); -} - -static void -gal_view_etable_save (GalView *view, - const gchar *filename) -{ - e_table_state_save_to_file (GAL_VIEW_ETABLE (view)->state, filename); -} - -static const gchar * -gal_view_etable_get_title (GalView *view) -{ - return GAL_VIEW_ETABLE (view)->title; -} - -static void -gal_view_etable_set_title (GalView *view, - const gchar *title) -{ - g_free (GAL_VIEW_ETABLE (view)->title); - GAL_VIEW_ETABLE (view)->title = g_strdup (title); -} - -static const gchar * -gal_view_etable_get_type_code (GalView *view) -{ - return "etable"; -} - -static GalView * -gal_view_etable_clone (GalView *view) -{ - GalViewEtable *gve, *new; - - gve = GAL_VIEW_ETABLE (view); - - new = g_object_new (GAL_TYPE_VIEW_ETABLE, NULL); - new->spec = gve->spec; - new->title = g_strdup (gve->title); - g_object_unref (new->state); - new->state = e_table_state_duplicate (gve->state); - - g_object_ref (new->spec); - - return GAL_VIEW (new); -} - -static void -gal_view_etable_dispose (GObject *object) -{ - GalViewEtable *view = GAL_VIEW_ETABLE (object); - - gal_view_etable_detach (view); - - g_free (view->title); - view->title = NULL; - - if (view->spec) - g_object_unref (view->spec); - view->spec = NULL; - - if (view->state) - g_object_unref (view->state); - view->state = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_etable_parent_class)->dispose (object); -} - -static void -gal_view_etable_class_init (GalViewEtableClass *class) -{ - GalViewClass *gal_view_class = GAL_VIEW_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - gal_view_class->edit = gal_view_etable_edit; - gal_view_class->load = gal_view_etable_load; - gal_view_class->save = gal_view_etable_save; - gal_view_class->get_title = gal_view_etable_get_title; - gal_view_class->set_title = gal_view_etable_set_title; - gal_view_class->get_type_code = gal_view_etable_get_type_code; - gal_view_class->clone = gal_view_etable_clone; - - object_class->dispose = gal_view_etable_dispose; -} - -static void -gal_view_etable_init (GalViewEtable *gve) -{ - gve->spec = NULL; - gve->state = e_table_state_new (); - gve->title = NULL; -} - -/** - * gal_view_etable_new - * @spec: The ETableSpecification that this view will be based upon. - * @title: The name of the new view. - * - * Returns a new GalViewEtable. This is primarily for use by - * GalViewFactoryEtable. - * - * Returns: The new GalViewEtable. - */ -GalView * -gal_view_etable_new (ETableSpecification *spec, - const gchar *title) -{ - GalViewEtable *view; - - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (spec), NULL); - - view = g_object_new (GAL_TYPE_VIEW_ETABLE, NULL); - - return gal_view_etable_construct (view, spec, title); -} - -/** - * gal_view_etable_construct - * @view: The view to construct. - * @spec: The ETableSpecification that this view will be based upon. - * @title: The name of the new view. - * - * constructs the GalViewEtable. To be used by subclasses and - * language bindings. - * - * Returns: The GalViewEtable. - */ -GalView * -gal_view_etable_construct (GalViewEtable *view, - ETableSpecification *spec, - const gchar *title) -{ - g_return_val_if_fail (GAL_IS_VIEW_ETABLE (view), NULL); - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (spec), NULL); - - view->spec = g_object_ref (spec); - - if (view->state) - g_object_unref (view->state); - view->state = e_table_state_duplicate (spec->state); - - view->title = g_strdup (title); - - return GAL_VIEW (view); -} - -void -gal_view_etable_set_state (GalViewEtable *view, - ETableState *state) -{ - g_return_if_fail (GAL_IS_VIEW_ETABLE (view)); - g_return_if_fail (E_IS_TABLE_STATE (state)); - - if (view->state) - g_object_unref (view->state); - view->state = e_table_state_duplicate (state); - - gal_view_changed (GAL_VIEW (view)); -} - -static void -table_state_changed (ETable *table, - GalViewEtable *view) -{ - ETableState *state; - - state = e_table_get_state_object (table); - g_object_unref (view->state); - view->state = state; - - gal_view_changed (GAL_VIEW (view)); -} - -static void -tree_state_changed (ETree *tree, - GalViewEtable *view) -{ - ETableState *state; - - state = e_tree_get_state_object (tree); - g_object_unref (view->state); - view->state = state; - - gal_view_changed (GAL_VIEW (view)); -} - -void -gal_view_etable_attach_table (GalViewEtable *view, - ETable *table) -{ - g_return_if_fail (GAL_IS_VIEW_ETABLE (view)); - g_return_if_fail (E_IS_TABLE (table)); - - gal_view_etable_detach (view); - - view->table = table; - - e_table_set_state_object (view->table, view->state); - g_object_ref (view->table); - view->table_state_changed_id = g_signal_connect ( - view->table, "state_change", - G_CALLBACK (table_state_changed), view); -} - -void -gal_view_etable_attach_tree (GalViewEtable *view, - ETree *tree) -{ - g_return_if_fail (GAL_IS_VIEW_ETABLE (view)); - g_return_if_fail (E_IS_TREE (tree)); - - gal_view_etable_detach (view); - - view->tree = tree; - - e_tree_set_state_object (view->tree, view->state); - g_object_ref (view->tree); - view->tree_state_changed_id = g_signal_connect ( - view->tree, "state_change", - G_CALLBACK (tree_state_changed), view); -} - -void -gal_view_etable_detach (GalViewEtable *view) -{ - g_return_if_fail (GAL_IS_VIEW_ETABLE (view)); - - if (view->table != NULL) - detach_table (view); - if (view->tree != NULL) - detach_tree (view); -} diff --git a/widgets/menus/gal-view-etable.h b/widgets/menus/gal-view-etable.h deleted file mode 100644 index cfccf1e15b..0000000000 --- a/widgets/menus/gal-view-etable.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_VIEW_ETABLE_H -#define GAL_VIEW_ETABLE_H - -#include <gtk/gtk.h> -#include <menus/gal-view.h> -#include <table/e-table-state.h> -#include <table/e-table-specification.h> -#include <table/e-table.h> -#include <table/e-tree.h> - -/* Standard GObject macros */ -#define GAL_TYPE_VIEW_ETABLE \ - (gal_view_etable_get_type ()) -#define GAL_VIEW_ETABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_VIEW_ETABLE, GalViewEtable)) -#define GAL_VIEW_ETABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_VIEW_ETABLE, GalViewEtableClass)) -#define GAL_IS_VIEW_ETABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_VIEW_ETABLE)) -#define GAL_IS_VIEW_ETABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_VIEW_ETABLE)) -#define GAL_VIEW_ETABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_VIEW_ETABLE, GalViewEtableClass)) - -G_BEGIN_DECLS - -typedef struct _GalViewEtable GalViewEtable; -typedef struct _GalViewEtableClass GalViewEtableClass; - -struct _GalViewEtable { - GalView parent; - - ETableSpecification *spec; - ETableState *state; - gchar *title; - - ETable *table; - guint table_state_changed_id; - - ETree *tree; - guint tree_state_changed_id; -}; - -struct _GalViewEtableClass { - GalViewClass parent_class; -}; - -GType gal_view_etable_get_type (void); -GalView * gal_view_etable_new (ETableSpecification *spec, - const gchar *title); -GalView * gal_view_etable_construct (GalViewEtable *view, - ETableSpecification *spec, - const gchar *title); -void gal_view_etable_set_state (GalViewEtable *view, - ETableState *state); -void gal_view_etable_attach_table (GalViewEtable *view, - ETable *table); -void gal_view_etable_attach_tree (GalViewEtable *view, - ETree *tree); -void gal_view_etable_detach (GalViewEtable *view); - -G_END_DECLS - -#endif /* GAL_VIEW_ETABLE_H */ diff --git a/widgets/menus/gal-view-factory-etable.c b/widgets/menus/gal-view-factory-etable.c deleted file mode 100644 index 8570d3c98c..0000000000 --- a/widgets/menus/gal-view-factory-etable.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "gal-view-etable.h" -#include "gal-view-factory-etable.h" - -#define GAL_VIEW_FACTORY_ETABLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), GAL_TYPE_VIEW_FACTORY_ETABLE, GalViewFactoryEtablePrivate)) - -struct _GalViewFactoryEtablePrivate { - ETableSpecification *specification; -}; - -enum { - PROP_0, - PROP_SPECIFICATION -}; - -G_DEFINE_TYPE ( - GalViewFactoryEtable, - gal_view_factory_etable, GAL_TYPE_VIEW_FACTORY) - -static void -view_factory_etable_set_specification (GalViewFactoryEtable *factory, - ETableSpecification *specification) -{ - g_return_if_fail (factory->priv->specification == NULL); - g_return_if_fail (E_IS_TABLE_SPECIFICATION (specification)); - - factory->priv->specification = g_object_ref (specification); -} - -static void -view_factory_etable_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SPECIFICATION: - view_factory_etable_set_specification ( - GAL_VIEW_FACTORY_ETABLE (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -view_factory_etable_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SPECIFICATION: - g_value_set_object ( - value, - gal_view_factory_etable_get_specification ( - GAL_VIEW_FACTORY_ETABLE (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -view_factory_etable_dispose (GObject *object) -{ - GalViewFactoryEtablePrivate *priv; - - priv = GAL_VIEW_FACTORY_ETABLE_GET_PRIVATE (object); - - if (priv->specification != NULL) { - g_object_unref (priv->specification); - priv->specification = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_factory_etable_parent_class)->dispose (object); -} - -static const gchar * -view_factory_etable_get_title (GalViewFactory *factory) -{ - return _("Table"); -} - -static const gchar * -view_factory_etable_get_type_code (GalViewFactory *factory) -{ - return "etable"; -} - -static GalView * -view_factory_etable_new_view (GalViewFactory *factory, - const gchar *name) -{ - GalViewFactoryEtablePrivate *priv; - - priv = GAL_VIEW_FACTORY_ETABLE_GET_PRIVATE (factory); - - return gal_view_etable_new (priv->specification, name); -} - -static void -gal_view_factory_etable_class_init (GalViewFactoryEtableClass *class) -{ - GObjectClass *object_class; - GalViewFactoryClass *view_factory_class; - - g_type_class_add_private (class, sizeof (GalViewFactoryEtablePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = view_factory_etable_set_property; - object_class->get_property = view_factory_etable_get_property; - object_class->dispose = view_factory_etable_dispose; - - view_factory_class = GAL_VIEW_FACTORY_CLASS (class); - view_factory_class->get_title = view_factory_etable_get_title; - view_factory_class->get_type_code = view_factory_etable_get_type_code; - view_factory_class->new_view = view_factory_etable_new_view; - - g_object_class_install_property ( - object_class, - PROP_SPECIFICATION, - g_param_spec_object ( - "specification", - NULL, - NULL, - E_TYPE_TABLE_SPECIFICATION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -gal_view_factory_etable_init (GalViewFactoryEtable *factory) -{ - factory->priv = GAL_VIEW_FACTORY_ETABLE_GET_PRIVATE (factory); -} - -/** - * gal_view_etable_new: - * @specification: The spec to create GalViewEtables based upon. - * - * A new GalViewFactory for creating ETable views. Create one of - * these and pass it to GalViewCollection for use. - * - * Returns: The new GalViewFactoryEtable. - */ -GalViewFactory * -gal_view_factory_etable_new (ETableSpecification *specification) -{ - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), NULL); - - return g_object_new ( - GAL_TYPE_VIEW_FACTORY_ETABLE, - "specification", specification, NULL); -} - -ETableSpecification * -gal_view_factory_etable_get_specification (GalViewFactoryEtable *factory) -{ - g_return_val_if_fail (GAL_IS_VIEW_FACTORY_ETABLE (factory), NULL); - - return factory->priv->specification; -} diff --git a/widgets/menus/gal-view-factory-etable.h b/widgets/menus/gal-view-factory-etable.h deleted file mode 100644 index a107b87083..0000000000 --- a/widgets/menus/gal-view-factory-etable.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_VIEW_FACTORY_ETABLE_H -#define GAL_VIEW_FACTORY_ETABLE_H - -#include <gtk/gtk.h> -#include <menus/gal-view-factory.h> -#include <table/e-table-specification.h> - -/* Standard GObject macros */ -#define GAL_TYPE_VIEW_FACTORY_ETABLE \ - (gal_view_factory_etable_get_type ()) -#define GAL_VIEW_FACTORY_ETABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_VIEW_FACTORY_ETABLE, GalViewFactoryEtable)) -#define GAL_VIEW_FACTORY_ETABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_VIEW_FACTORY_ETABLE, GalViewFactoryEtableClass)) -#define GAL_IS_VIEW_FACTORY_ETABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_VIEW_FACTORY_ETABLE)) -#define GAL_IS_VIEW_FACTORY_ETABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_VIEW_FACTORY_ETABLE)) -#define GAL_VIEW_FACTORY_ETABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_VIEW_FACTORY_ETABLE, GalViewFactoryEtableClass)) - -G_BEGIN_DECLS - -typedef struct _GalViewFactoryEtable GalViewFactoryEtable; -typedef struct _GalViewFactoryEtableClass GalViewFactoryEtableClass; -typedef struct _GalViewFactoryEtablePrivate GalViewFactoryEtablePrivate; - -struct _GalViewFactoryEtable { - GalViewFactory parent; - GalViewFactoryEtablePrivate *priv; -}; - -struct _GalViewFactoryEtableClass { - GalViewFactoryClass parent_class; -}; - -GType gal_view_factory_etable_get_type (void); -ETableSpecification * - gal_view_factory_etable_get_specification - (GalViewFactoryEtable *factory); -GalViewFactory *gal_view_factory_etable_new (ETableSpecification *specification); - -G_END_DECLS - -#endif /* GAL_VIEW_FACTORY_ETABLE_H */ diff --git a/widgets/menus/gal-view-factory.c b/widgets/menus/gal-view-factory.c deleted file mode 100644 index 0f311cf976..0000000000 --- a/widgets/menus/gal-view-factory.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gal-view-factory.h" - -#include <e-util/e-util.h> - -G_DEFINE_TYPE (GalViewFactory, gal_view_factory, G_TYPE_OBJECT) - -/* XXX Should GalViewFactory be a GInterface? */ - -static void -gal_view_factory_class_init (GalViewFactoryClass *class) -{ -} - -static void -gal_view_factory_init (GalViewFactory *factory) -{ -} - -/** - * gal_view_factory_get_title: - * @factory: a #GalViewFactory - * - * Returns: The title of the factory. - */ -const gchar * -gal_view_factory_get_title (GalViewFactory *factory) -{ - GalViewFactoryClass *class; - - g_return_val_if_fail (GAL_IS_VIEW_FACTORY (factory), NULL); - - class = GAL_VIEW_FACTORY_GET_CLASS (factory); - g_return_val_if_fail (class->get_title != NULL, NULL); - - return class->get_title (factory); -} - -/** - * gal_view_factory_get_type_code: - * @factory: a #GalViewFactory - * - * Returns: The type code - */ -const gchar * -gal_view_factory_get_type_code (GalViewFactory *factory) -{ - GalViewFactoryClass *class; - - g_return_val_if_fail (GAL_IS_VIEW_FACTORY (factory), NULL); - - class = GAL_VIEW_FACTORY_GET_CLASS (factory); - g_return_val_if_fail (class->get_type_code != NULL, NULL); - - return class->get_type_code (factory); -} - -/** - * gal_view_factory_new_view: - * @factory: a #GalViewFactory - * @name: the name for the view - * - * Returns: The new view - */ -GalView * -gal_view_factory_new_view (GalViewFactory *factory, - const gchar *name) -{ - GalViewFactoryClass *class; - - g_return_val_if_fail (GAL_IS_VIEW_FACTORY (factory), NULL); - - class = GAL_VIEW_FACTORY_GET_CLASS (factory); - g_return_val_if_fail (class->new_view != NULL, NULL); - - return class->new_view (factory, name); -} - diff --git a/widgets/menus/gal-view-factory.h b/widgets/menus/gal-view-factory.h deleted file mode 100644 index 92c3df45ac..0000000000 --- a/widgets/menus/gal-view-factory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_VIEW_FACTORY_H -#define GAL_VIEW_FACTORY_H - -#include <menus/gal-view.h> - -/* Standard GObject macros */ -#define GAL_TYPE_VIEW_FACTORY \ - (gal_view_factory_get_type ()) -#define GAL_VIEW_FACTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_VIEW_FACTORY, GalViewFactory)) -#define GAL_VIEW_FACTORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_VIEW_FACTORY, GalViewFactoryClass)) -#define GAL_IS_VIEW_FACTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_VIEW_FACTORY)) -#define GAL_IS_VIEW_FACTORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_VIEW_FACTORY)) -#define GAL_VIEW_FACTORY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_VIEW_FACTORY, GalViewFactoryClass)) - -G_BEGIN_DECLS - -typedef struct _GalViewFactory GalViewFactory; -typedef struct _GalViewFactoryClass GalViewFactoryClass; - -struct _GalViewFactory { - GObject parent; -}; - -struct _GalViewFactoryClass { - GObjectClass parent_class; - - /* Methods */ - const gchar * (*get_title) (GalViewFactory *factory); - const gchar * (*get_type_code) (GalViewFactory *factory); - GalView * (*new_view) (GalViewFactory *factory, - const gchar *name); -}; - -GType gal_view_factory_get_type (void); -const gchar * gal_view_factory_get_title (GalViewFactory *factory); - -/* Returns the code for use in identifying this type of object in the - * view list. This identifier should identify this as being the - * unique factory for xml files which were written out with this - * identifier. Thus each factory should have a unique type code. */ -const gchar * gal_view_factory_get_type_code (GalViewFactory *factory); - -GalView * gal_view_factory_new_view (GalViewFactory *factory, - const gchar *name); - -G_END_DECLS - -#endif /* GAL_VIEW_FACTORY_H */ diff --git a/widgets/menus/gal-view-instance-save-as-dialog.c b/widgets/menus/gal-view-instance-save-as-dialog.c deleted file mode 100644 index df1d1ca743..0000000000 --- a/widgets/menus/gal-view-instance-save-as-dialog.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" - -#include "gal-define-views-model.h" -#include "gal-view-instance-save-as-dialog.h" -#include "gal-view-new-dialog.h" - -G_DEFINE_TYPE (GalViewInstanceSaveAsDialog, gal_view_instance_save_as_dialog, GTK_TYPE_DIALOG) - -enum { - PROP_0, - PROP_INSTANCE -}; - -enum { - COL_GALVIEW_NAME, - COL_GALVIEW_DATA -}; - -/* Static functions */ -static void -gal_view_instance_save_as_dialog_set_instance (GalViewInstanceSaveAsDialog *dialog, - GalViewInstance *instance) -{ - gint i; - GtkListStore *store; - GtkCellRenderer *renderer; - dialog->instance = instance; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); - - for (i = 0; i < instance->collection->view_count; i++) { - GalViewCollectionItem *item = instance->collection->view_data[i]; - GtkTreeIter iter; - gchar *title = NULL; - - /* hide built in views */ - /*if (item->built_in == 1) - continue;*/ - - title = e_str_without_underscores (item->title); - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - COL_GALVIEW_NAME, title, - COL_GALVIEW_DATA, item, - -1); - - g_free (title); - } - - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (store), - COL_GALVIEW_NAME, GTK_SORT_ASCENDING); - - /* attaching treeview to model */ - gtk_tree_view_set_model (dialog->treeview, GTK_TREE_MODEL (store)); - gtk_tree_view_set_search_column (dialog->treeview, COL_GALVIEW_NAME); - - dialog->model = GTK_TREE_MODEL (store); - - renderer = gtk_cell_renderer_text_new (); - - gtk_tree_view_insert_column_with_attributes ( - dialog->treeview, - COL_GALVIEW_NAME, _("Name"), - renderer, "text", COL_GALVIEW_NAME, - NULL); - - /* set sort column */ - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (dialog->model), - COL_GALVIEW_NAME, GTK_SORT_ASCENDING); -} - -static void -gvisad_setup_validate_button (GalViewInstanceSaveAsDialog *dialog) -{ - if ((dialog->toggle == GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE - && g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (dialog->entry_create)), -1) > 0) - || dialog->toggle == GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE) { - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE); - } else { - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE); - } -} - -static void -gvisad_setup_radio_buttons (GalViewInstanceSaveAsDialog *dialog) -{ - GtkWidget *widget; - - widget = dialog->scrolledwindow; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->radiobutton_replace))) { - GtkTreeIter iter; - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection (dialog->treeview); - if (!gtk_tree_selection_get_selected (selection, &dialog->model, &iter)) { - if (gtk_tree_model_get_iter_first (dialog->model, &iter)) { - gtk_tree_selection_select_iter (selection, &iter); - } - } - - gtk_widget_set_sensitive (widget, TRUE); - dialog->toggle = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE; - } else { - gtk_widget_set_sensitive (widget, FALSE); - } - - widget = dialog->entry_create; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->radiobutton_create))) { - gtk_widget_set_sensitive (widget, TRUE); - dialog->toggle = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE; - } else { - gtk_widget_set_sensitive (widget, FALSE); - } - - gvisad_setup_validate_button (dialog); -} - -static void -gvisad_radio_toggled (GtkWidget *widget, - GalViewInstanceSaveAsDialog *dialog) -{ - gvisad_setup_radio_buttons (dialog); -} - -static void -gvisad_entry_changed (GtkWidget *widget, - GalViewInstanceSaveAsDialog *dialog) -{ - gvisad_setup_validate_button (dialog); -} - -/* Method override implementations */ -static void -gal_view_instance_save_as_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GalViewInstanceSaveAsDialog *dialog; - - dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (object); - - switch (property_id) { - case PROP_INSTANCE: - if (g_value_get_object (value)) - gal_view_instance_save_as_dialog_set_instance (dialog, GAL_VIEW_INSTANCE (g_value_get_object (value))); - else - gal_view_instance_save_as_dialog_set_instance (dialog, NULL); - break; - - default: - return; - } -} - -static void -gal_view_instance_save_as_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GalViewInstanceSaveAsDialog *dialog; - - dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (object); - - switch (property_id) { - case PROP_INSTANCE: - g_value_set_object (value, dialog->instance); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gal_view_instance_save_as_dialog_dispose (GObject *object) -{ - GalViewInstanceSaveAsDialog *gal_view_instance_save_as_dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (object); - - if (gal_view_instance_save_as_dialog->builder) - g_object_unref (gal_view_instance_save_as_dialog->builder); - gal_view_instance_save_as_dialog->builder = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_instance_save_as_dialog_parent_class)->dispose (object); -} - -/* Init functions */ -static void -gal_view_instance_save_as_dialog_class_init (GalViewInstanceSaveAsDialogClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - object_class->set_property = gal_view_instance_save_as_dialog_set_property; - object_class->get_property = gal_view_instance_save_as_dialog_get_property; - object_class->dispose = gal_view_instance_save_as_dialog_dispose; - - g_object_class_install_property ( - object_class, - PROP_INSTANCE, - g_param_spec_object ( - "instance", - "Instance", - NULL, - GAL_VIEW_INSTANCE_TYPE, - G_PARAM_READWRITE)); -} - -static void -gal_view_instance_save_as_dialog_init (GalViewInstanceSaveAsDialog *dialog) -{ - GtkWidget *content_area; - GtkWidget *widget; - - dialog->instance = NULL; - dialog->model = NULL; - dialog->collection = NULL; - - dialog->builder = gtk_builder_new (); - e_load_ui_builder_definition ( - dialog->builder, "gal-view-instance-save-as-dialog.ui"); - - widget = e_builder_get_widget (dialog->builder, "vbox-top"); - content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - /* TODO: add position/size saving/restoring */ - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 360); - - gtk_dialog_add_buttons ( - GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_OK, - NULL); - - dialog->scrolledwindow = e_builder_get_widget (dialog->builder, "scrolledwindow2"); - dialog->treeview = GTK_TREE_VIEW (e_builder_get_widget (dialog->builder, "custom-replace")); - dialog->entry_create = e_builder_get_widget (dialog->builder, "entry-create"); - dialog->radiobutton_replace = e_builder_get_widget (dialog->builder, "radiobutton-replace"); - dialog->radiobutton_create = e_builder_get_widget (dialog->builder, "radiobutton-create"); - - gtk_tree_view_set_reorderable (GTK_TREE_VIEW (dialog->treeview), FALSE); - gtk_tree_view_set_headers_visible (dialog->treeview, FALSE); - - g_signal_connect ( - dialog->radiobutton_replace, "toggled", - G_CALLBACK (gvisad_radio_toggled), dialog); - g_signal_connect ( - dialog->radiobutton_create, "toggled", - G_CALLBACK (gvisad_radio_toggled), dialog); - g_signal_connect ( - dialog->entry_create, "changed", - G_CALLBACK (gvisad_entry_changed), dialog); - - gvisad_setup_radio_buttons (dialog); - gvisad_setup_validate_button (dialog); - - gtk_window_set_title (GTK_WINDOW (dialog), _("Save Current View")); - gtk_widget_show (GTK_WIDGET (dialog)); -} - -/* External methods */ -/** - * gal_view_instance_save_as_dialog_new - * - * Returns a new dialog for defining views. - * - * Returns: The GalViewInstanceSaveAsDialog. - */ -GtkWidget * -gal_view_instance_save_as_dialog_new (GalViewInstance *instance) -{ - GtkWidget *widget = g_object_new (GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG, NULL); - gal_view_instance_save_as_dialog_set_instance (GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (widget), instance); - return widget; -} - -void -gal_view_instance_save_as_dialog_save (GalViewInstanceSaveAsDialog *dialog) -{ - GalView *view = gal_view_instance_get_current_view (dialog->instance); - const gchar *title; - gint n; - const gchar *id = NULL; - GalViewCollectionItem *item; - - view = gal_view_clone (view); - switch (dialog->toggle) { - case GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE: - if (dialog->treeview) { - GtkTreeIter iter; - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection (dialog->treeview); - if (gtk_tree_selection_get_selected (selection, &dialog->model, &iter)) { - gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1); - - for (n = 0; n < dialog->instance->collection->view_count; n++) { - if (item == dialog->instance->collection->view_data[n]) { - id = gal_view_collection_set_nth_view (dialog->instance->collection, n, view); - gal_view_collection_save (dialog->instance->collection); - } - } - } - - } - break; - - case GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE: - if (dialog->entry_create && GTK_IS_ENTRY (dialog->entry_create)) { - title = gtk_entry_get_text (GTK_ENTRY (dialog->entry_create)); - id = gal_view_collection_append_with_title (dialog->instance->collection, title, view); - gal_view_collection_save (dialog->instance->collection); - } - break; - } - - if (id) { - gal_view_instance_set_current_view_id (dialog->instance, id); - } -} diff --git a/widgets/menus/gal-view-instance-save-as-dialog.h b/widgets/menus/gal-view-instance-save-as-dialog.h deleted file mode 100644 index b5f9ac56e8..0000000000 --- a/widgets/menus/gal-view-instance-save-as-dialog.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_H -#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_H - -#include <gtk/gtk.h> -#include <widgets/menus/gal-view-collection.h> -#include <widgets/menus/gal-view-instance.h> - -/* Standard GObject macros */ -#define GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG \ - (gal_view_instance_save_as_dialog_get_type ()) -#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG, GalViewInstanceSaveAsDialog)) -#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG, GalViewInstanceSaveAsDialogClass)) -#define GAL_IS_VIEW_INSTANCE_SAVE_AS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG)) -#define GAL_IS_VIEW_INSTANCE_SAVE_AS_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG)) -#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_VIEW_INSTANCE_SAVE_AS_DIALOG, GalViewInstanceSaveAsDialogClass)) - -G_BEGIN_DECLS - -typedef struct _GalViewInstanceSaveAsDialog GalViewInstanceSaveAsDialog; -typedef struct _GalViewInstanceSaveAsDialogClass GalViewInstanceSaveAsDialogClass; - -typedef enum { - GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE, - GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE -} GalViewInstanceSaveAsDialogToggle; - -struct _GalViewInstanceSaveAsDialog { - GtkDialog parent; - - /* item specific fields */ - GtkBuilder *builder; - GtkTreeView *treeview; - GtkTreeModel *model; - - GtkWidget *scrolledwindow, *radiobutton_replace; - GtkWidget *entry_create, *radiobutton_create; - - GalViewInstance *instance; - GalViewCollection *collection; - - GalViewInstanceSaveAsDialogToggle toggle; -}; - -struct _GalViewInstanceSaveAsDialogClass { - GtkDialogClass parent_class; -}; - -GType gal_view_instance_save_as_dialog_get_type (void); -GtkWidget * gal_view_instance_save_as_dialog_new - (GalViewInstance *instance); -void gal_view_instance_save_as_dialog_save - (GalViewInstanceSaveAsDialog *dialog); - -G_END_DECLS - -#endif /* GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_H */ diff --git a/widgets/menus/gal-view-instance-save-as-dialog.ui b/widgets/menus/gal-view-instance-save-as-dialog.ui deleted file mode 100644 index d7215f1f61..0000000000 --- a/widgets/menus/gal-view-instance-save-as-dialog.ui +++ /dev/null @@ -1,133 +0,0 @@ -<?xml version="1.0"?> -<interface> - <!-- interface-requires gtk+ 2.12 --> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkVBox" id="vbox-top"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkVBox" id="vbox1"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkRadioButton" id="radiobutton-create"> - <property name="label" translatable="yes">_Create new view</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="left_padding">24</property> - <child> - <object class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label8"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Name:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry-create</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="entry-create"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox2"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkRadioButton" id="radiobutton-replace"> - <property name="label" translatable="yes">_Replace existing view</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-create</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="left_padding">24</property> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="custom-replace"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> -</interface> diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c deleted file mode 100644 index 97ba252a0b..0000000000 --- a/widgets/menus/gal-view-instance.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sys/stat.h> - -#include <gtk/gtk.h> -#include <libxml/parser.h> -#include <glib/gstdio.h> -#include <glib/gi18n.h> - -#include <libedataserver/libedataserver.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" -#include "e-util/e-unicode.h" - -#include "gal-define-views-dialog.h" -#include "gal-view-instance.h" -#include "gal-view-instance-save-as-dialog.h" - -G_DEFINE_TYPE (GalViewInstance, gal_view_instance, G_TYPE_OBJECT) - -#define d(x) - -enum { - DISPLAY_VIEW, - CHANGED, - LOADED, - LAST_SIGNAL -}; - -static guint gal_view_instance_signals[LAST_SIGNAL] = { 0, }; - -static void -gal_view_instance_changed (GalViewInstance *instance) -{ - g_return_if_fail (instance != NULL); - g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); - - g_signal_emit ( - instance, - gal_view_instance_signals[CHANGED], 0); -} - -static void -gal_view_instance_display_view (GalViewInstance *instance, - GalView *view) -{ - g_return_if_fail (instance != NULL); - g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); - - g_signal_emit ( - instance, - gal_view_instance_signals[DISPLAY_VIEW], 0, - view); -} - -static void -save_current_view (GalViewInstance *instance) -{ - xmlDoc *doc; - xmlNode *root; - - doc = xmlNewDoc ((const guchar *)"1.0"); - root = xmlNewNode (NULL, (const guchar *)"GalViewCurrentView"); - xmlDocSetRootElement (doc, root); - - if (instance->current_id) - e_xml_set_string_prop_by_name (root, (const guchar *)"current_view", instance->current_id); - if (instance->current_type) - e_xml_set_string_prop_by_name (root, (const guchar *)"current_view_type", instance->current_type); - - if (e_xml_save_file (instance->current_view_filename, doc) == -1) - g_warning ("Unable to save view to %s - %s", instance->current_view_filename, g_strerror (errno)); - xmlFreeDoc (doc); -} - -static void -view_changed (GalView *view, - GalViewInstance *instance) -{ - if (instance->current_id != NULL) { - g_free (instance->current_id); - instance->current_id = NULL; - save_current_view (instance); - gal_view_instance_changed (instance); - } - - gal_view_save (view, instance->custom_filename); -} - -static void -disconnect_view (GalViewInstance *instance) -{ - if (instance->current_view) { - if (instance->view_changed_id) { - g_signal_handler_disconnect ( - instance->current_view, - instance->view_changed_id); - } - - g_object_unref (instance->current_view); - } - g_free (instance->current_type); - g_free (instance->current_title); - instance->current_title = NULL; - instance->current_type = NULL; - instance->view_changed_id = 0; - instance->current_view = NULL; -} - -static void -connect_view (GalViewInstance *instance, - GalView *view) -{ - if (instance->current_view) - disconnect_view (instance); - instance->current_view = view; - - instance->current_title = g_strdup (gal_view_get_title (view)); - instance->current_type = g_strdup (gal_view_get_type_code (view)); - instance->view_changed_id = g_signal_connect ( - instance->current_view, "changed", - G_CALLBACK (view_changed), instance); - - gal_view_instance_display_view (instance, instance->current_view); -} - -static void -gal_view_instance_dispose (GObject *object) -{ - GalViewInstance *instance = GAL_VIEW_INSTANCE (object); - - if (instance->collection) { - if (instance->collection_changed_id) { - g_signal_handler_disconnect ( - instance->collection, - instance->collection_changed_id); - } - g_object_unref (instance->collection); - } - - g_free (instance->instance_id); - g_free (instance->custom_filename); - g_free (instance->current_view_filename); - - g_free (instance->current_id); - disconnect_view (instance); - - g_free (instance->default_view); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_instance_parent_class)->dispose (object); -} - -static void -gal_view_instance_class_init (GalViewInstanceClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = gal_view_instance_dispose; - - gal_view_instance_signals[DISPLAY_VIEW] = g_signal_new ( - "display_view", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalViewInstanceClass, display_view), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GAL_TYPE_VIEW); - - gal_view_instance_signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalViewInstanceClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - gal_view_instance_signals[LOADED] = g_signal_new ( - "loaded", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GalViewInstanceClass, loaded), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - class->display_view = NULL; - class->changed = NULL; -} - -static void -gal_view_instance_init (GalViewInstance *instance) -{ - instance->collection = NULL; - - instance->instance_id = NULL; - instance->custom_filename = NULL; - instance->current_view_filename = NULL; - - instance->current_title = NULL; - instance->current_type = NULL; - instance->current_id = NULL; - instance->current_view = NULL; - - instance->view_changed_id = 0; - instance->collection_changed_id = 0; - - instance->loaded = FALSE; - instance->default_view = NULL; -} - -static void -collection_changed (GalView *view, - GalViewInstance *instance) -{ - if (instance->current_id) { - gchar *view_id = instance->current_id; - instance->current_id = NULL; - gal_view_instance_set_current_view_id (instance, view_id); - g_free (view_id); - } -} - -static void -load_current_view (GalViewInstance *instance) -{ - xmlDoc *doc = NULL; - xmlNode *root; - GalView *view = NULL; - - if (g_file_test (instance->current_view_filename, G_FILE_TEST_IS_REGULAR)) { -#ifdef G_OS_WIN32 - gchar *locale_filename = g_win32_locale_filename_from_utf8 (instance->current_view_filename); - if (locale_filename != NULL) - doc = xmlParseFile (locale_filename); - g_free (locale_filename); -#else - doc = xmlParseFile (instance->current_view_filename); -#endif - } - - if (doc == NULL) { - instance->current_id = g_strdup (gal_view_instance_get_default_view (instance)); - - if (instance->current_id) { - gint index = gal_view_collection_get_view_index_by_id ( - instance->collection, - instance->current_id); - - if (index != -1) { - view = gal_view_collection_get_view ( - instance->collection, index); - view = gal_view_clone (view); - connect_view (instance, view); - } - } - return; - } - - root = xmlDocGetRootElement (doc); - instance->current_id = e_xml_get_string_prop_by_name_with_default (root, (const guchar *)"current_view", NULL); - - if (instance->current_id != NULL) { - gint index = gal_view_collection_get_view_index_by_id ( - instance->collection, - instance->current_id); - - if (index != -1) { - view = gal_view_collection_get_view ( - instance->collection, index); - view = gal_view_clone (view); - } - } - if (view == NULL) { - gchar *type; - type = e_xml_get_string_prop_by_name_with_default (root, (const guchar *)"current_view_type", NULL); - view = gal_view_collection_load_view_from_file ( - instance->collection, type, - instance->custom_filename); - g_free (type); - } - - connect_view (instance, view); - - xmlFreeDoc (doc); -} - -/** - * gal_view_instance_new: - * @collection: This %GalViewCollection should be loaded before being passed to this function. - * @instance_id: Which instance of this type of object is this (for most of evo, this is the folder id.) - * - * Create a new %GalViewInstance. - * - * Return value: The new %GalViewInstance. - **/ -GalViewInstance * -gal_view_instance_new (GalViewCollection *collection, - const gchar *instance_id) -{ - GalViewInstance *instance = g_object_new (GAL_VIEW_INSTANCE_TYPE, NULL); - if (gal_view_instance_construct (instance, collection, instance_id)) - return instance; - else { - g_object_unref (instance); - return NULL; - } -} - -GalViewInstance * -gal_view_instance_construct (GalViewInstance *instance, - GalViewCollection *collection, - const gchar *instance_id) -{ - gchar *filename; - gchar *safe_id; - - g_return_val_if_fail (gal_view_collection_loaded (collection), NULL); - - instance->collection = collection; - if (collection) - g_object_ref (collection); - instance->collection_changed_id = g_signal_connect ( - collection, "changed", - G_CALLBACK (collection_changed), instance); - - if (instance_id) - instance->instance_id = g_strdup (instance_id); - else - instance->instance_id = g_strdup (""); - - safe_id = g_strdup (instance->instance_id); - e_filename_make_safe (safe_id); - - filename = g_strdup_printf ("custom_view-%s.xml", safe_id); - instance->custom_filename = g_build_filename (instance->collection->local_dir, filename, NULL); - g_free (filename); - - filename = g_strdup_printf ("current_view-%s.xml", safe_id); - instance->current_view_filename = g_build_filename (instance->collection->local_dir, filename, NULL); - g_free (filename); - - g_free (safe_id); - - return instance; -} - -/* Manipulate the current view. */ -gchar * -gal_view_instance_get_current_view_id (GalViewInstance *instance) -{ - if (instance->current_id && gal_view_collection_get_view_index_by_id (instance->collection, instance->current_id) != -1) - return g_strdup (instance->current_id); - else - return NULL; -} - -void -gal_view_instance_set_current_view_id (GalViewInstance *instance, - const gchar *view_id) -{ - GalView *view; - gint index; - - g_return_if_fail (instance != NULL); - g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); - - d (g_print ("%s: view_id set to %s\n", G_STRFUNC, view_id)); - - if (instance->current_id && !strcmp (instance->current_id, view_id)) - return; - - g_free (instance->current_id); - instance->current_id = g_strdup (view_id); - - index = gal_view_collection_get_view_index_by_id (instance->collection, view_id); - if (index != -1) { - view = gal_view_collection_get_view (instance->collection, index); - connect_view (instance, gal_view_clone (view)); - } - - if (instance->loaded) - save_current_view (instance); - gal_view_instance_changed (instance); -} - -GalView * -gal_view_instance_get_current_view (GalViewInstance *instance) -{ - return instance->current_view; -} - -void -gal_view_instance_set_custom_view (GalViewInstance *instance, - GalView *view) -{ - g_free (instance->current_id); - instance->current_id = NULL; - - view = gal_view_clone (view); - connect_view (instance, view); - gal_view_save (view, instance->custom_filename); - save_current_view (instance); - gal_view_instance_changed (instance); -} - -static void -dialog_response (GtkWidget *dialog, - gint id, - GalViewInstance *instance) -{ - if (id == GTK_RESPONSE_OK) { - gal_view_instance_save_as_dialog_save (GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (dialog)); - } - gtk_widget_destroy (dialog); -} - -void -gal_view_instance_save_as (GalViewInstance *instance) -{ - GtkWidget *dialog; - - g_return_if_fail (instance != NULL); - - dialog = gal_view_instance_save_as_dialog_new (instance); - g_signal_connect ( - dialog, "response", - G_CALLBACK (dialog_response), instance); - gtk_widget_show (dialog); -} - -/* This is idempotent. Once it's been called once, the rest of the calls are ignored. */ -void -gal_view_instance_load (GalViewInstance *instance) -{ - if (!instance->loaded) { - load_current_view (instance); - instance->loaded = TRUE; - g_signal_emit (instance, gal_view_instance_signals[LOADED], 0); - } -} - -/* These only mean anything before gal_view_instance_load is called the first time. */ -const gchar * -gal_view_instance_get_default_view (GalViewInstance *instance) -{ - if (instance->default_view) - return instance->default_view; - else - return gal_view_collection_get_default_view (instance->collection); -} - -void -gal_view_instance_set_default_view (GalViewInstance *instance, - const gchar *id) -{ - g_free (instance->default_view); - instance->default_view = g_strdup (id); -} - -gboolean -gal_view_instance_exists (GalViewInstance *instance) -{ - struct stat st; - - if (instance->current_view_filename && g_stat (instance->current_view_filename, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) - return TRUE; - else - return FALSE; - -} diff --git a/widgets/menus/gal-view-instance.h b/widgets/menus/gal-view-instance.h deleted file mode 100644 index 7495f0fa8f..0000000000 --- a/widgets/menus/gal-view-instance.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _GAL_VIEW_INSTANCE_H_ -#define _GAL_VIEW_INSTANCE_H_ - -#include <menus/gal-view-collection.h> - -G_BEGIN_DECLS - -#define GAL_VIEW_INSTANCE_TYPE (gal_view_instance_get_type ()) -#define GAL_VIEW_INSTANCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_VIEW_INSTANCE_TYPE, GalViewInstance)) -#define GAL_VIEW_INSTANCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_VIEW_INSTANCE_TYPE, GalViewInstanceClass)) -#define GAL_IS_VIEW_INSTANCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_VIEW_INSTANCE_TYPE)) -#define GAL_IS_VIEW_INSTANCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_VIEW_INSTANCE_TYPE)) - -typedef struct { - GObject base; - - GalViewCollection *collection; - - gchar *instance_id; - gchar *current_view_filename; - gchar *custom_filename; - - gchar *current_title; - gchar *current_type; - gchar *current_id; - - GalView *current_view; - - guint view_changed_id; - guint collection_changed_id; - - guint loaded : 1; - gchar *default_view; -} GalViewInstance; - -typedef struct { - GObjectClass parent_class; - - /* - * Signals - */ - void (*display_view) (GalViewInstance *instance, - GalView *view); - void (*changed) (GalViewInstance *instance); - void (*loaded) (GalViewInstance *instance); -} GalViewInstanceClass; - -/* Standard functions */ -GType gal_view_instance_get_type (void); - -/* */ -/*collection should be loaded when you call this. - instance_id: Which instance of this type of object is this (for most of evo, this is the folder id.) */ -GalViewInstance *gal_view_instance_new (GalViewCollection *collection, - const gchar *instance_id); -GalViewInstance *gal_view_instance_construct (GalViewInstance *instance, - GalViewCollection *collection, - const gchar *instance_id); - -/* Manipulate the current view. */ -gchar *gal_view_instance_get_current_view_id (GalViewInstance *instance); -void gal_view_instance_set_current_view_id (GalViewInstance *instance, - const gchar *view_id); -GalView *gal_view_instance_get_current_view (GalViewInstance *instance); - -/* Sets the current view to the given custom view. */ -void gal_view_instance_set_custom_view (GalViewInstance *instance, - GalView *view); - -/* Returns true if this instance has ever been used before. */ -gboolean gal_view_instance_exists (GalViewInstance *instance); - -/* Manipulate the view collection */ -/* void gal_view_instance_set_as_default (GalViewInstance *instance); */ -void gal_view_instance_save_as (GalViewInstance *instance); - -/* This is idempotent. Once it's been called once, the rest of the calls are ignored. */ -void gal_view_instance_load (GalViewInstance *instance); - -/* These only mean anything before gal_view_instance_load is called the first time. */ -const gchar *gal_view_instance_get_default_view (GalViewInstance *instance); -void gal_view_instance_set_default_view (GalViewInstance *instance, - const gchar *id); - -G_END_DECLS - -#endif /* _GAL_VIEW_INSTANCE_H_ */ diff --git a/widgets/menus/gal-view-new-dialog.c b/widgets/menus/gal-view-new-dialog.c deleted file mode 100644 index b0de7156dc..0000000000 --- a/widgets/menus/gal-view-new-dialog.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" -#include "e-util/e-unicode.h" - -#include "gal-define-views-model.h" -#include "gal-view-new-dialog.h" - -enum { - PROP_0, - PROP_NAME, - PROP_FACTORY -}; - -G_DEFINE_TYPE (GalViewNewDialog, gal_view_new_dialog, GTK_TYPE_DIALOG) - -static void -gal_view_new_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GalViewNewDialog *dialog; - GtkWidget *entry; - - dialog = GAL_VIEW_NEW_DIALOG (object); - - switch (property_id) { - case PROP_NAME: - entry = e_builder_get_widget (dialog->builder, "entry-name"); - if (entry && GTK_IS_ENTRY (entry)) { - gtk_entry_set_text (GTK_ENTRY (entry), g_value_get_string (value)); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - return; - } -} - -static void -gal_view_new_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GalViewNewDialog *dialog; - GtkWidget *entry; - - dialog = GAL_VIEW_NEW_DIALOG (object); - - switch (property_id) { - case PROP_NAME: - entry = e_builder_get_widget (dialog->builder, "entry-name"); - if (entry && GTK_IS_ENTRY (entry)) { - g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (entry))); - } - break; - case PROP_FACTORY: - g_value_set_object (value, dialog->selected_factory); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gal_view_new_dialog_dispose (GObject *object) -{ - GalViewNewDialog *gal_view_new_dialog = GAL_VIEW_NEW_DIALOG (object); - - if (gal_view_new_dialog->builder) - g_object_unref (gal_view_new_dialog->builder); - gal_view_new_dialog->builder = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (gal_view_new_dialog_parent_class)->dispose (object); -} - -static void -gal_view_new_dialog_class_init (GalViewNewDialogClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = gal_view_new_dialog_set_property; - object_class->get_property = gal_view_new_dialog_get_property; - object_class->dispose = gal_view_new_dialog_dispose; - - g_object_class_install_property ( - object_class, - PROP_NAME, - g_param_spec_string ( - "name", - "Name", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FACTORY, - g_param_spec_object ( - "factory", - "Factory", - NULL, - GAL_TYPE_VIEW_FACTORY, - G_PARAM_READWRITE)); -} - -static void -gal_view_new_dialog_init (GalViewNewDialog *dialog) -{ - GtkWidget *content_area; - GtkWidget *parent; - GtkWidget *widget; - - dialog->builder = gtk_builder_new (); - e_load_ui_builder_definition ( - dialog->builder, "gal-view-new-dialog.ui"); - - widget = e_builder_get_widget (dialog->builder, "table-top"); - if (!widget) { - return; - } - - g_object_ref (widget); - - parent = gtk_widget_get_parent (widget); - gtk_container_remove (GTK_CONTAINER (parent), widget); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - g_object_unref (widget); - - gtk_dialog_add_buttons ( - GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - gtk_window_set_title (GTK_WINDOW (dialog), _("Define New View")); - - dialog->collection = NULL; - dialog->selected_factory = NULL; -} - -GtkWidget * -gal_view_new_dialog_new (GalViewCollection *collection) -{ - GtkWidget *widget = - gal_view_new_dialog_construct ( - g_object_new (GAL_VIEW_NEW_DIALOG_TYPE, NULL), - collection); - return widget; -} - -static void -sensitize_ok_response (GalViewNewDialog *dialog) -{ - gboolean ok = TRUE; - const gchar *text; - - text = gtk_entry_get_text (GTK_ENTRY (dialog->entry)); - if (!text || !text[0]) - ok = FALSE; - - if (!dialog->selected_factory) - ok = FALSE; - - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok); -} - -static gboolean -selection_func (GtkTreeSelection *selection, - GtkTreeModel *model, - GtkTreePath *path, - gboolean path_currently_selected, - gpointer data) -{ - GtkTreeIter iter; - GalViewNewDialog *dialog = data; - - if (path_currently_selected) - return TRUE; - - model = GTK_TREE_MODEL (dialog->list_store); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, 1, &dialog->selected_factory, -1); - - sensitize_ok_response (dialog); - - return TRUE; -} - -static void -entry_changed (GtkWidget *entry, - gpointer data) -{ - GalViewNewDialog *dialog = data; - - sensitize_ok_response (dialog); -} - -GtkWidget * -gal_view_new_dialog_construct (GalViewNewDialog *dialog, - GalViewCollection *collection) -{ - GList *iterator; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkCellRenderer *rend; - - dialog->collection = collection; - dialog->list = e_builder_get_widget (dialog->builder,"list-type-list"); - dialog->entry = e_builder_get_widget (dialog->builder, "entry-name"); - - dialog->list_store = gtk_list_store_new ( - 2, G_TYPE_STRING, G_TYPE_POINTER); - - rend = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ( - "factory title", rend, "text", 0, NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->list), column); - - iterator = dialog->collection->factory_list; - for (; iterator; iterator = g_list_next (iterator)) { - GalViewFactory *factory = iterator->data; - GtkTreeIter iter; - - g_object_ref (factory); - gtk_list_store_append ( - dialog->list_store, &iter); - gtk_list_store_set ( - dialog->list_store, &iter, - 0, gal_view_factory_get_title (factory), - 1, factory, - -1); - } - - gtk_tree_view_set_model ( - GTK_TREE_VIEW (dialog->list), - GTK_TREE_MODEL (dialog->list_store)); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list)); - - gtk_tree_selection_set_select_function ( - selection, selection_func, dialog, NULL); - - g_signal_connect ( - dialog->entry, "changed", - G_CALLBACK (entry_changed), dialog); - - sensitize_ok_response (dialog); - - return GTK_WIDGET (dialog); -} - diff --git a/widgets/menus/gal-view-new-dialog.h b/widgets/menus/gal-view-new-dialog.h deleted file mode 100644 index 6b7d2b0335..0000000000 --- a/widgets/menus/gal-view-new-dialog.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_VIEW_NEW_DIALOG_H__ -#define __GAL_VIEW_NEW_DIALOG_H__ - -#include <gtk/gtk.h> -#include <gal-view-collection.h> - -G_BEGIN_DECLS - -/* GalViewNewDialog - A dialog displaying information about a contact. - * - * The following arguments are available: - * - * name type read/write description - * -------------------------------------------------------------------------------- - */ - -#define GAL_VIEW_NEW_DIALOG_TYPE (gal_view_new_dialog_get_type ()) -#define GAL_VIEW_NEW_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_VIEW_NEW_DIALOG_TYPE, GalViewNewDialog)) -#define GAL_VIEW_NEW_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_VIEW_NEW_DIALOG_TYPE, GalViewNewDialogClass)) -#define GAL_IS_VIEW_NEW_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_VIEW_NEW_DIALOG_TYPE)) -#define GAL_IS_VIEW_NEW_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GAL_VIEW_NEW_DIALOG_TYPE)) - -typedef struct _GalViewNewDialog GalViewNewDialog; -typedef struct _GalViewNewDialogClass GalViewNewDialogClass; - -struct _GalViewNewDialog -{ - GtkDialog parent; - - /* item specific fields */ - GtkBuilder *builder; - - GalViewCollection *collection; - GalViewFactory *selected_factory; - - GtkListStore *list_store; - - GtkWidget *entry; - GtkWidget *list; -}; - -struct _GalViewNewDialogClass -{ - GtkDialogClass parent_class; -}; - -GtkWidget *gal_view_new_dialog_new (GalViewCollection *collection); -GType gal_view_new_dialog_get_type (void); - -GtkWidget *gal_view_new_dialog_construct (GalViewNewDialog *dialog, - GalViewCollection *collection); - -G_END_DECLS - -#endif /* __GAL_VIEW_NEW_DIALOG_H__ */ diff --git a/widgets/menus/gal-view-new-dialog.ui b/widgets/menus/gal-view-new-dialog.ui deleted file mode 100644 index 227e3954d8..0000000000 --- a/widgets/menus/gal-view-new-dialog.ui +++ /dev/null @@ -1,177 +0,0 @@ -<?xml version="1.0"?> -<!--*- mode: xml -*--> -<interface> - <object class="GtkDialog" id="dialog1"> - <property name="title" translatable="yes"/> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="decorated">True</property> - <property name="skip_taskbar_hint">False</property> - <property name="skip_pager_hint">False</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">8</property> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <object class="GtkButton" id="button1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - </object> - </child> - <child> - <object class="GtkButton" id="button3"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - </object> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - <child> - <object class="GtkTable" id="table-top"> - <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="n_columns">1</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Name of new view:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">entry-name</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkEntry" id="entry-name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"/> - <property name="has_frame">True</property> - <property name="activates_default">False</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">fill</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Type of view:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">fill</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - <child> - <object class="GtkTreeView" id="list-type-list"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - <property name="rules_hint">False</property> - <property name="reorderable">False</property> - <property name="enable_search">True</property> - <accessibility> - - </accessibility> - <child internal-child="accessible"> - <object class="AtkObject" id="a11y-list-type-list1"> - <property name="AtkObject::accessible_name" translatable="yes">Type of View</property> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">fill</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="0">button1</action-widget> - <action-widget response="0">button3</action-widget> - </action-widgets> - </object> -</interface> diff --git a/widgets/menus/gal-view.c b/widgets/menus/gal-view.c deleted file mode 100644 index b24be56e83..0000000000 --- a/widgets/menus/gal-view.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gal-view.h" - -#include <e-util/e-util.h> - -#define d(x) - -enum { - PROP_0, - PROP_TITLE, - PROP_TYPE_CODE -}; - -enum { - CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_ABSTRACT_TYPE (GalView, gal_view, G_TYPE_OBJECT) - -static void -view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_TITLE: - gal_view_set_title ( - GAL_VIEW (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_TITLE: - g_value_set_string ( - value, gal_view_get_title ( - GAL_VIEW (object))); - return; - - case PROP_TYPE_CODE: - g_value_set_string ( - value, gal_view_get_type_code ( - GAL_VIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -gal_view_class_init (GalViewClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = view_set_property; - object_class->get_property = view_get_property; - - g_object_class_install_property ( - object_class, - PROP_TITLE, - g_param_spec_string ( - "title", - NULL, - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TYPE_CODE, - g_param_spec_string ( - "type-code", - NULL, - NULL, - NULL, - G_PARAM_READABLE)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalViewClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gal_view_init (GalView *view) -{ -} - -/** - * gal_view_edit - * @view: The view to edit - * @parent: the parent window. - */ -void -gal_view_edit (GalView *view, - GtkWindow *parent) -{ - GalViewClass *class; - - g_return_if_fail (GAL_IS_VIEW (view)); - g_return_if_fail (GTK_IS_WINDOW (parent)); - - class = GAL_VIEW_GET_CLASS (view); - g_return_if_fail (class->edit != NULL); - - class->edit (view, parent); -} - -/** - * gal_view_load - * @view: The view to load to - * @filename: The file to load from - */ -void -gal_view_load (GalView *view, - const gchar *filename) -{ - GalViewClass *class; - - g_return_if_fail (GAL_IS_VIEW (view)); - g_return_if_fail (filename != NULL); - - class = GAL_VIEW_GET_CLASS (view); - g_return_if_fail (class->load != NULL); - - class->load (view, filename); -} - -/** - * gal_view_save - * @view: The view to save - * @filename: The file to save to - */ -void -gal_view_save (GalView *view, - const gchar *filename) -{ - GalViewClass *class; - - g_return_if_fail (GAL_IS_VIEW (view)); - g_return_if_fail (filename != NULL); - - class = GAL_VIEW_GET_CLASS (view); - g_return_if_fail (class->save != NULL); - - class->save (view, filename); -} - -/** - * gal_view_get_title - * @view: The view to query. - * - * Returns: The title of the view. - */ -const gchar * -gal_view_get_title (GalView *view) -{ - GalViewClass *class; - - g_return_val_if_fail (GAL_IS_VIEW (view), NULL); - - class = GAL_VIEW_GET_CLASS (view); - g_return_val_if_fail (class->get_title != NULL, NULL); - - return class->get_title (view); -} - -/** - * gal_view_set_title - * @view: The view to set. - * @title: The new title value. - */ -void -gal_view_set_title (GalView *view, - const gchar *title) -{ - GalViewClass *class; - - g_return_if_fail (GAL_IS_VIEW (view)); - - class = GAL_VIEW_GET_CLASS (view); - g_return_if_fail (class->set_title != NULL); - - class->set_title (view, title); - - g_object_notify (G_OBJECT (view), "title"); -} - -/** - * gal_view_get_type_code - * @view: The view to get. - * - * Returns: The type of the view. - */ -const gchar * -gal_view_get_type_code (GalView *view) -{ - GalViewClass *class; - - g_return_val_if_fail (GAL_IS_VIEW (view), NULL); - - class = GAL_VIEW_GET_CLASS (view); - g_return_val_if_fail (class->get_type_code != NULL, NULL); - - return class->get_type_code (view); -} - -/** - * gal_view_clone - * @view: The view to clone. - * - * Returns: The clone. - */ -GalView * -gal_view_clone (GalView *view) -{ - GalViewClass *class; - - g_return_val_if_fail (GAL_IS_VIEW (view), NULL); - - class = GAL_VIEW_GET_CLASS (view); - g_return_val_if_fail (class->clone != NULL, NULL); - - return class->clone (view); -} - -/** - * gal_view_changed - * @view: The view that changed. - */ -void -gal_view_changed (GalView *view) -{ - g_return_if_fail (GAL_IS_VIEW (view)); - - g_signal_emit (view, signals[CHANGED], 0); -} - diff --git a/widgets/menus/gal-view.h b/widgets/menus/gal-view.h deleted file mode 100644 index 84c26ba77f..0000000000 --- a/widgets/menus/gal-view.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef GAL_VIEW_H -#define GAL_VIEW_H - -#include <gtk/gtk.h> -#include <libxml/tree.h> - -/* Standard GObject macros */ -#define GAL_TYPE_VIEW \ - (gal_view_get_type ()) -#define GAL_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), GAL_TYPE_VIEW, GalView)) -#define GAL_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), GAL_TYPE_VIEW, GalViewClass)) -#define GAL_IS_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), GAL_TYPE_VIEW)) -#define GAL_IS_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), GAL_TYPE_VIEW)) -#define GAL_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), GAL_TYPE_VIEW, GalViewClass)) - -G_BEGIN_DECLS - -typedef struct _GalView GalView; -typedef struct _GalViewClass GalViewClass; - -struct _GalView { - GObject parent; -}; - -struct _GalViewClass { - GObjectClass parent_class; - - /* Methods */ - void (*edit) (GalView *view, - GtkWindow *parent_window); - void (*load) (GalView *view, - const gchar *filename); - void (*save) (GalView *view, - const gchar *filename); - const gchar * (*get_title) (GalView *view); - void (*set_title) (GalView *view, - const gchar *title); - const gchar * (*get_type_code) (GalView *view); - GalView * (*clone) (GalView *view); - - /* Signals */ - void (*changed) (GalView *view); -}; - -GType gal_view_get_type (void); -void gal_view_edit (GalView *view, - GtkWindow *parent); -void gal_view_load (GalView *view, - const gchar *filename); -void gal_view_save (GalView *view, - const gchar *filename); -const gchar * gal_view_get_title (GalView *view); -void gal_view_set_title (GalView *view, - const gchar *title); -const gchar * gal_view_get_type_code (GalView *view); -GalView * gal_view_clone (GalView *view); -void gal_view_changed (GalView *view); - -G_END_DECLS - -#endif /* GAL_VIEW_H */ diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am deleted file mode 100644 index 4f4a5a17b1..0000000000 --- a/widgets/misc/Makefile.am +++ /dev/null @@ -1,289 +0,0 @@ -privsolib_LTLIBRARIES = libemiscwidgets.la - -widgetsincludedir = $(privincludedir)/misc - -ui_DATA = e-send-options.ui - -widgetsinclude_HEADERS = \ - e-action-combo-box.h \ - e-activity-bar.h \ - e-activity-proxy.h \ - e-alarm-selector.h \ - e-alert-bar.h \ - e-attachment.h \ - e-attachment-bar.h \ - e-attachment-button.h \ - e-attachment-dialog.h \ - e-attachment-handler.h \ - e-attachment-handler-image.h \ - e-attachment-handler-sendto.h \ - e-attachment-icon-view.h \ - e-attachment-paned.h \ - e-attachment-store.h \ - e-attachment-tree-view.h \ - e-attachment-view.h \ - e-auth-combo-box.h \ - e-autocomplete-selector.h \ - e-book-source-config.h \ - e-buffer-tagger.h \ - e-cal-source-config.h \ - e-calendar.h \ - e-calendar-item.h \ - e-canvas.h \ - e-canvas-background.h \ - e-canvas-utils.h \ - e-canvas-vbox.h \ - e-charset-combo-box.h \ - e-contact-map.h \ - e-contact-map-window.h \ - e-contact-marker.h \ - e-dateedit.h \ - e-focus-tracker.h \ - e-image-chooser.h \ - e-import-assistant.h \ - e-interval-chooser.h \ - e-mail-identity-combo-box.h \ - e-mail-signature-combo-box.h \ - e-mail-signature-editor.h \ - e-mail-signature-manager.h \ - e-mail-signature-preview.h \ - e-mail-signature-script-dialog.h \ - e-mail-signature-tree-view.h \ - e-map.h \ - e-menu-tool-action.h \ - e-menu-tool-button.h \ - e-online-button.h \ - e-paned.h \ - e-picture-gallery.h \ - e-popup-action.h \ - e-port-entry.h \ - e-preferences-window.h \ - e-preview-pane.h \ - e-printable.h \ - e-search-bar.h \ - e-selectable.h \ - e-selection-model.h \ - e-selection-model-array.h \ - e-selection-model-simple.h \ - e-send-options.h \ - e-source-config.h \ - e-source-config-backend.h \ - e-source-config-dialog.h \ - e-spell-entry.h \ - e-url-entry.h \ - e-web-view.h \ - e-web-view-gtkhtml.h \ - e-web-view-preview.h \ - ea-calendar-cell.h \ - ea-calendar-item.h \ - ea-cell-table.h \ - ea-widgets.h - -libemiscwidgets_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/filter \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DEVOLUTION_UIDIR=\""$(uidir)"\" \ - -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ - -DG_LOG_DOMAIN=__FILE__ \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) \ - $(CHAMPLAIN_CFLAGS) \ - $(GEO_CFLAGS) \ - $(CLUTTER_CFLAGS) - -libemiscwidgets_la_SOURCES = \ - $(widgetsinclude_HEADERS) \ - e-action-combo-box.c \ - e-activity-bar.c \ - e-activity-proxy.c \ - e-alarm-selector.c \ - e-alert-bar.c \ - e-attachment.c \ - e-attachment-bar.c \ - e-attachment-button.c \ - e-attachment-dialog.c \ - e-attachment-handler.c \ - e-attachment-handler-image.c \ - e-attachment-handler-sendto.c \ - e-attachment-icon-view.c \ - e-attachment-paned.c \ - e-attachment-store.c \ - e-attachment-tree-view.c \ - e-attachment-view.c \ - e-auth-combo-box.c \ - e-autocomplete-selector.c \ - e-book-source-config.c \ - e-buffer-tagger.c \ - e-cal-source-config.c \ - e-calendar.c \ - e-calendar-item.c \ - e-canvas.c \ - e-canvas-background.c \ - e-canvas-utils.c \ - e-canvas-vbox.c \ - e-charset-combo-box.c \ - e-contact-map.c \ - e-contact-map-window.c \ - e-contact-marker.c \ - e-dateedit.c \ - e-focus-tracker.c \ - e-image-chooser.c \ - e-import-assistant.c \ - e-interval-chooser.c \ - e-mail-identity-combo-box.c \ - e-mail-signature-combo-box.c \ - e-mail-signature-editor.c \ - e-mail-signature-manager.c \ - e-mail-signature-preview.c \ - e-mail-signature-script-dialog.c \ - e-mail-signature-tree-view.c \ - e-map.c \ - e-menu-tool-action.c \ - e-menu-tool-button.c \ - e-online-button.c \ - e-paned.c \ - e-picture-gallery.c \ - e-popup-action.c \ - e-port-entry.c \ - e-preferences-window.c \ - e-preview-pane.c \ - e-printable.c \ - e-search-bar.c \ - e-selectable.c \ - e-selection-model.c \ - e-selection-model-array.c \ - e-selection-model-simple.c \ - e-send-options.c \ - e-source-config.c \ - e-source-config-backend.c \ - e-source-config-dialog.c \ - e-spell-entry.c \ - e-url-entry.c \ - e-web-view.c \ - e-web-view-gtkhtml.c \ - e-web-view-preview.c \ - ea-calendar-cell.c \ - ea-calendar-item.c \ - ea-cell-table.c \ - ea-widgets.c - -libemiscwidgets_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libemiscwidgets_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(top_builddir)/a11y/libevolution-a11y.la \ - $(top_builddir)/libgnomecanvas/libgnomecanvas.la \ - $(top_builddir)/libemail-utils/libemail-utils.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(MATH_LIB) \ - $(ICONV_LIBS) \ - $(CHAMPLAIN_LIBS) \ - $(GEO_LIBS) \ - $(CLUTTER_LIBS) \ - $(GTKHTML_LIBS) - -error_DATA = widgets.error -errordir = $(privdatadir)/errors -# provides error rules too -@EVO_PLUGIN_RULE@ - -noinst_PROGRAMS = \ - test-calendar \ - test-dateedit \ - test-mail-signatures \ - test-preferences-window \ - test-source-config - -test_widgets_misc_CPPFLAGS= \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/filter \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DG_LOG_DOMAIN=__FILE__ \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -# test-calendar - -test_calendar_CPPFLAGS = $(test_widgets_misc_CPPFLAGS) - -test_calendar_SOURCES = test-calendar.c - -test_calendar_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -# test-dateedit - -test_dateedit_CPPFLAGS = $(test_widgets_misc_CPPFLAGS) - -test_dateedit_SOURCES = test-dateedit.c - -test_dateedit_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -# test-mail-signatures - -test_mail_signatures_CPPFLAGS = \ - $(test_widgets_misc_CPPFLAGS) \ - $(GTKHTML_CFLAGS) - -test_mail_signatures_SOURCES = test-mail-signatures.c - -test_mail_signatures_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) - -# test-preferences-window - -test_preferences_window_CPPFLAGS = $(test_widgets_misc_CPPFLAGS) - -test_preferences_window_SOURCES = test-preferences-window.c - -test_preferences_window_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -# test-source-config - -test_source_config_CPPFLAGS = $(test_widgets_misc_CPPFLAGS) - -test_source_config_SOURCES = test-source-config.c - -test_source_config_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -BUILT_SOURCES = $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = $(ui_DATA) widgets.error.xml - --include $(top_srcdir)/git.mk diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c deleted file mode 100644 index 0747a6ed27..0000000000 --- a/widgets/misc/e-action-combo-box.c +++ /dev/null @@ -1,578 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-action-combo-box.c - * - * Copyright (C) 2008 Novell, Inc. - * - * 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-action-combo-box.h" - -#include <glib/gi18n.h> - -#define E_ACTION_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxPrivate)) - -enum { - COLUMN_ACTION, - COLUMN_SORT -}; - -enum { - PROP_0, - PROP_ACTION -}; - -struct _EActionComboBoxPrivate { - GtkRadioAction *action; - GtkActionGroup *action_group; - GHashTable *index; - guint changed_handler_id; /* action::changed */ - guint group_sensitive_handler_id; /* action-group::sensitive */ - guint group_visible_handler_id; /* action-group::visible */ - gboolean group_has_icons : 1; -}; - -G_DEFINE_TYPE ( - EActionComboBox, - e_action_combo_box, - GTK_TYPE_COMBO_BOX) - -static void -action_combo_box_action_changed_cb (GtkRadioAction *action, - GtkRadioAction *current, - EActionComboBox *combo_box) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean valid; - - reference = g_hash_table_lookup ( - combo_box->priv->index, GINT_TO_POINTER ( - gtk_radio_action_get_current_value (current))); - g_return_if_fail (reference != NULL); - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - valid = gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - g_return_if_fail (valid); - - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); -} - -static void -action_combo_box_action_group_notify_cb (GtkActionGroup *action_group, - GParamSpec *pspec, - EActionComboBox *combo_box) -{ - g_object_set ( - combo_box, "sensitive", - gtk_action_group_get_sensitive (action_group), "visible", - gtk_action_group_get_visible (action_group), NULL); -} - -static void -action_combo_box_render_pixbuf (GtkCellLayout *layout, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - EActionComboBox *combo_box) -{ - GtkRadioAction *action; - gchar *icon_name; - gchar *stock_id; - gboolean sensitive; - gboolean visible; - gint width; - - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - - /* Do any of the actions have an icon? */ - if (!combo_box->priv->group_has_icons) - return; - - /* A NULL action means the row is a separator. */ - if (action == NULL) - return; - - g_object_get ( - G_OBJECT (action), - "icon-name", &icon_name, - "sensitive", &sensitive, - "stock-id", &stock_id, - "visible", &visible, - NULL); - - /* Keep the pixbuf renderer a fixed size for proper alignment. */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL); - - /* We can't set both "icon-name" and "stock-id" because setting - * one unsets the other. So pick the one that has a non-NULL - * value. If both are non-NULL, "stock-id" wins. */ - - if (stock_id != NULL) - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "icon-name", NULL, - "stock-id", stock_id, - "stock-size", GTK_ICON_SIZE_MENU, - "visible", visible, - "width", width, - NULL); - else - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "icon-name", icon_name, - "stock-id", NULL, - "stock-size", GTK_ICON_SIZE_MENU, - "visible", visible, - "width", width, - NULL); - - g_free (icon_name); - g_free (stock_id); -} - -static void -action_combo_box_render_text (GtkCellLayout *layout, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - EActionComboBox *combo_box) -{ - GtkRadioAction *action; - gchar **strv; - gchar *label; - gboolean sensitive; - gboolean visible; - gint xpad; - - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - - /* A NULL action means the row is a separator. */ - if (action == NULL) - return; - - g_object_get ( - G_OBJECT (action), - "label", &label, - "sensitive", &sensitive, - "visible", &visible, - NULL); - - /* Strip out underscores. */ - strv = g_strsplit (label, "_", -1); - g_free (label); - label = g_strjoinv (NULL, strv); - g_strfreev (strv); - - xpad = combo_box->priv->group_has_icons ? 3 : 0; - - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "text", label, - "visible", visible, - "xpad", xpad, - NULL); - - g_free (label); -} - -static gboolean -action_combo_box_is_row_separator (GtkTreeModel *model, - GtkTreeIter *iter) -{ - GtkAction *action; - gboolean separator; - - /* NULL actions are rendered as separators. */ - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - separator = (action == NULL); - if (action != NULL) - g_object_unref (action); - - return separator; -} - -static void -action_combo_box_update_model (EActionComboBox *combo_box) -{ - GtkListStore *list_store; - GSList *list; - - g_hash_table_remove_all (combo_box->priv->index); - - if (combo_box->priv->action == NULL) { - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL); - return; - } - - /* We store values in the sort column as floats so that we can - * insert separators in between consecutive integer values and - * still maintain the proper ordering. */ - list_store = gtk_list_store_new ( - 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT); - - list = gtk_radio_action_get_group (combo_box->priv->action); - combo_box->priv->group_has_icons = FALSE; - - while (list != NULL) { - GtkTreeRowReference *reference; - GtkRadioAction *action = list->data; - GtkTreePath *path; - GtkTreeIter iter; - gchar *icon_name; - gchar *stock_id; - gint value; - - g_object_get ( - action, "icon-name", &icon_name, - "stock-id", &stock_id, NULL); - combo_box->priv->group_has_icons |= - (icon_name != NULL || stock_id != NULL); - g_free (icon_name); - g_free (stock_id); - - gtk_list_store_append (list_store, &iter); - g_object_get (action, "value", &value, NULL); - gtk_list_store_set ( - list_store, &iter, COLUMN_ACTION, - list->data, COLUMN_SORT, (gfloat) value, -1); - - path = gtk_tree_model_get_path ( - GTK_TREE_MODEL (list_store), &iter); - reference = gtk_tree_row_reference_new ( - GTK_TREE_MODEL (list_store), path); - g_hash_table_insert ( - combo_box->priv->index, - GINT_TO_POINTER (value), reference); - gtk_tree_path_free (path); - - list = g_slist_next (list); - } - - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (list_store), - COLUMN_SORT, GTK_SORT_ASCENDING); - gtk_combo_box_set_model ( - GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (list_store)); - - action_combo_box_action_changed_cb ( - combo_box->priv->action, - combo_box->priv->action, - combo_box); -} - -static void -action_combo_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTION: - e_action_combo_box_set_action ( - E_ACTION_COMBO_BOX (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -action_combo_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTION: - g_value_set_object ( - value, e_action_combo_box_get_action ( - E_ACTION_COMBO_BOX (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -action_combo_box_dispose (GObject *object) -{ - EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); - - if (priv->action != NULL) { - g_object_unref (priv->action); - priv->action = NULL; - } - - if (priv->action_group != NULL) { - g_object_unref (priv->action_group); - priv->action_group = NULL; - } - - g_hash_table_remove_all (priv->index); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_action_combo_box_parent_class)->dispose (object); -} - -static void -action_combo_box_finalize (GObject *object) -{ - EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); - - g_hash_table_destroy (priv->index); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_action_combo_box_parent_class)->finalize (object); -} - -static void -action_combo_box_constructed (GObject *object) -{ - GtkComboBox *combo_box; - GtkCellRenderer *renderer; - - combo_box = GTK_COMBO_BOX (object); - - /* This needs to happen after constructor properties are set - * so that GtkCellLayout.get_area() returns something valid. */ - - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_cell_layout_pack_start ( - GTK_CELL_LAYOUT (combo_box), renderer, FALSE); - gtk_cell_layout_set_cell_data_func ( - GTK_CELL_LAYOUT (combo_box), renderer, - (GtkCellLayoutDataFunc) action_combo_box_render_pixbuf, - combo_box, NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start ( - GTK_CELL_LAYOUT (combo_box), renderer, TRUE); - gtk_cell_layout_set_cell_data_func ( - GTK_CELL_LAYOUT (combo_box), renderer, - (GtkCellLayoutDataFunc) action_combo_box_render_text, - combo_box, NULL); - - gtk_combo_box_set_row_separator_func ( - combo_box, (GtkTreeViewRowSeparatorFunc) - action_combo_box_is_row_separator, NULL, NULL); -} - -static void -action_combo_box_changed (GtkComboBox *combo_box) -{ - GtkRadioAction *action; - GtkTreeModel *model; - GtkTreeIter iter; - gint value; - - /* This method is virtual, so no need to chain up. */ - - if (!gtk_combo_box_get_active_iter (combo_box, &iter)) - return; - - model = gtk_combo_box_get_model (combo_box); - gtk_tree_model_get (model, &iter, COLUMN_ACTION, &action, -1); - g_object_get (action, "value", &value, NULL); - gtk_radio_action_set_current_value (action, value); -} - -static void -e_action_combo_box_class_init (EActionComboBoxClass *class) -{ - GObjectClass *object_class; - GtkComboBoxClass *combo_box_class; - - g_type_class_add_private (class, sizeof (EActionComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = action_combo_box_set_property; - object_class->get_property = action_combo_box_get_property; - object_class->dispose = action_combo_box_dispose; - object_class->finalize = action_combo_box_finalize; - object_class->constructed = action_combo_box_constructed; - - combo_box_class = GTK_COMBO_BOX_CLASS (class); - combo_box_class->changed = action_combo_box_changed; - - g_object_class_install_property ( - object_class, - PROP_ACTION, - g_param_spec_object ( - "action", - "Action", - "A GtkRadioAction", - GTK_TYPE_RADIO_ACTION, - G_PARAM_READWRITE)); -} - -static void -e_action_combo_box_init (EActionComboBox *combo_box) -{ - combo_box->priv = E_ACTION_COMBO_BOX_GET_PRIVATE (combo_box); - - combo_box->priv->index = g_hash_table_new_full ( - g_direct_hash, g_direct_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) gtk_tree_row_reference_free); -} - -GtkWidget * -e_action_combo_box_new (void) -{ - return e_action_combo_box_new_with_action (NULL); -} - -GtkWidget * -e_action_combo_box_new_with_action (GtkRadioAction *action) -{ - return g_object_new (E_TYPE_ACTION_COMBO_BOX, "action", action, NULL); -} - -GtkRadioAction * -e_action_combo_box_get_action (EActionComboBox *combo_box) -{ - g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), NULL); - - return combo_box->priv->action; -} - -void -e_action_combo_box_set_action (EActionComboBox *combo_box, - GtkRadioAction *action) -{ - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - - if (action != NULL) - g_return_if_fail (GTK_IS_RADIO_ACTION (action)); - - if (combo_box->priv->action != NULL) { - g_signal_handler_disconnect ( - combo_box->priv->action, - combo_box->priv->changed_handler_id); - g_object_unref (combo_box->priv->action); - } - - if (combo_box->priv->action_group != NULL) { - g_signal_handler_disconnect ( - combo_box->priv->action_group, - combo_box->priv->group_sensitive_handler_id); - g_signal_handler_disconnect ( - combo_box->priv->action_group, - combo_box->priv->group_visible_handler_id); - g_object_unref (combo_box->priv->action_group); - combo_box->priv->action_group = NULL; - } - - if (action != NULL) - g_object_get ( - g_object_ref (action), "action-group", - &combo_box->priv->action_group, NULL); - - combo_box->priv->action = action; - action_combo_box_update_model (combo_box); - - if (combo_box->priv->action != NULL) - combo_box->priv->changed_handler_id = g_signal_connect ( - combo_box->priv->action, "changed", - G_CALLBACK (action_combo_box_action_changed_cb), - combo_box); - - if (combo_box->priv->action_group != NULL) { - g_object_ref (combo_box->priv->action_group); - combo_box->priv->group_sensitive_handler_id = - g_signal_connect ( - combo_box->priv->action_group, - "notify::sensitive", G_CALLBACK ( - action_combo_box_action_group_notify_cb), - combo_box); - combo_box->priv->group_visible_handler_id = - g_signal_connect ( - combo_box->priv->action_group, - "notify::visible", G_CALLBACK ( - action_combo_box_action_group_notify_cb), - combo_box); - } - - g_object_notify (G_OBJECT (combo_box), "action"); -} - -gint -e_action_combo_box_get_current_value (EActionComboBox *combo_box) -{ - g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), 0); - g_return_val_if_fail (combo_box->priv->action != NULL, 0); - - return gtk_radio_action_get_current_value (combo_box->priv->action); -} - -void -e_action_combo_box_set_current_value (EActionComboBox *combo_box, - gint current_value) -{ - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - g_return_if_fail (combo_box->priv->action != NULL); - - gtk_radio_action_set_current_value ( - combo_box->priv->action, current_value); -} - -void -e_action_combo_box_add_separator_before (EActionComboBox *combo_box, - gint action_value) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - - /* NULL actions are rendered as separators. */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, COLUMN_ACTION, - NULL, COLUMN_SORT, (gfloat) action_value - 0.5, -1); -} - -void -e_action_combo_box_add_separator_after (EActionComboBox *combo_box, - gint action_value) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - - /* NULL actions are rendered as separators. */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, COLUMN_ACTION, - NULL, COLUMN_SORT, (gfloat) action_value + 0.5, -1); -} diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h deleted file mode 100644 index 300338639a..0000000000 --- a/widgets/misc/e-action-combo-box.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-action-combo-box.h - * - * Copyright (C) 2008 Novell, Inc. - * - * 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_ACTION_COMBO_BOX_H -#define E_ACTION_COMBO_BOX_H - -/* This is a GtkComboBox that is driven by a group of GtkRadioActions. - * Just plug in a GtkRadioAction and the widget will handle the rest. - * (Based on GtkhtmlComboBox.) */ - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_ACTION_COMBO_BOX \ - (e_action_combo_box_get_type ()) -#define E_ACTION_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBox)) -#define E_ACTION_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass)) -#define E_ACTION_IS_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ACTION_COMBO_BOX)) -#define E_ACTION_IS_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ACTION_COMBO_BOX)) -#define E_ACTION_COMBO_BOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass)) - -G_BEGIN_DECLS - -typedef struct _EActionComboBox EActionComboBox; -typedef struct _EActionComboBoxClass EActionComboBoxClass; -typedef struct _EActionComboBoxPrivate EActionComboBoxPrivate; - -struct _EActionComboBox { - GtkComboBox parent; - EActionComboBoxPrivate *priv; -}; - -struct _EActionComboBoxClass { - GtkComboBoxClass parent_class; -}; - -GType e_action_combo_box_get_type (void); -GtkWidget * e_action_combo_box_new (void); -GtkWidget * e_action_combo_box_new_with_action - (GtkRadioAction *action); -GtkRadioAction *e_action_combo_box_get_action (EActionComboBox *combo_box); -void e_action_combo_box_set_action (EActionComboBox *combo_box, - GtkRadioAction *action); -gint e_action_combo_box_get_current_value - (EActionComboBox *combo_box); -void e_action_combo_box_set_current_value - (EActionComboBox *combo_box, - gint current_value); -void e_action_combo_box_add_separator_before - (EActionComboBox *combo_box, - gint action_value); -void e_action_combo_box_add_separator_after - (EActionComboBox *combo_box, - gint action_value); - -G_END_DECLS - -#endif /* E_ACTION_COMBO_BOX_H */ diff --git a/widgets/misc/e-activity-bar.c b/widgets/misc/e-activity-bar.c deleted file mode 100644 index f85b403bd7..0000000000 --- a/widgets/misc/e-activity-bar.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * e-activity-bar.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-activity-bar.h" - -#define E_ACTIVITY_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ACTIVITY_BAR, EActivityBarPrivate)) - -#define FEEDBACK_PERIOD 1 /* seconds */ -#define COMPLETED_ICON_NAME "emblem-default" - -struct _EActivityBarPrivate { - EActivity *activity; /* weak reference */ - GtkWidget *image; /* not referenced */ - GtkWidget *label; /* not referenced */ - GtkWidget *cancel; /* not referenced */ - GtkWidget *spinner; /* not referenced */ - - /* If the user clicks the Cancel button, keep the cancelled - * EActivity object alive for a short duration so the user - * gets some visual feedback that cancellation worked. */ - guint timeout_id; -}; - -enum { - PROP_0, - PROP_ACTIVITY -}; - -G_DEFINE_TYPE ( - EActivityBar, - e_activity_bar, - GTK_TYPE_INFO_BAR) - -static void -activity_bar_feedback (EActivityBar *bar) -{ - EActivity *activity; - EActivityState state; - - activity = e_activity_bar_get_activity (bar); - g_return_if_fail (E_IS_ACTIVITY (activity)); - - state = e_activity_get_state (activity); - if (state != E_ACTIVITY_CANCELLED && state != E_ACTIVITY_COMPLETED) - return; - - if (bar->priv->timeout_id > 0) - g_source_remove (bar->priv->timeout_id); - - /* Hold a reference on the EActivity for a short - * period so the activity bar stays visible. */ - bar->priv->timeout_id = g_timeout_add_seconds_full ( - G_PRIORITY_LOW, FEEDBACK_PERIOD, (GSourceFunc) gtk_false, - g_object_ref (activity), (GDestroyNotify) g_object_unref); -} - -static void -activity_bar_update (EActivityBar *bar) -{ - EActivity *activity; - EActivityState state; - GCancellable *cancellable; - const gchar *icon_name; - gboolean sensitive; - gboolean visible; - gchar *description; - - activity = e_activity_bar_get_activity (bar); - - if (activity == NULL) { - gtk_widget_hide (GTK_WIDGET (bar)); - return; - } - - cancellable = e_activity_get_cancellable (activity); - icon_name = e_activity_get_icon_name (activity); - state = e_activity_get_state (activity); - - description = e_activity_describe (activity); - gtk_label_set_text (GTK_LABEL (bar->priv->label), description); - - if (state == E_ACTIVITY_CANCELLED) { - PangoAttribute *attr; - PangoAttrList *attr_list; - - attr_list = pango_attr_list_new (); - - attr = pango_attr_strikethrough_new (TRUE); - pango_attr_list_insert (attr_list, attr); - - gtk_label_set_attributes ( - GTK_LABEL (bar->priv->label), attr_list); - - pango_attr_list_unref (attr_list); - } else - gtk_label_set_attributes ( - GTK_LABEL (bar->priv->label), NULL); - - if (state == E_ACTIVITY_COMPLETED) - icon_name = COMPLETED_ICON_NAME; - - if (state == E_ACTIVITY_CANCELLED) { - gtk_image_set_from_stock ( - GTK_IMAGE (bar->priv->image), - GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (bar->priv->image); - } else if (icon_name != NULL) { - gtk_image_set_from_icon_name ( - GTK_IMAGE (bar->priv->image), - icon_name, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (bar->priv->image); - } else { - gtk_widget_hide (bar->priv->image); - } - - visible = (cancellable != NULL); - gtk_widget_set_visible (bar->priv->cancel, visible); - - sensitive = (state == E_ACTIVITY_RUNNING); - gtk_widget_set_sensitive (bar->priv->cancel, sensitive); - - visible = (description != NULL && *description != '\0'); - gtk_widget_set_visible (GTK_WIDGET (bar), visible); - - g_free (description); -} - -static void -activity_bar_cancel (EActivityBar *bar) -{ - EActivity *activity; - GCancellable *cancellable; - - activity = e_activity_bar_get_activity (bar); - g_return_if_fail (E_IS_ACTIVITY (activity)); - - cancellable = e_activity_get_cancellable (activity); - g_cancellable_cancel (cancellable); - - activity_bar_update (bar); -} - -static void -activity_bar_weak_notify_cb (EActivityBar *bar, - GObject *where_the_object_was) -{ - g_return_if_fail (E_IS_ACTIVITY_BAR (bar)); - - bar->priv->activity = NULL; - e_activity_bar_set_activity (bar, NULL); -} - -static void -activity_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVITY: - e_activity_bar_set_activity ( - E_ACTIVITY_BAR (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -activity_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVITY: - g_value_set_object ( - value, e_activity_bar_get_activity ( - E_ACTIVITY_BAR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -activity_bar_dispose (GObject *object) -{ - EActivityBarPrivate *priv; - - priv = E_ACTIVITY_BAR_GET_PRIVATE (object); - - if (priv->timeout_id > 0) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - if (priv->activity != NULL) { - g_signal_handlers_disconnect_matched ( - priv->activity, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_weak_unref ( - G_OBJECT (priv->activity), (GWeakNotify) - activity_bar_weak_notify_cb, object); - priv->activity = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_activity_bar_parent_class)->dispose (object); -} - -static void -e_activity_bar_class_init (EActivityBarClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EActivityBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = activity_bar_set_property; - object_class->get_property = activity_bar_get_property; - object_class->dispose = activity_bar_dispose; - - g_object_class_install_property ( - object_class, - PROP_ACTIVITY, - g_param_spec_object ( - "activity", - NULL, - NULL, - E_TYPE_ACTIVITY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_activity_bar_init (EActivityBar *bar) -{ - GtkWidget *container; - GtkWidget *widget; - - bar->priv = E_ACTIVITY_BAR_GET_PRIVATE (bar); - - container = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar)); - - widget = gtk_hbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->image = widget; - - widget = gtk_spinner_new (); - gtk_spinner_start (GTK_SPINNER (widget)); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->spinner = widget; - - /* The spinner is only visible when the image is not. */ - g_object_bind_property ( - bar->priv->image, "visible", - bar->priv->spinner, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE | - G_BINDING_INVERT_BOOLEAN); - - widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - bar->priv->label = widget; - gtk_widget_show (widget); - - /* This is only shown if the EActivity has a GCancellable. */ - widget = gtk_button_new_from_stock (GTK_STOCK_CANCEL); - gtk_info_bar_add_action_widget ( - GTK_INFO_BAR (bar), widget, GTK_RESPONSE_CANCEL); - bar->priv->cancel = widget; - gtk_widget_hide (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (activity_bar_cancel), bar); -} - -GtkWidget * -e_activity_bar_new (void) -{ - return g_object_new (E_TYPE_ACTIVITY_BAR, NULL); -} - -EActivity * -e_activity_bar_get_activity (EActivityBar *bar) -{ - g_return_val_if_fail (E_IS_ACTIVITY_BAR (bar), NULL); - - return bar->priv->activity; -} - -void -e_activity_bar_set_activity (EActivityBar *bar, - EActivity *activity) -{ - g_return_if_fail (E_IS_ACTIVITY_BAR (bar)); - - if (activity != NULL) - g_return_if_fail (E_IS_ACTIVITY (activity)); - - if (bar->priv->timeout_id > 0) { - g_source_remove (bar->priv->timeout_id); - bar->priv->timeout_id = 0; - } - - if (bar->priv->activity != NULL) { - g_signal_handlers_disconnect_matched ( - bar->priv->activity, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, bar); - g_object_weak_unref ( - G_OBJECT (bar->priv->activity), - (GWeakNotify) activity_bar_weak_notify_cb, bar); - } - - bar->priv->activity = activity; - - if (activity != NULL) { - g_object_weak_ref ( - G_OBJECT (activity), (GWeakNotify) - activity_bar_weak_notify_cb, bar); - - g_signal_connect_swapped ( - activity, "notify::state", - G_CALLBACK (activity_bar_feedback), bar); - - g_signal_connect_swapped ( - activity, "notify", - G_CALLBACK (activity_bar_update), bar); - } - - activity_bar_update (bar); - - g_object_notify (G_OBJECT (bar), "activity"); -} diff --git a/widgets/misc/e-activity-bar.h b/widgets/misc/e-activity-bar.h deleted file mode 100644 index 24f56eca53..0000000000 --- a/widgets/misc/e-activity-bar.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * e-activity-bar.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_ACTIVITY_BAR_H -#define E_ACTIVITY_BAR_H - -#include <gtk/gtk.h> -#include <e-util/e-activity.h> - -/* Standard GObject macros */ -#define E_TYPE_ACTIVITY_BAR \ - (e_activity_bar_get_type ()) -#define E_ACTIVITY_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ACTIVITY_BAR, EActivityBar)) -#define E_ACTIVITY_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ACTIVITY_BAR, EActivityBarClass)) -#define E_IS_ACTIVITY_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ACTIVITY_BAR)) -#define E_IS_ACTIVITY_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ACTIVITY_BAR)) -#define E_ACTIVITY_BAR_GET_CLASS(obj) \ - (G_TYPE_CHECK_INSTANCE_GET_TYPE \ - ((obj), E_TYPE_ACTIVITY_BAR, EActivityBarClass)) - -G_BEGIN_DECLS - -typedef struct _EActivityBar EActivityBar; -typedef struct _EActivityBarClass EActivityBarClass; -typedef struct _EActivityBarPrivate EActivityBarPrivate; - -struct _EActivityBar { - GtkInfoBar parent; - EActivityBarPrivate *priv; -}; - -struct _EActivityBarClass { - GtkInfoBarClass parent_class; -}; - -GType e_activity_bar_get_type (void); -GtkWidget * e_activity_bar_new (void); -EActivity * e_activity_bar_get_activity (EActivityBar *bar); -void e_activity_bar_set_activity (EActivityBar *bar, - EActivity *activity); - -G_END_DECLS - -#endif /* E_ACTIVITY_BAR_H */ diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c deleted file mode 100644 index 7547088aac..0000000000 --- a/widgets/misc/e-activity-proxy.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * e-activity-proxy.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-activity-proxy.h" - -#include <glib/gi18n.h> - -#define E_ACTIVITY_PROXY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyPrivate)) - -#define FEEDBACK_PERIOD 1 /* seconds */ -#define COMPLETED_ICON_NAME "emblem-default" - -struct _EActivityProxyPrivate { - EActivity *activity; /* weak reference */ - GtkWidget *image; /* not referenced */ - GtkWidget *label; /* not referenced */ - GtkWidget *cancel; /* not referenced */ - GtkWidget *spinner; /* not referenced */ - - /* If the user clicks the Cancel button, keep the cancelled - * EActivity object alive for a short duration so the user - * gets some visual feedback that cancellation worked. */ - guint timeout_id; -}; - -enum { - PROP_0, - PROP_ACTIVITY -}; - -G_DEFINE_TYPE ( - EActivityProxy, - e_activity_proxy, - GTK_TYPE_FRAME) - -static void -activity_proxy_feedback (EActivityProxy *proxy) -{ - EActivity *activity; - EActivityState state; - - activity = e_activity_proxy_get_activity (proxy); - g_return_if_fail (E_IS_ACTIVITY (activity)); - - state = e_activity_get_state (activity); - if (state != E_ACTIVITY_CANCELLED) - return; - - if (proxy->priv->timeout_id > 0) - g_source_remove (proxy->priv->timeout_id); - - /* Hold a reference on the EActivity for a short - * period so the activity proxy stays visible. */ - proxy->priv->timeout_id = g_timeout_add_seconds_full ( - G_PRIORITY_LOW, FEEDBACK_PERIOD, (GSourceFunc) gtk_false, - g_object_ref (activity), (GDestroyNotify) g_object_unref); -} - -static void -activity_proxy_update (EActivityProxy *proxy) -{ - EActivity *activity; - EActivityState state; - GCancellable *cancellable; - const gchar *icon_name; - gboolean sensitive; - gboolean visible; - gchar *description; - - activity = e_activity_proxy_get_activity (proxy); - - if (activity == NULL) { - gtk_widget_hide (GTK_WIDGET (proxy)); - return; - } - - cancellable = e_activity_get_cancellable (activity); - icon_name = e_activity_get_icon_name (activity); - state = e_activity_get_state (activity); - - description = e_activity_describe (activity); - gtk_widget_set_tooltip_text (GTK_WIDGET (proxy), description); - gtk_label_set_text (GTK_LABEL (proxy->priv->label), description); - - if (state == E_ACTIVITY_CANCELLED) { - PangoAttribute *attr; - PangoAttrList *attr_list; - - attr_list = pango_attr_list_new (); - - attr = pango_attr_strikethrough_new (TRUE); - pango_attr_list_insert (attr_list, attr); - - gtk_label_set_attributes ( - GTK_LABEL (proxy->priv->label), attr_list); - - pango_attr_list_unref (attr_list); - } else - gtk_label_set_attributes ( - GTK_LABEL (proxy->priv->label), NULL); - - if (state == E_ACTIVITY_COMPLETED) - icon_name = COMPLETED_ICON_NAME; - - if (state == E_ACTIVITY_CANCELLED) { - gtk_image_set_from_stock ( - GTK_IMAGE (proxy->priv->image), - GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (proxy->priv->image); - } else if (icon_name != NULL) { - gtk_image_set_from_icon_name ( - GTK_IMAGE (proxy->priv->image), - icon_name, GTK_ICON_SIZE_MENU); - gtk_widget_show (proxy->priv->image); - } else { - gtk_widget_hide (proxy->priv->image); - } - - visible = (cancellable != NULL); - gtk_widget_set_visible (proxy->priv->cancel, visible); - - sensitive = (state == E_ACTIVITY_RUNNING); - gtk_widget_set_sensitive (proxy->priv->cancel, sensitive); - - visible = (description != NULL && *description != '\0'); - gtk_widget_set_visible (GTK_WIDGET (proxy), visible); - - g_free (description); -} - -static void -activity_proxy_cancel (EActivityProxy *proxy) -{ - EActivity *activity; - GCancellable *cancellable; - - activity = e_activity_proxy_get_activity (proxy); - g_return_if_fail (E_IS_ACTIVITY (activity)); - - cancellable = e_activity_get_cancellable (activity); - g_cancellable_cancel (cancellable); - - activity_proxy_update (proxy); -} - -static void -activity_proxy_weak_notify_cb (EActivityProxy *proxy, - GObject *where_the_object_was) -{ - g_return_if_fail (E_IS_ACTIVITY_PROXY (proxy)); - - proxy->priv->activity = NULL; - e_activity_proxy_set_activity (proxy, NULL); -} - -static void -activity_proxy_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVITY: - e_activity_proxy_set_activity ( - E_ACTIVITY_PROXY (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -activity_proxy_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVITY: - g_value_set_object ( - value, e_activity_proxy_get_activity ( - E_ACTIVITY_PROXY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -activity_proxy_dispose (GObject *object) -{ - EActivityProxyPrivate *priv; - - priv = E_ACTIVITY_PROXY_GET_PRIVATE (object); - - if (priv->timeout_id > 0) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - if (priv->activity != NULL) { - g_signal_handlers_disconnect_matched ( - priv->activity, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_weak_unref ( - G_OBJECT (priv->activity), (GWeakNotify) - activity_proxy_weak_notify_cb, object); - priv->activity = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_activity_proxy_parent_class)->dispose (object); -} - -static void -e_activity_proxy_class_init (EActivityProxyClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EActivityProxyPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = activity_proxy_set_property; - object_class->get_property = activity_proxy_get_property; - object_class->dispose = activity_proxy_dispose; - - g_object_class_install_property ( - object_class, - PROP_ACTIVITY, - g_param_spec_object ( - "activity", - NULL, - NULL, - E_TYPE_ACTIVITY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_activity_proxy_init (EActivityProxy *proxy) -{ - GtkWidget *container; - GtkWidget *widget; - - proxy->priv = E_ACTIVITY_PROXY_GET_PRIVATE (proxy); - - gtk_frame_set_shadow_type (GTK_FRAME (proxy), GTK_SHADOW_IN); - - container = GTK_WIDGET (proxy); - - widget = gtk_hbox_new (FALSE, 3); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - proxy->priv->image = widget; - - widget = gtk_spinner_new (); - gtk_spinner_start (GTK_SPINNER (widget)); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 3); - proxy->priv->spinner = widget; - - /* The spinner is only visible when the image is not. */ - g_object_bind_property ( - proxy->priv->image, "visible", - proxy->priv->spinner, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE | - G_BINDING_INVERT_BOOLEAN); - - widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - proxy->priv->label = widget; - gtk_widget_show (widget); - - /* This is only shown if the EActivity has a GCancellable. */ - widget = gtk_button_new (); - gtk_button_set_image ( - GTK_BUTTON (widget), gtk_image_new_from_stock ( - GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU)); - gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text (widget, _("Cancel")); - proxy->priv->cancel = widget; - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (activity_proxy_cancel), proxy); -} - -GtkWidget * -e_activity_proxy_new (EActivity *activity) -{ - g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); - - return g_object_new ( - E_TYPE_ACTIVITY_PROXY, "activity", activity, NULL); -} - -EActivity * -e_activity_proxy_get_activity (EActivityProxy *proxy) -{ - g_return_val_if_fail (E_IS_ACTIVITY_PROXY (proxy), NULL); - - return proxy->priv->activity; -} - -void -e_activity_proxy_set_activity (EActivityProxy *proxy, - EActivity *activity) -{ - g_return_if_fail (E_IS_ACTIVITY_PROXY (proxy)); - - if (activity != NULL) - g_return_if_fail (E_IS_ACTIVITY (activity)); - - if (proxy->priv->timeout_id > 0) { - g_source_remove (proxy->priv->timeout_id); - proxy->priv->timeout_id = 0; - } - - if (proxy->priv->activity != NULL) { - g_signal_handlers_disconnect_matched ( - proxy->priv->activity, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, proxy); - g_object_weak_unref ( - G_OBJECT (proxy->priv->activity), - (GWeakNotify) activity_proxy_weak_notify_cb, proxy); - } - - proxy->priv->activity = activity; - - if (activity != NULL) { - g_object_weak_ref ( - G_OBJECT (activity), (GWeakNotify) - activity_proxy_weak_notify_cb, proxy); - - g_signal_connect_swapped ( - activity, "notify::state", - G_CALLBACK (activity_proxy_feedback), proxy); - - g_signal_connect_swapped ( - activity, "notify", - G_CALLBACK (activity_proxy_update), proxy); - } - - activity_proxy_update (proxy); - - g_object_notify (G_OBJECT (proxy), "activity"); -} diff --git a/widgets/misc/e-activity-proxy.h b/widgets/misc/e-activity-proxy.h deleted file mode 100644 index 975cd6ff05..0000000000 --- a/widgets/misc/e-activity-proxy.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * e-activity-proxy.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ACTIVITY_PROXY_H -#define E_ACTIVITY_PROXY_H - -#include <gtk/gtk.h> -#include <e-util/e-activity.h> - -/* Standard GObject macros */ -#define E_TYPE_ACTIVITY_PROXY \ - (e_activity_proxy_get_type ()) -#define E_ACTIVITY_PROXY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxy)) -#define E_ACTIVITY_PROXY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass)) -#define E_IS_ACTIVITY_PROXY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ACTIVITY_PROXY)) -#define E_IS_ACTIVITY_PROXY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ACTIVITY_PROXY)) -#define E_ACTIVITY_PROXY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass)) - -G_BEGIN_DECLS - -typedef struct _EActivityProxy EActivityProxy; -typedef struct _EActivityProxyClass EActivityProxyClass; -typedef struct _EActivityProxyPrivate EActivityProxyPrivate; - -struct _EActivityProxy { - GtkFrame parent; - EActivityProxyPrivate *priv; -}; - -struct _EActivityProxyClass { - GtkFrameClass parent_class; -}; - -GType e_activity_proxy_get_type (void); -GtkWidget * e_activity_proxy_new (EActivity *activity); -EActivity * e_activity_proxy_get_activity (EActivityProxy *proxy); -void e_activity_proxy_set_activity (EActivityProxy *proxy, - EActivity *activity); - -G_END_DECLS - -#endif /* E_ACTIVITY_PROXY_H */ diff --git a/widgets/misc/e-alarm-selector.c b/widgets/misc/e-alarm-selector.c deleted file mode 100644 index bdc1b7e35e..0000000000 --- a/widgets/misc/e-alarm-selector.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * e-alarm-selector.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-alarm-selector.h" - -G_DEFINE_TYPE ( - EAlarmSelector, - e_alarm_selector, - E_TYPE_SOURCE_SELECTOR) - -static gboolean -alarm_selector_get_source_selected (ESourceSelector *selector, - ESource *source) -{ - ESourceAlarms *extension; - const gchar *extension_name; - - /* Make sure this source is a calendar. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return FALSE; - - extension_name = E_SOURCE_EXTENSION_ALARMS; - extension = e_source_get_extension (source, extension_name); - g_return_val_if_fail (E_IS_SOURCE_ALARMS (extension), FALSE); - - return e_source_alarms_get_include_me (extension); -} - -static void -alarm_selector_set_source_selected (ESourceSelector *selector, - ESource *source, - gboolean selected) -{ - ESourceAlarms *extension; - const gchar *extension_name; - - /* Make sure this source is a calendar. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return; - - extension_name = E_SOURCE_EXTENSION_ALARMS; - extension = e_source_get_extension (source, extension_name); - g_return_if_fail (E_IS_SOURCE_ALARMS (extension)); - - if (selected != e_source_alarms_get_include_me (extension)) { - e_source_alarms_set_include_me (extension, selected); - e_source_selector_queue_write (selector, source); - } -} - -static void -e_alarm_selector_class_init (EAlarmSelectorClass *class) -{ - ESourceSelectorClass *source_selector_class; - - source_selector_class = E_SOURCE_SELECTOR_CLASS (class); - source_selector_class->get_source_selected = - alarm_selector_get_source_selected; - source_selector_class->set_source_selected = - alarm_selector_set_source_selected; -} - -static void -e_alarm_selector_init (EAlarmSelector *selector) -{ -} - -GtkWidget * -e_alarm_selector_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_ALARM_SELECTOR, - "extension-name", E_SOURCE_EXTENSION_CALENDAR, - "registry", registry, NULL); -} diff --git a/widgets/misc/e-alarm-selector.h b/widgets/misc/e-alarm-selector.h deleted file mode 100644 index 63500866c9..0000000000 --- a/widgets/misc/e-alarm-selector.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * e-alarm-selector.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_ALARM_SELECTOR_H -#define E_ALARM_SELECTOR_H - -#include <libedataserverui/libedataserverui.h> - -/* Standard GObject macros */ -#define E_TYPE_ALARM_SELECTOR \ - (e_alarm_selector_get_type ()) -#define E_ALARM_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ALARM_SELECTOR, EAlarmSelector)) -#define E_ALARM_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ALARM_SELECTOR, EAlarmSelectorClass)) -#define E_IS_ALARM_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ALARM_SELECTOR)) -#define E_IS_ALARM_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ALARM_SELECTOR)) -#define E_ALARM_SELECTOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ALARM_SELECTOR, EAlarmSelectorClass)) - -G_BEGIN_DECLS - -typedef struct _EAlarmSelector EAlarmSelector; -typedef struct _EAlarmSelectorClass EAlarmSelectorClass; -typedef struct _EAlarmSelectorPrivate EAlarmSelectorPrivate; - -struct _EAlarmSelector { - ESourceSelector parent; - EAlarmSelectorPrivate *priv; -}; - -struct _EAlarmSelectorClass { - ESourceSelectorClass parent_class; -}; - -GType e_alarm_selector_get_type (void) G_GNUC_CONST; -GtkWidget * e_alarm_selector_new (ESourceRegistry *registry); - -G_END_DECLS - -#endif /* E_ALARM_SELECTOR_H */ diff --git a/widgets/misc/e-alert-bar.c b/widgets/misc/e-alert-bar.c deleted file mode 100644 index 2022af99f1..0000000000 --- a/widgets/misc/e-alert-bar.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * e-alert-bar.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-alert-bar.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#define E_ALERT_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ALERT_BAR, EAlertBarPrivate)) - -#define E_ALERT_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ALERT_BAR, EAlertBarPrivate)) - -/* GTK_ICON_SIZE_DIALOG is a tad too big. */ -#define ICON_SIZE GTK_ICON_SIZE_DND - -/* Dismiss warnings automatically after 5 minutes. */ -#define WARNING_TIMEOUT_SECONDS (5 * 60) - -struct _EAlertBarPrivate { - GQueue alerts; - GtkWidget *image; /* not referenced */ - GtkWidget *primary_label; /* not referenced */ - GtkWidget *secondary_label; /* not referenced */ -}; - -G_DEFINE_TYPE ( - EAlertBar, - e_alert_bar, - GTK_TYPE_INFO_BAR) - -static void -alert_bar_response_close (EAlert *alert) -{ - e_alert_response (alert, GTK_RESPONSE_CLOSE); -} - -static void -alert_bar_show_alert (EAlertBar *alert_bar) -{ - GtkImage *image; - GtkInfoBar *info_bar; - GtkWidget *action_area; - GtkWidget *widget; - EAlert *alert; - GList *actions; - GList *children; - GtkMessageType message_type; - const gchar *primary_text; - const gchar *secondary_text; - const gchar *stock_id; - gboolean have_primary_text; - gboolean have_secondary_text; - gboolean visible; - gint response_id; - gchar *markup; - - info_bar = GTK_INFO_BAR (alert_bar); - action_area = gtk_info_bar_get_action_area (info_bar); - - alert = g_queue_peek_head (&alert_bar->priv->alerts); - g_return_if_fail (E_IS_ALERT (alert)); - - /* Remove all buttons from the previous alert. */ - children = gtk_container_get_children (GTK_CONTAINER (action_area)); - while (children != NULL) { - GtkWidget *child = GTK_WIDGET (children->data); - gtk_container_remove (GTK_CONTAINER (action_area), child); - children = g_list_delete_link (children, children); - } - - /* Add alert-specific buttons. */ - actions = e_alert_peek_actions (alert); - while (actions != NULL) { - /* These actions are already wired to trigger an - * EAlert::response signal when activated, which - * will in turn call gtk_info_bar_response(), so - * we can add buttons directly to the action - * area without knowning their response IDs. */ - - widget = gtk_button_new (); - - gtk_activatable_set_related_action ( - GTK_ACTIVATABLE (widget), - GTK_ACTION (actions->data)); - - gtk_box_pack_end ( - GTK_BOX (action_area), widget, FALSE, FALSE, 0); - - actions = g_list_next (actions); - } - - /* Add a dismiss button. */ - widget = gtk_button_new (); - gtk_button_set_image ( - GTK_BUTTON (widget), - gtk_image_new_from_stock ( - GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)); - gtk_button_set_relief ( - GTK_BUTTON (widget), GTK_RELIEF_NONE); - gtk_widget_set_tooltip_text ( - widget, _("Close this message")); - gtk_box_pack_end ( - GTK_BOX (action_area), widget, FALSE, FALSE, 0); - gtk_button_box_set_child_non_homogeneous ( - GTK_BUTTON_BOX (action_area), widget, TRUE); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (alert_bar_response_close), alert); - - primary_text = e_alert_get_primary_text (alert); - secondary_text = e_alert_get_secondary_text (alert); - - if (primary_text == NULL) - primary_text = ""; - - if (secondary_text == NULL) - secondary_text = ""; - - have_primary_text = (*primary_text != '\0'); - have_secondary_text = (*secondary_text != '\0'); - - response_id = e_alert_get_default_response (alert); - gtk_info_bar_set_default_response (info_bar, response_id); - - message_type = e_alert_get_message_type (alert); - gtk_info_bar_set_message_type (info_bar, message_type); - - widget = alert_bar->priv->primary_label; - if (have_primary_text && have_secondary_text) - markup = g_markup_printf_escaped ( - "<b>%s</b>", primary_text); - else - markup = g_markup_escape_text (primary_text, -1); - gtk_label_set_markup (GTK_LABEL (widget), markup); - gtk_widget_set_visible (widget, have_primary_text); - g_free (markup); - - widget = alert_bar->priv->secondary_label; - if (have_primary_text && have_secondary_text) - markup = g_markup_printf_escaped ( - "<small>%s</small>", secondary_text); - else - markup = g_markup_escape_text (secondary_text, -1); - gtk_label_set_markup (GTK_LABEL (widget), markup); - gtk_widget_set_visible (widget, have_secondary_text); - g_free (markup); - - stock_id = e_alert_get_stock_id (alert); - image = GTK_IMAGE (alert_bar->priv->image); - gtk_image_set_from_stock (image, stock_id, ICON_SIZE); - - /* Avoid showing an image for one-line alerts, - * which are usually questions or informational. */ - visible = have_primary_text && have_secondary_text; - gtk_widget_set_visible (alert_bar->priv->image, visible); - - gtk_widget_show (GTK_WIDGET (alert_bar)); - - /* Warnings are generally meant for transient errors. - * No need to leave them up indefinitely. Close them - * automatically if the user hasn't responded after a - * reasonable period of time has elapsed. */ - if (message_type == GTK_MESSAGE_WARNING) - e_alert_start_timer (alert, WARNING_TIMEOUT_SECONDS); -} - -static void -alert_bar_response_cb (EAlert *alert, - gint response_id, - EAlertBar *alert_bar) -{ - GQueue *queue; - EAlert *head; - gboolean was_head; - - queue = &alert_bar->priv->alerts; - head = g_queue_peek_head (queue); - was_head = (alert == head); - - g_signal_handlers_disconnect_by_func ( - alert, alert_bar_response_cb, alert_bar); - - if (g_queue_remove (queue, alert)) - g_object_unref (alert); - - if (g_queue_is_empty (queue)) - gtk_widget_hide (GTK_WIDGET (alert_bar)); - else if (was_head) { - GtkInfoBar *info_bar = GTK_INFO_BAR (alert_bar); - gtk_info_bar_response (info_bar, response_id); - alert_bar_show_alert (alert_bar); - } -} - -static void -alert_bar_dispose (GObject *object) -{ - EAlertBarPrivate *priv; - - priv = E_ALERT_BAR_GET_PRIVATE (object); - - while (!g_queue_is_empty (&priv->alerts)) { - EAlert *alert = g_queue_pop_head (&priv->alerts); - g_signal_handlers_disconnect_by_func ( - alert, alert_bar_response_cb, object); - g_object_unref (alert); - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_alert_bar_parent_class)->dispose (object); -} - -static void -alert_bar_constructed (GObject *object) -{ - EAlertBarPrivate *priv; - GtkInfoBar *info_bar; - GtkWidget *action_area; - GtkWidget *content_area; - GtkWidget *container; - GtkWidget *widget; - - priv = E_ALERT_BAR_GET_PRIVATE (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_alert_bar_parent_class)->constructed (object); - - g_queue_init (&priv->alerts); - - info_bar = GTK_INFO_BAR (object); - action_area = gtk_info_bar_get_action_area (info_bar); - content_area = gtk_info_bar_get_content_area (info_bar); - - gtk_orientable_set_orientation ( - GTK_ORIENTABLE (action_area), GTK_ORIENTATION_HORIZONTAL); - gtk_widget_set_valign (action_area, GTK_ALIGN_START); - - container = content_area; - - widget = gtk_image_new (); - gtk_misc_set_alignment (GTK_MISC (widget), 0.5, 0.0); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - priv->image = widget; - gtk_widget_show (widget); - - widget = gtk_vbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_label_set_selectable (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - priv->primary_label = widget; - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_label_set_selectable (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - priv->secondary_label = widget; - gtk_widget_show (widget); - - container = action_area; -} - -static GtkSizeRequestMode -alert_bar_get_request_mode (GtkWidget *widget) -{ - /* GtkBox does width-for-height by default. But we - * want the alert bar to be as short as possible. */ - return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; -} - -static void -e_alert_bar_class_init (EAlertBarClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EAlertBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = alert_bar_dispose; - object_class->constructed = alert_bar_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->get_request_mode = alert_bar_get_request_mode; -} - -static void -e_alert_bar_init (EAlertBar *alert_bar) -{ - alert_bar->priv = E_ALERT_BAR_GET_PRIVATE (alert_bar); -} - -GtkWidget * -e_alert_bar_new (void) -{ - return g_object_new (E_TYPE_ALERT_BAR, NULL); -} - -void -e_alert_bar_clear (EAlertBar *alert_bar) -{ - GQueue *queue; - EAlert *alert; - - g_return_if_fail (E_IS_ALERT_BAR (alert_bar)); - - queue = &alert_bar->priv->alerts; - - while ((alert = g_queue_pop_head (queue)) != NULL) - alert_bar_response_close (alert); -} - -typedef struct { - gboolean found; - EAlert *looking_for; -} DuplicateData; - -static void -alert_bar_find_duplicate_cb (EAlert *alert, - DuplicateData *dd) -{ - g_return_if_fail (dd->looking_for != NULL); - - dd->found |= ( - e_alert_get_message_type (alert) == - e_alert_get_message_type (dd->looking_for) && - g_strcmp0 ( - e_alert_get_primary_text (alert), - e_alert_get_primary_text (dd->looking_for)) == 0 && - g_strcmp0 ( - e_alert_get_secondary_text (alert), - e_alert_get_secondary_text (dd->looking_for)) == 0); -} - -void -e_alert_bar_add_alert (EAlertBar *alert_bar, - EAlert *alert) -{ - DuplicateData dd; - - g_return_if_fail (E_IS_ALERT_BAR (alert_bar)); - g_return_if_fail (E_IS_ALERT (alert)); - - dd.found = FALSE; - dd.looking_for = alert; - - g_queue_foreach ( - &alert_bar->priv->alerts, - (GFunc) alert_bar_find_duplicate_cb, &dd); - - if (dd.found) - return; - - g_signal_connect ( - alert, "response", - G_CALLBACK (alert_bar_response_cb), alert_bar); - - g_queue_push_head (&alert_bar->priv->alerts, g_object_ref (alert)); - - alert_bar_show_alert (alert_bar); -} diff --git a/widgets/misc/e-alert-bar.h b/widgets/misc/e-alert-bar.h deleted file mode 100644 index f0cf39abb1..0000000000 --- a/widgets/misc/e-alert-bar.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * e-alert-bar.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_ALERT_BAR_H -#define E_ALERT_BAR_H - -#include <gtk/gtk.h> -#include <libevolution-utils/e-alert.h> - -/* Standard GObject macros */ -#define E_TYPE_ALERT_BAR \ - (e_alert_bar_get_type ()) -#define E_ALERT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ALERT_BAR, EAlertBar)) -#define E_ALERT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ALERT_BAR, EAlertBarClass)) -#define E_IS_ALERT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ALERT_BAR)) -#define E_IS_ALERT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ALERT_BAR)) -#define E_ALERT_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ALERT_BAR, EAlertBarClass)) - -G_BEGIN_DECLS - -typedef struct _EAlertBar EAlertBar; -typedef struct _EAlertBarClass EAlertBarClass; -typedef struct _EAlertBarPrivate EAlertBarPrivate; - -struct _EAlertBar { - GtkInfoBar parent; - EAlertBarPrivate *priv; -}; - -struct _EAlertBarClass { - GtkInfoBarClass parent_class; -}; - -GType e_alert_bar_get_type (void); -GtkWidget * e_alert_bar_new (void); -void e_alert_bar_clear (EAlertBar *alert_bar); -void e_alert_bar_add_alert (EAlertBar *alert_bar, - EAlert *alert); - -G_END_DECLS - -#endif /* E_ALERT_BAR_H */ diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c deleted file mode 100644 index 3fc4753055..0000000000 --- a/widgets/misc/e-attachment-bar.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * e-attachment-bar.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-bar.h" - -#include <glib/gi18n.h> - -#include "e-attachment-store.h" -#include "e-attachment-icon-view.h" -#include "e-attachment-tree-view.h" - -#define E_ATTACHMENT_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarPrivate)) - -#define NUM_VIEWS 2 - -struct _EAttachmentBarPrivate { - GtkTreeModel *model; - GtkWidget *vbox; - GtkWidget *expander; - GtkWidget *combo_box; - GtkWidget *icon_view; - GtkWidget *tree_view; - GtkWidget *icon_frame; - GtkWidget *tree_frame; - GtkWidget *status_icon; - GtkWidget *status_label; - GtkWidget *save_all_button; - GtkWidget *save_one_button; - - gint active_view; - guint expanded : 1; -}; - -enum { - PROP_0, - PROP_ACTIVE_VIEW, - PROP_DRAGGING, - PROP_EDITABLE, - PROP_EXPANDED, - PROP_STORE -}; - -/* Forward Declarations */ -static void e_attachment_bar_interface_init - (EAttachmentViewInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EAttachmentBar, - e_attachment_bar, - GTK_TYPE_VBOX, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ATTACHMENT_VIEW, - e_attachment_bar_interface_init)) - -static void -attachment_bar_update_status (EAttachmentBar *bar) -{ - EAttachmentStore *store; - GtkActivatable *activatable; - GtkAction *action; - GtkLabel *label; - gint num_attachments; - guint64 total_size; - gchar *display_size; - gchar *markup; - - store = E_ATTACHMENT_STORE (bar->priv->model); - label = GTK_LABEL (bar->priv->status_label); - - num_attachments = e_attachment_store_get_num_attachments (store); - total_size = e_attachment_store_get_total_size (store); - display_size = g_format_size (total_size); - - if (total_size > 0) - markup = g_strdup_printf ( - "<b>%d</b> %s (%s)", num_attachments, ngettext ( - "Attachment", "Attachments", num_attachments), - display_size); - else - markup = g_strdup_printf ( - "<b>%d</b> %s", num_attachments, ngettext ( - "Attachment", "Attachments", num_attachments)); - gtk_label_set_markup (label, markup); - g_free (markup); - - activatable = GTK_ACTIVATABLE (bar->priv->save_all_button); - action = gtk_activatable_get_related_action (activatable); - gtk_action_set_visible (action, (num_attachments > 1)); - - activatable = GTK_ACTIVATABLE (bar->priv->save_one_button); - action = gtk_activatable_get_related_action (activatable); - gtk_action_set_visible (action, (num_attachments == 1)); - - g_free (display_size); -} - -static void -attachment_bar_set_store (EAttachmentBar *bar, - EAttachmentStore *store) -{ - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - - bar->priv->model = g_object_ref (store); - - gtk_icon_view_set_model ( - GTK_ICON_VIEW (bar->priv->icon_view), - bar->priv->model); - gtk_tree_view_set_model ( - GTK_TREE_VIEW (bar->priv->tree_view), - bar->priv->model); - - g_signal_connect_object ( - bar->priv->model, "notify::num-attachments", - G_CALLBACK (attachment_bar_update_status), bar, - G_CONNECT_SWAPPED); - - g_signal_connect_object ( - bar->priv->model, "notify::total-size", - G_CALLBACK (attachment_bar_update_status), bar, - G_CONNECT_SWAPPED); - - /* Initialize */ - attachment_bar_update_status (bar); -} - -static void -attachment_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVE_VIEW: - e_attachment_bar_set_active_view ( - E_ATTACHMENT_BAR (object), - g_value_get_int (value)); - return; - - case PROP_DRAGGING: - e_attachment_view_set_dragging ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_attachment_view_set_editable ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EXPANDED: - e_attachment_bar_set_expanded ( - E_ATTACHMENT_BAR (object), - g_value_get_boolean (value)); - return; - case PROP_STORE: - attachment_bar_set_store ( - E_ATTACHMENT_BAR (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVE_VIEW: - g_value_set_int ( - value, - e_attachment_bar_get_active_view ( - E_ATTACHMENT_BAR (object))); - return; - - case PROP_DRAGGING: - g_value_set_boolean ( - value, - e_attachment_view_get_dragging ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, - e_attachment_view_get_editable ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EXPANDED: - g_value_set_boolean ( - value, - e_attachment_bar_get_expanded ( - E_ATTACHMENT_BAR (object))); - return; - case PROP_STORE: - g_value_set_object ( - value, - e_attachment_bar_get_store ( - E_ATTACHMENT_BAR (object))); - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_bar_dispose (GObject *object) -{ - EAttachmentBarPrivate *priv; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); - - if (priv->model != NULL) { - g_object_unref (priv->model); - priv->model = NULL; - } - - if (priv->vbox != NULL) { - g_object_unref (priv->vbox); - priv->vbox = NULL; - } - - if (priv->expander != NULL) { - g_object_unref (priv->expander); - priv->expander = NULL; - } - - if (priv->combo_box != NULL) { - g_object_unref (priv->combo_box); - priv->combo_box = NULL; - } - - if (priv->icon_view != NULL) { - g_object_unref (priv->icon_view); - priv->icon_view = NULL; - } - - if (priv->tree_view != NULL) { - g_object_unref (priv->tree_view); - priv->tree_view = NULL; - } - - if (priv->icon_frame != NULL) { - g_object_unref (priv->icon_frame); - priv->icon_frame = NULL; - } - - if (priv->tree_frame != NULL) { - g_object_unref (priv->tree_frame); - priv->tree_frame = NULL; - } - - if (priv->status_icon != NULL) { - g_object_unref (priv->status_icon); - priv->status_icon = NULL; - } - - if (priv->status_label != NULL) { - g_object_unref (priv->status_label); - priv->status_label = NULL; - } - - if (priv->save_all_button != NULL) { - g_object_unref (priv->save_all_button); - priv->save_all_button = NULL; - } - - if (priv->save_one_button != NULL) { - g_object_unref (priv->save_one_button); - priv->save_one_button = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_bar_parent_class)->dispose (object); -} - -static void -attachment_bar_constructed (GObject *object) -{ - EAttachmentBarPrivate *priv; - GSettings *settings; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); - - /* Set up property-to-property bindings. */ - - g_object_bind_property ( - object, "active-view", - priv->combo_box, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "dragging", - priv->icon_view, "dragging", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "dragging", - priv->tree_view, "dragging", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "editable", - priv->icon_view, "editable", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "editable", - priv->tree_view, "editable", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->expander, "expanded", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->combo_box, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->vbox, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Set up property-to-GSettings bindings. */ - settings = g_settings_new ("org.gnome.evolution.shell"); - g_settings_bind ( - settings, "attachment-view", - object, "active-view", - G_SETTINGS_BIND_DEFAULT); - g_object_unref (settings); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_attachment_bar_parent_class)->constructed (object); -} - -static EAttachmentViewPrivate * -attachment_bar_get_private (EAttachmentView *view) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - return e_attachment_view_get_private (view); -} - -static GtkTreePath * -attachment_bar_get_path_at_pos (EAttachmentView *view, - gint x, - gint y) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - return e_attachment_view_get_path_at_pos (view, x, y); -} - -static EAttachmentStore * -attachment_bar_get_store (EAttachmentView *view) -{ - return e_attachment_bar_get_store (E_ATTACHMENT_BAR (view)); -} - -static GList * -attachment_bar_get_selected_paths (EAttachmentView *view) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - return e_attachment_view_get_selected_paths (view); -} - -static gboolean -attachment_bar_path_is_selected (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - return e_attachment_view_path_is_selected (view, path); -} - -static void -attachment_bar_select_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - e_attachment_view_select_path (view, path); -} - -static void -attachment_bar_unselect_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - e_attachment_view_unselect_path (view, path); -} - -static void -attachment_bar_select_all (EAttachmentView *view) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - e_attachment_view_select_all (view); -} - -static void -attachment_bar_unselect_all (EAttachmentView *view) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - e_attachment_view_unselect_all (view); -} - -static void -attachment_bar_update_actions (EAttachmentView *view) -{ - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (view); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - e_attachment_view_update_actions (view); -} - -static void -e_attachment_bar_class_init (EAttachmentBarClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAttachmentBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_bar_set_property; - object_class->get_property = attachment_bar_get_property; - object_class->dispose = attachment_bar_dispose; - object_class->constructed = attachment_bar_constructed; - - g_object_class_install_property ( - object_class, - PROP_ACTIVE_VIEW, - g_param_spec_int ( - "active-view", - "Active View", - NULL, - 0, - NUM_VIEWS, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_EXPANDED, - g_param_spec_boolean ( - "expanded", - "Expanded", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_STORE, - g_param_spec_object ( - "store", - "Attachment Store", - NULL, - E_TYPE_ATTACHMENT_STORE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_override_property ( - object_class, PROP_DRAGGING, "dragging"); - - g_object_class_override_property ( - object_class, PROP_EDITABLE, "editable"); -} - -static void -e_attachment_bar_interface_init (EAttachmentViewInterface *interface) -{ - interface->get_private = attachment_bar_get_private; - interface->get_store = attachment_bar_get_store; - interface->get_path_at_pos = attachment_bar_get_path_at_pos; - interface->get_selected_paths = attachment_bar_get_selected_paths; - interface->path_is_selected = attachment_bar_path_is_selected; - interface->select_path = attachment_bar_select_path; - interface->unselect_path = attachment_bar_unselect_path; - interface->select_all = attachment_bar_select_all; - interface->unselect_all = attachment_bar_unselect_all; - interface->update_actions = attachment_bar_update_actions; -} - -static void -e_attachment_bar_init (EAttachmentBar *bar) -{ - EAttachmentView *view; - GtkSizeGroup *size_group; - GtkWidget *container; - GtkWidget *widget; - GtkAction *action; - - bar->priv = E_ATTACHMENT_BAR_GET_PRIVATE (bar); - - gtk_box_set_spacing (GTK_BOX (bar), 6); - - /* Keep the expander label and save button the same height. */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); - - /* Construct the Attachment Views */ - - container = GTK_WIDGET (bar); - - widget = gtk_vbox_new (FALSE, 0); - gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->vbox = g_object_ref (widget); - gtk_widget_show (widget); - - container = bar->priv->vbox; - - widget = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - bar->priv->icon_frame = g_object_ref (widget); - gtk_widget_show (widget); - - container = widget; - - widget = e_attachment_icon_view_new (); - gtk_widget_set_can_focus (widget, TRUE); - gtk_icon_view_set_model (GTK_ICON_VIEW (widget), bar->priv->model); - gtk_container_add (GTK_CONTAINER (container), widget); - bar->priv->icon_view = g_object_ref (widget); - gtk_widget_show (widget); - - container = bar->priv->vbox; - - widget = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - bar->priv->tree_frame = g_object_ref (widget); - gtk_widget_hide (widget); - - container = widget; - - widget = e_attachment_tree_view_new (); - gtk_widget_set_can_focus (widget, TRUE); - gtk_tree_view_set_model (GTK_TREE_VIEW (widget), bar->priv->model); - gtk_container_add (GTK_CONTAINER (container), widget); - bar->priv->tree_view = g_object_ref (widget); - gtk_widget_show (widget); - - /* Construct the Controls */ - - container = GTK_WIDGET (bar); - - widget = gtk_hbox_new (FALSE, 12); - gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_expander_new (NULL); - gtk_expander_set_spacing (GTK_EXPANDER (widget), 0); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->expander = g_object_ref (widget); - gtk_widget_show (widget); - - /* The "Save All" button proxies the "save-all" action from - * one of the two attachment views. Doesn't matter which. */ - widget = gtk_button_new (); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - action = e_attachment_view_get_action (view, "save-all"); - gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->save_all_button = g_object_ref (widget); - gtk_widget_show (widget); - - /* Same deal with the "Save" button. */ - widget = gtk_button_new (); - view = E_ATTACHMENT_VIEW (bar->priv->icon_view); - action = e_attachment_view_get_action (view, "save-one"); - gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->save_one_button = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_alignment_new (1.0, 0.5, 0.0, 0.0); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_combo_box_text_new (); - gtk_size_group_add_widget (size_group, widget); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("Icon View")); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("List View")); - gtk_container_add (GTK_CONTAINER (container), widget); - bar->priv->combo_box = g_object_ref (widget); - gtk_widget_show (widget); - - container = bar->priv->expander; - - widget = gtk_hbox_new (FALSE, 6); - gtk_size_group_add_widget (size_group, widget); - gtk_expander_set_label_widget (GTK_EXPANDER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new_from_icon_name ( - "mail-attachment", GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->status_icon = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - bar->priv->status_label = g_object_ref (widget); - gtk_widget_show (widget); - - g_object_unref (size_group); -} - -GtkWidget * -e_attachment_bar_new (EAttachmentStore *store) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); - - return g_object_new ( - E_TYPE_ATTACHMENT_BAR, - "editable", FALSE, - "store", store, NULL); -} - -gint -e_attachment_bar_get_active_view (EAttachmentBar *bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - return bar->priv->active_view; -} - -void -e_attachment_bar_set_active_view (EAttachmentBar *bar, - gint active_view) -{ - EAttachmentView *source; - EAttachmentView *target; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS); - - if (active_view == bar->priv->active_view) - return; - - bar->priv->active_view = active_view; - - if (active_view == 0) { - gtk_widget_show (bar->priv->icon_frame); - gtk_widget_hide (bar->priv->tree_frame); - } else { - gtk_widget_hide (bar->priv->icon_frame); - gtk_widget_show (bar->priv->tree_frame); - } - - /* Synchronize the item selection of the view we're - * switching TO with the view we're switching FROM. */ - if (active_view == 0) { - /* from tree view to icon view */ - source = E_ATTACHMENT_VIEW (bar->priv->tree_view); - target = E_ATTACHMENT_VIEW (bar->priv->icon_view); - } else { - /* from icon view to tree view */ - source = E_ATTACHMENT_VIEW (bar->priv->icon_view); - target = E_ATTACHMENT_VIEW (bar->priv->tree_view); - } - - e_attachment_view_sync_selection (source, target); - - g_object_notify (G_OBJECT (bar), "active-view"); -} - -gboolean -e_attachment_bar_get_expanded (EAttachmentBar *bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), FALSE); - - return bar->priv->expanded; -} - -void -e_attachment_bar_set_expanded (EAttachmentBar *bar, - gboolean expanded) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - if (bar->priv->expanded == expanded) - return; - - bar->priv->expanded = expanded; - - g_object_notify (G_OBJECT (bar), "expanded"); -} - -EAttachmentStore * -e_attachment_bar_get_store (EAttachmentBar *bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - return E_ATTACHMENT_STORE (bar->priv->model); -} diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h deleted file mode 100644 index 3542f217df..0000000000 --- a/widgets/misc/e-attachment-bar.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * e-attachment-bar.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_BAR_H -#define E_ATTACHMENT_BAR_H - -#include <gtk/gtk.h> -#include <misc/e-attachment-view.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_BAR \ - (e_attachment_bar_get_type ()) -#define E_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBar)) -#define E_ATTACHMENT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) -#define E_IS_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_BAR)) -#define E_IS_ATTACHMENT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_BAR)) -#define E_ATTACHMENT_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentBar EAttachmentBar; -typedef struct _EAttachmentBarClass EAttachmentBarClass; -typedef struct _EAttachmentBarPrivate EAttachmentBarPrivate; - -struct _EAttachmentBar { - GtkBox parent; - EAttachmentBarPrivate *priv; -}; - -struct _EAttachmentBarClass { - GtkBoxClass parent_class; -}; - -GType e_attachment_bar_get_type (void); -GtkWidget * e_attachment_bar_new (EAttachmentStore *store); -gint e_attachment_bar_get_active_view - (EAttachmentBar *bar); -void e_attachment_bar_set_active_view - (EAttachmentBar *bar, - gint active_view); -gboolean e_attachment_bar_get_expanded - (EAttachmentBar *bar); -void e_attachment_bar_set_expanded - (EAttachmentBar *bar, - gboolean expanded); -EAttachmentStore * - e_attachment_bar_get_store (EAttachmentBar *bar); - -G_END_DECLS - -#endif /* E_ATTACHMENT_BAR_H */ diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c deleted file mode 100644 index a2057e3354..0000000000 --- a/widgets/misc/e-attachment-button.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * e-attachment-button.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* Much of the popup menu logic here was ripped from GtkMenuToolButton. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-button.h" - -#define E_ATTACHMENT_BUTTON_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonPrivate)) - -struct _EAttachmentButtonPrivate { - - EAttachmentView *view; - EAttachment *attachment; - gulong reference_handler_id; - - GBinding *can_show_binding; - GBinding *shown_binding; - - GtkWidget *expand_button; - GtkWidget *toggle_button; - GtkWidget *cell_view; - GtkWidget *popup_menu; - - guint expandable : 1; - guint expanded : 1; -}; - -enum { - PROP_0, - PROP_ATTACHMENT, - PROP_EXPANDABLE, - PROP_EXPANDED, - PROP_VIEW -}; - -G_DEFINE_TYPE ( - EAttachmentButton, - e_attachment_button, - GTK_TYPE_HBOX) - -static void -attachment_button_menu_deactivate_cb (EAttachmentButton *button) -{ - EAttachmentView *view; - GtkActionGroup *action_group; - GtkToggleButton *toggle_button; - - view = e_attachment_button_get_view (button); - action_group = e_attachment_view_get_action_group (view, "inline"); - toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); - - gtk_toggle_button_set_active (toggle_button, FALSE); - - gtk_action_group_set_visible (action_group, FALSE); -} - -static void -attachment_button_menu_position (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - EAttachmentButton *button) -{ - GtkRequisition menu_requisition; - GtkTextDirection direction; - GtkAllocation allocation; - GdkRectangle monitor; - GdkScreen *screen; - GdkWindow *window; - GtkWidget *widget; - GtkWidget *toggle_button; - gint monitor_num; - - widget = GTK_WIDGET (button); - toggle_button = button->priv->toggle_button; - gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_requisition, NULL); - - window = gtk_widget_get_parent_window (widget); - screen = gtk_widget_get_screen (GTK_WIDGET (menu)); - monitor_num = gdk_screen_get_monitor_at_window (screen, window); - if (monitor_num < 0) - monitor_num = 0; - gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - - gtk_widget_get_allocation (widget, &allocation); - - gdk_window_get_origin (window, x, y); - *x += allocation.x; - *y += allocation.y; - - direction = gtk_widget_get_direction (widget); - if (direction == GTK_TEXT_DIR_LTR) - *x += MAX (allocation.width - menu_requisition.width, 0); - else if (menu_requisition.width > allocation.width) - *x -= menu_requisition.width - allocation.width; - - gtk_widget_get_allocation (toggle_button, &allocation); - - if ((*y + allocation.height + - menu_requisition.height) <= monitor.y + monitor.height) - *y += allocation.height; - else if ((*y - menu_requisition.height) >= monitor.y) - *y -= menu_requisition.height; - else if (monitor.y + monitor.height - - (*y + allocation.height) > *y) - *y += allocation.height; - else - *y -= menu_requisition.height; - - *push_in = FALSE; -} - -static void -attachment_button_select_path (EAttachmentButton *button) -{ - EAttachmentView *view; - EAttachment *attachment; - GtkTreeRowReference *reference; - GtkTreePath *path; - - attachment = e_attachment_button_get_attachment (button); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - reference = e_attachment_get_reference (attachment); - g_return_if_fail (gtk_tree_row_reference_valid (reference)); - - view = e_attachment_button_get_view (button); - path = gtk_tree_row_reference_get_path (reference); - - e_attachment_view_unselect_all (view); - e_attachment_view_select_path (view, path); - - gtk_tree_path_free (path); -} - -static void -attachment_button_show_popup_menu (EAttachmentButton *button, - GdkEventButton *event) -{ - EAttachmentView *view; - GtkActionGroup *action_group; - GtkToggleButton *toggle_button; - - view = e_attachment_button_get_view (button); - action_group = e_attachment_view_get_action_group (view, "inline"); - toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); - - attachment_button_select_path (button); - gtk_toggle_button_set_active (toggle_button, TRUE); - - e_attachment_view_show_popup_menu ( - view, event, (GtkMenuPositionFunc) - attachment_button_menu_position, button); - - gtk_action_group_set_visible (action_group, TRUE); -} - -static void -attachment_button_update_cell_view (EAttachmentButton *button) -{ - GtkCellView *cell_view; - EAttachment *attachment; - GtkTreeRowReference *reference; - GtkTreeModel *model = NULL; - GtkTreePath *path = NULL; - - cell_view = GTK_CELL_VIEW (button->priv->cell_view); - - attachment = e_attachment_button_get_attachment (button); - if (attachment == NULL) - goto exit; - - reference = e_attachment_get_reference (attachment); - if (reference == NULL) - goto exit; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - -exit: - gtk_cell_view_set_model (cell_view, model); - gtk_cell_view_set_displayed_row (cell_view, path); - - if (path != NULL) - gtk_tree_path_free (path); -} - -static void -attachment_button_update_pixbufs (EAttachmentButton *button) -{ - GtkCellLayout *cell_layout; - GtkCellRenderer *renderer; - GdkPixbuf *pixbuf_expander_open; - GdkPixbuf *pixbuf_expander_closed; - GList *list; - - /* Grab the first cell renderer. */ - cell_layout = GTK_CELL_LAYOUT (button->priv->cell_view); - list = gtk_cell_layout_get_cells (cell_layout); - renderer = GTK_CELL_RENDERER (list->data); - g_list_free (list); - - pixbuf_expander_open = gtk_widget_render_icon ( - GTK_WIDGET (button), GTK_STOCK_GO_DOWN, - GTK_ICON_SIZE_BUTTON, NULL); - - pixbuf_expander_closed = gtk_widget_render_icon ( - GTK_WIDGET (button), GTK_STOCK_GO_FORWARD, - GTK_ICON_SIZE_BUTTON, NULL); - - g_object_set ( - renderer, - "pixbuf-expander-open", pixbuf_expander_open, - "pixbuf-expander-closed", pixbuf_expander_closed, - NULL); - - g_object_unref (pixbuf_expander_open); - g_object_unref (pixbuf_expander_closed); -} - -static void -attachment_button_expand_clicked_cb (EAttachmentButton *button) -{ - gboolean expanded; - - expanded = e_attachment_button_get_expanded (button); - e_attachment_button_set_expanded (button, !expanded); -} - -static void -attachment_button_expand_drag_begin_cb (EAttachmentButton *button, - GdkDragContext *context) -{ - EAttachmentView *view; - - view = e_attachment_button_get_view (button); - - attachment_button_select_path (button); - e_attachment_view_drag_begin (view, context); -} - -static void -attachment_button_expand_drag_data_get_cb (EAttachmentButton *button, - GdkDragContext *context, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentView *view; - - if (button->priv->attachment) { - gchar *mime_type; - - mime_type = e_attachment_get_mime_type ( - button->priv->attachment); - - if (mime_type) { - gboolean processed = FALSE; - GdkAtom atom; - gchar *atom_name; - - atom = gtk_selection_data_get_target (selection); - atom_name = gdk_atom_name (atom); - - if (g_strcmp0 (atom_name, mime_type) == 0) { - CamelMimePart *mime_part; - - mime_part = e_attachment_get_mime_part ( - button->priv->attachment); - - if (CAMEL_IS_MIME_PART (mime_part)) { - CamelDataWrapper *wrapper; - CamelStream *stream; - GByteArray *buffer; - - buffer = g_byte_array_new (); - stream = camel_stream_mem_new (); - camel_stream_mem_set_byte_array ( - CAMEL_STREAM_MEM (stream), - buffer); - wrapper = camel_medium_get_content ( - CAMEL_MEDIUM (mime_part)); - camel_data_wrapper_decode_to_stream_sync ( - wrapper, stream, NULL, NULL); - g_object_unref (stream); - - gtk_selection_data_set ( - selection, atom, 8, - buffer->data, buffer->len); - processed = TRUE; - - g_byte_array_free (buffer, TRUE); - } - } - - g_free (atom_name); - g_free (mime_type); - - if (processed) - return; - } - } - - view = e_attachment_button_get_view (button); - - e_attachment_view_drag_data_get ( - view, context, selection, info, time); -} - -static void -attachment_button_expand_drag_end_cb (EAttachmentButton *button, - GdkDragContext *context) -{ - EAttachmentView *view; - - view = e_attachment_button_get_view (button); - - e_attachment_view_drag_end (view, context); -} - -static gboolean -attachment_button_toggle_button_press_event_cb (EAttachmentButton *button, - GdkEventButton *event) -{ - if (event->button == 1) { - attachment_button_show_popup_menu (button, event); - return TRUE; - } - - return FALSE; -} - -static void -attachment_button_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ATTACHMENT: - e_attachment_button_set_attachment ( - E_ATTACHMENT_BUTTON (object), - g_value_get_object (value)); - return; - - case PROP_EXPANDABLE: - e_attachment_button_set_expandable ( - E_ATTACHMENT_BUTTON (object), - g_value_get_boolean (value)); - return; - - case PROP_EXPANDED: - e_attachment_button_set_expanded ( - E_ATTACHMENT_BUTTON (object), - g_value_get_boolean (value)); - return; - - case PROP_VIEW: - e_attachment_button_set_view ( - E_ATTACHMENT_BUTTON (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_button_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ATTACHMENT: - g_value_set_object ( - value, - e_attachment_button_get_attachment ( - E_ATTACHMENT_BUTTON (object))); - return; - - case PROP_EXPANDABLE: - g_value_set_boolean ( - value, - e_attachment_button_get_expandable ( - E_ATTACHMENT_BUTTON (object))); - return; - - case PROP_EXPANDED: - g_value_set_boolean ( - value, - e_attachment_button_get_expanded ( - E_ATTACHMENT_BUTTON (object))); - return; - - case PROP_VIEW: - g_value_set_object ( - value, - e_attachment_button_get_view ( - E_ATTACHMENT_BUTTON (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_button_dispose (GObject *object) -{ - EAttachmentButtonPrivate *priv; - - priv = E_ATTACHMENT_BUTTON_GET_PRIVATE (object); - - if (priv->view != NULL) { - g_object_unref (priv->view); - priv->view = NULL; - } - - if (priv->attachment != NULL) { - g_signal_handler_disconnect ( - priv->attachment, - priv->reference_handler_id); - g_object_unref (priv->attachment); - priv->attachment = NULL; - } - - if (priv->expand_button != NULL) { - g_object_unref (priv->expand_button); - priv->expand_button = NULL; - } - - if (priv->toggle_button != NULL) { - g_object_unref (priv->toggle_button); - priv->toggle_button = NULL; - } - - if (priv->cell_view != NULL) { - g_object_unref (priv->cell_view); - priv->cell_view = NULL; - } - - if (priv->popup_menu != NULL) { - g_signal_handlers_disconnect_matched ( - priv->popup_menu, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->popup_menu); - priv->popup_menu = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_button_parent_class)->dispose (object); -} - -static void -attachment_button_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EAttachmentButton *button; - - /* Chain up to parent's style_set() method. */ - GTK_WIDGET_CLASS (e_attachment_button_parent_class)-> - style_set (widget, previous_style); - - button = E_ATTACHMENT_BUTTON (widget); - attachment_button_update_pixbufs (button); -} - -static void -e_attachment_button_class_init (EAttachmentButtonClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EAttachmentButtonPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_button_set_property; - object_class->get_property = attachment_button_get_property; - object_class->dispose = attachment_button_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->style_set = attachment_button_style_set; - - g_object_class_install_property ( - object_class, - PROP_ATTACHMENT, - g_param_spec_object ( - "attachment", - "Attachment", - NULL, - E_TYPE_ATTACHMENT, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_EXPANDABLE, - g_param_spec_boolean ( - "expandable", - "Expandable", - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_EXPANDED, - g_param_spec_boolean ( - "expanded", - "Expanded", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_VIEW, - g_param_spec_object ( - "view", - "View", - NULL, - E_TYPE_ATTACHMENT_VIEW, - G_PARAM_READWRITE)); -} - -static void -e_attachment_button_init (EAttachmentButton *button) -{ - GtkCellRenderer *renderer; - GtkCellLayout *cell_layout; - GtkTargetEntry *targets; - GtkTargetList *list; - GtkWidget *container; - GtkWidget *widget; - GtkStyleContext *context; - gint n_targets; - - button->priv = E_ATTACHMENT_BUTTON_GET_PRIVATE (button); - - /* Configure Widgets */ - - container = GTK_WIDGET (button); - context = gtk_widget_get_style_context (container); - gtk_style_context_add_class (context, "linked"); - - widget = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - button->priv->expand_button = g_object_ref (widget); - gtk_widget_show (widget); - - g_object_bind_property ( - button, "expandable", - widget, "sensitive", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - widget = gtk_toggle_button_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - button->priv->toggle_button = g_object_ref (widget); - gtk_widget_show (widget); - - container = button->priv->expand_button; - - widget = gtk_cell_view_new (); - gtk_container_add (GTK_CONTAINER (container), widget); - button->priv->cell_view = g_object_ref (widget); - gtk_widget_show (widget); - - container = button->priv->toggle_button; - - widget = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - /* Configure Renderers */ - - cell_layout = GTK_CELL_LAYOUT (button->priv->cell_view); - - renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (renderer, "is-expander", TRUE, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); - - g_object_bind_property ( - button, "expanded", - renderer, "is-expanded", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "gicon", - E_ATTACHMENT_STORE_COLUMN_ICON); - - /* Configure Drag and Drop */ - - list = gtk_target_list_new (NULL, 0); - gtk_target_list_add_uri_targets (list, 0); - targets = gtk_target_table_new_from_list (list, &n_targets); - - gtk_drag_source_set ( - button->priv->expand_button, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_drag_source_set ( - button->priv->toggle_button, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_target_table_free (targets, n_targets); - gtk_target_list_unref (list); - - /* Configure Signal Handlers */ - - g_signal_connect_swapped ( - button->priv->expand_button, "clicked", - G_CALLBACK (attachment_button_expand_clicked_cb), button); - - g_signal_connect_swapped ( - button->priv->expand_button, "drag-begin", - G_CALLBACK (attachment_button_expand_drag_begin_cb), - button); - - g_signal_connect_swapped ( - button->priv->expand_button, "drag-data-get", - G_CALLBACK (attachment_button_expand_drag_data_get_cb), - button); - - g_signal_connect_swapped ( - button->priv->expand_button, "drag-end", - G_CALLBACK (attachment_button_expand_drag_end_cb), - button); - - g_signal_connect_swapped ( - button->priv->toggle_button, "button-press-event", - G_CALLBACK (attachment_button_toggle_button_press_event_cb), - button); - - g_signal_connect_swapped ( - button->priv->toggle_button, "drag-begin", - G_CALLBACK (attachment_button_expand_drag_begin_cb), - button); - - g_signal_connect_swapped ( - button->priv->toggle_button, "drag-data-get", - G_CALLBACK (attachment_button_expand_drag_data_get_cb), - button); - - g_signal_connect_swapped ( - button->priv->toggle_button, "drag-end", - G_CALLBACK (attachment_button_expand_drag_end_cb), - button); -} - -GtkWidget * -e_attachment_button_new () -{ - return g_object_new ( - E_TYPE_ATTACHMENT_BUTTON, NULL); -} - -EAttachmentView * -e_attachment_button_get_view (EAttachmentButton *button) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), NULL); - - return button->priv->view; -} - -void -e_attachment_button_set_view (EAttachmentButton *button, - EAttachmentView *view) -{ - GtkWidget *popup_menu; - - g_return_if_fail (button->priv->view == NULL); - - g_object_ref (view); - if (button->priv->view) - g_object_unref (button->priv->view); - button->priv->view = view; - - popup_menu = e_attachment_view_get_popup_menu (view); - - g_signal_connect_swapped ( - popup_menu, "deactivate", - G_CALLBACK (attachment_button_menu_deactivate_cb), button); - - /* Keep a reference to the popup menu so we can - * disconnect the signal handler in dispose(). */ - if (button->priv->popup_menu) - g_object_unref (button->priv->popup_menu); - button->priv->popup_menu = g_object_ref (popup_menu); -} - -EAttachment * -e_attachment_button_get_attachment (EAttachmentButton *button) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), NULL); - - return button->priv->attachment; -} - -void -e_attachment_button_set_attachment (EAttachmentButton *button, - EAttachment *attachment) -{ - GtkTargetEntry *targets; - GtkTargetList *list; - gint n_targets; - - g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); - - if (attachment != NULL) { - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_object_ref (attachment); - } - - if (button->priv->attachment != NULL) { - g_object_unref (button->priv->can_show_binding); - button->priv->can_show_binding = NULL; - g_object_unref (button->priv->shown_binding); - button->priv->shown_binding = NULL; - g_signal_handler_disconnect ( - button->priv->attachment, - button->priv->reference_handler_id); - g_object_unref (button->priv->attachment); - } - - button->priv->attachment = attachment; - - if (attachment != NULL) { - GBinding *binding; - gulong handler_id; - - binding = g_object_bind_property ( - attachment, "can-show", - button, "expandable", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - button->priv->can_show_binding = binding; - - binding = g_object_bind_property ( - attachment, "shown", - button, "expanded", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - button->priv->shown_binding = binding; - - handler_id = g_signal_connect_swapped ( - attachment, "notify::reference", - G_CALLBACK (attachment_button_update_cell_view), - button); - button->priv->reference_handler_id = handler_id; - - attachment_button_update_cell_view (button); - attachment_button_update_pixbufs (button); - } - - /* update drag sources */ - list = gtk_target_list_new (NULL, 0); - gtk_target_list_add_uri_targets (list, 0); - - if (attachment) { - gchar *simple_type; - - simple_type = e_attachment_get_mime_type (attachment); - if (simple_type) { - GtkTargetEntry attach_entry[] = { { NULL, 0, 2 } }; - - attach_entry[0].target = simple_type; - - gtk_target_list_add_table ( - list, attach_entry, - G_N_ELEMENTS (attach_entry)); - - g_free (simple_type); - } - } - - targets = gtk_target_table_new_from_list (list, &n_targets); - - gtk_drag_source_set ( - button->priv->expand_button, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_drag_source_set ( - button->priv->toggle_button, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_target_table_free (targets, n_targets); - gtk_target_list_unref (list); - - g_object_notify (G_OBJECT (button), "attachment"); -} - -gboolean -e_attachment_button_get_expandable (EAttachmentButton *button) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), FALSE); - - return button->priv->expandable; -} - -void -e_attachment_button_set_expandable (EAttachmentButton *button, - gboolean expandable) -{ - g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); - - if (button->priv->expandable == expandable) - return; - - button->priv->expandable = expandable; - - if (!expandable) - e_attachment_button_set_expanded (button, FALSE); - - g_object_notify (G_OBJECT (button), "expandable"); -} - -gboolean -e_attachment_button_get_expanded (EAttachmentButton *button) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), FALSE); - - return button->priv->expanded; -} - -void -e_attachment_button_set_expanded (EAttachmentButton *button, - gboolean expanded) -{ - g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); - - if (button->priv->expanded == expanded) - return; - - button->priv->expanded = expanded; - - g_object_notify (G_OBJECT (button), "expanded"); -} diff --git a/widgets/misc/e-attachment-button.h b/widgets/misc/e-attachment-button.h deleted file mode 100644 index 56adf704f0..0000000000 --- a/widgets/misc/e-attachment-button.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * e-attachment-button.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_BUTTON_H -#define E_ATTACHMENT_BUTTON_H - -#include <gtk/gtk.h> -#include <misc/e-attachment.h> -#include <misc/e-attachment-view.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_BUTTON \ - (e_attachment_button_get_type ()) -#define E_ATTACHMENT_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButton)) -#define E_ATTACHMENT_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonClass)) -#define E_IS_ATTACHMENT_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_BUTTON)) -#define E_IS_ATTACHMENT_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_BUTTON)) -#define E_ATTACHMENT_BUTTON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentButton EAttachmentButton; -typedef struct _EAttachmentButtonClass EAttachmentButtonClass; -typedef struct _EAttachmentButtonPrivate EAttachmentButtonPrivate; - -struct _EAttachmentButton { - GtkBox parent; - EAttachmentButtonPrivate *priv; -}; - -struct _EAttachmentButtonClass { - GtkBoxClass parent_class; -}; - -GType e_attachment_button_get_type (void); -GtkWidget * e_attachment_button_new (void); -EAttachmentView * - e_attachment_button_get_view (EAttachmentButton *button); -void e_attachment_button_set_view (EAttachmentButton *button, - EAttachmentView *view); -EAttachment * e_attachment_button_get_attachment - (EAttachmentButton *button); -void e_attachment_button_set_attachment - (EAttachmentButton *button, - EAttachment *attachment); -gboolean e_attachment_button_get_expandable - (EAttachmentButton *button); -void e_attachment_button_set_expandable - (EAttachmentButton *button, - gboolean expandable); -gboolean e_attachment_button_get_expanded - (EAttachmentButton *button); -void e_attachment_button_set_expanded - (EAttachmentButton *button, - gboolean expanded); - -G_END_DECLS - -#endif /* E_ATTACHMENT_BUTTON_H */ diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c deleted file mode 100644 index 9a9a1e7942..0000000000 --- a/widgets/misc/e-attachment-dialog.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * e-attachment-dialog.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-dialog.h" - -#include <glib/gi18n.h> - -#define E_ATTACHMENT_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogPrivate)) - -struct _EAttachmentDialogPrivate { - EAttachment *attachment; - GtkWidget *display_name_entry; - GtkWidget *description_entry; - GtkWidget *content_type_label; - GtkWidget *disposition_checkbox; -}; - -enum { - PROP_0, - PROP_ATTACHMENT -}; - -G_DEFINE_TYPE ( - EAttachmentDialog, - e_attachment_dialog, - GTK_TYPE_DIALOG) - -static void -attachment_dialog_update (EAttachmentDialog *dialog) -{ - EAttachment *attachment; - GFileInfo *file_info; - GtkWidget *widget; - const gchar *content_type; - const gchar *display_name; - const gchar *description; - const gchar *disposition; - gchar *type_description = NULL; - gboolean sensitive; - gboolean active; - - attachment = e_attachment_dialog_get_attachment (dialog); - - if (attachment != NULL) { - file_info = e_attachment_get_file_info (attachment); - description = e_attachment_get_description (attachment); - disposition = e_attachment_get_disposition (attachment); - } else { - file_info = NULL; - description = NULL; - disposition = NULL; - } - - if (file_info != NULL) { - content_type = g_file_info_get_content_type (file_info); - display_name = g_file_info_get_display_name (file_info); - } else { - content_type = NULL; - display_name = NULL; - } - - if (content_type != NULL) { - gchar *comment; - gchar *mime_type; - - comment = g_content_type_get_description (content_type); - mime_type = g_content_type_get_mime_type (content_type); - - type_description = - g_strdup_printf ("%s (%s)", comment, mime_type); - - g_free (comment); - g_free (mime_type); - } - - sensitive = G_IS_FILE_INFO (file_info); - - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); - - widget = dialog->priv->display_name_entry; - gtk_widget_set_sensitive (widget, sensitive); - if (display_name != NULL) - gtk_entry_set_text (GTK_ENTRY (widget), display_name); - - widget = dialog->priv->description_entry; - gtk_widget_set_sensitive (widget, sensitive); - if (description != NULL) - gtk_entry_set_text (GTK_ENTRY (widget), description); - - widget = dialog->priv->content_type_label; - gtk_label_set_text (GTK_LABEL (widget), type_description); - - active = (g_strcmp0 (disposition, "inline") == 0); - widget = dialog->priv->disposition_checkbox; - gtk_widget_set_sensitive (widget, sensitive); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active); - - g_free (type_description); -} - -static void -attachment_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ATTACHMENT: - e_attachment_dialog_set_attachment ( - E_ATTACHMENT_DIALOG (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ATTACHMENT: - g_value_set_object ( - value, e_attachment_dialog_get_attachment ( - E_ATTACHMENT_DIALOG (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_dialog_dispose (GObject *object) -{ - EAttachmentDialogPrivate *priv; - - priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (object); - - if (priv->attachment != NULL) { - g_object_unref (priv->attachment); - priv->attachment = NULL; - } - - if (priv->display_name_entry != NULL) { - g_object_unref (priv->display_name_entry); - priv->display_name_entry = NULL; - } - - if (priv->description_entry != NULL) { - g_object_unref (priv->description_entry); - priv->description_entry = NULL; - } - - if (priv->content_type_label != NULL) { - g_object_unref (priv->content_type_label); - priv->content_type_label = NULL; - } - - if (priv->disposition_checkbox != NULL) { - g_object_unref (priv->disposition_checkbox); - priv->disposition_checkbox = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_dialog_parent_class)->dispose (object); -} - -static void -attachment_dialog_map (GtkWidget *widget) -{ - GtkWidget *action_area; - GtkWidget *content_area; - - /* Chain up to parent's map() method. */ - GTK_WIDGET_CLASS (e_attachment_dialog_parent_class)->map (widget); - - /* XXX Override GtkDialog's broken style property defaults. */ - action_area = gtk_dialog_get_action_area (GTK_DIALOG (widget)); - content_area = gtk_dialog_get_content_area (GTK_DIALOG (widget)); - - gtk_box_set_spacing (GTK_BOX (content_area), 12); - gtk_container_set_border_width (GTK_CONTAINER (action_area), 0); - gtk_container_set_border_width (GTK_CONTAINER (content_area), 12); -} - -static void -attachment_dialog_response (GtkDialog *dialog, - gint response_id) -{ - EAttachmentDialogPrivate *priv; - EAttachment *attachment; - GtkToggleButton *button; - GFileInfo *file_info; - CamelMimePart *mime_part; - const gchar *attribute; - const gchar *text; - gboolean active; - - if (response_id != GTK_RESPONSE_OK) - return; - - priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (dialog); - g_return_if_fail (E_IS_ATTACHMENT (priv->attachment)); - attachment = priv->attachment; - - file_info = e_attachment_get_file_info (attachment); - g_return_if_fail (G_IS_FILE_INFO (file_info)); - - mime_part = e_attachment_get_mime_part (attachment); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; - text = gtk_entry_get_text (GTK_ENTRY (priv->display_name_entry)); - g_file_info_set_attribute_string (file_info, attribute, text); - - if (mime_part != NULL) - camel_mime_part_set_filename (mime_part, text); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - text = gtk_entry_get_text (GTK_ENTRY (priv->description_entry)); - g_file_info_set_attribute_string (file_info, attribute, text); - - if (mime_part != NULL) - camel_mime_part_set_description (mime_part, text); - - button = GTK_TOGGLE_BUTTON (priv->disposition_checkbox); - active = gtk_toggle_button_get_active (button); - text = active ? "inline" : "attachment"; - e_attachment_set_disposition (attachment, text); - - if (mime_part != NULL) - camel_mime_part_set_disposition (mime_part, text); - - g_object_notify (G_OBJECT (attachment), "file-info"); -} - -static void -e_attachment_dialog_class_init (EAttachmentDialogClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkDialogClass *dialog_class; - - g_type_class_add_private (class, sizeof (EAttachmentDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_dialog_set_property; - object_class->get_property = attachment_dialog_get_property; - object_class->dispose = attachment_dialog_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->map = attachment_dialog_map; - - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = attachment_dialog_response; - - g_object_class_install_property ( - object_class, - PROP_ATTACHMENT, - g_param_spec_object ( - "attachment", - "Attachment", - NULL, - E_TYPE_ATTACHMENT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_attachment_dialog_init (EAttachmentDialog *dialog) -{ - GtkWidget *container; - GtkWidget *widget; - - dialog->priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (dialog); - - gtk_dialog_add_button ( - GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_dialog_add_button ( - GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); - gtk_window_set_icon_name ( - GTK_WINDOW (dialog), "mail-attachment"); - gtk_window_set_title ( - GTK_WINDOW (dialog), _("Attachment Properties")); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - - container = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - - widget = gtk_table_new (4, 2, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (widget), 6); - gtk_table_set_row_spacings (GTK_TABLE (widget), 6); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_entry_new (); - gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->display_name_entry = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new_with_mnemonic (_("F_ilename:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), dialog->priv->display_name_entry); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_entry_new (); - gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->description_entry = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new_with_mnemonic (_("_Description:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), dialog->priv->description_entry); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->content_type_label = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new (_("MIME Type:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_check_button_new_with_mnemonic ( - _("_Suggest automatic display of attachment")); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->disposition_checkbox = g_object_ref (widget); - gtk_widget_show (widget); -} - -GtkWidget * -e_attachment_dialog_new (GtkWindow *parent, - EAttachment *attachment) -{ - if (parent != NULL) - g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); - if (attachment != NULL) - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return g_object_new ( - E_TYPE_ATTACHMENT_DIALOG, - "transient-for", parent, "attachment", attachment, NULL); -} - -EAttachment * -e_attachment_dialog_get_attachment (EAttachmentDialog *dialog) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_DIALOG (dialog), NULL); - - return dialog->priv->attachment; -} - -void -e_attachment_dialog_set_attachment (EAttachmentDialog *dialog, - EAttachment *attachment) -{ - g_return_if_fail (E_IS_ATTACHMENT_DIALOG (dialog)); - - if (attachment != NULL) { - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_object_ref (attachment); - } - - if (dialog->priv->attachment != NULL) - g_object_unref (dialog->priv->attachment); - - dialog->priv->attachment = attachment; - - attachment_dialog_update (dialog); - - g_object_notify (G_OBJECT (dialog), "attachment"); -} diff --git a/widgets/misc/e-attachment-dialog.h b/widgets/misc/e-attachment-dialog.h deleted file mode 100644 index 503dcbbc67..0000000000 --- a/widgets/misc/e-attachment-dialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * e-attachment-dialog.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_DIALOG_H -#define E_ATTACHMENT_DIALOG_H - -#include <gtk/gtk.h> -#include <misc/e-attachment.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_DIALOG \ - (e_attachment_dialog_get_type ()) -#define E_ATTACHMENT_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialog)) -#define E_ATTACHMENT_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogClass)) -#define E_IS_ATTACHMENT_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_DIALOG)) -#define E_IS_ATTACHMENT_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_DIALOG)) -#define E_ATTACHMENT_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentDialog EAttachmentDialog; -typedef struct _EAttachmentDialogClass EAttachmentDialogClass; -typedef struct _EAttachmentDialogPrivate EAttachmentDialogPrivate; - -struct _EAttachmentDialog { - GtkDialog parent; - EAttachmentDialogPrivate *priv; -}; - -struct _EAttachmentDialogClass { - GtkDialogClass parent_class; -}; - -GType e_attachment_dialog_get_type (void); -GtkWidget * e_attachment_dialog_new (GtkWindow *parent, - EAttachment *attachment); -EAttachment * e_attachment_dialog_get_attachment - (EAttachmentDialog *dialog); -void e_attachment_dialog_set_attachment - (EAttachmentDialog *dialog, - EAttachment *attachment); - -G_END_DECLS - -#endif /* E_ATTACHMENT_DIALOG_H */ diff --git a/widgets/misc/e-attachment-handler-image.c b/widgets/misc/e-attachment-handler-image.c deleted file mode 100644 index a8c29f24c0..0000000000 --- a/widgets/misc/e-attachment-handler-image.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * e-attachment-handler-image.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-handler-image.h" - -#include <glib/gi18n.h> -#include <gdesktop-enums.h> - -#include <e-util/e-util.h> - -#define E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImagePrivate)) - -struct _EAttachmentHandlerImagePrivate { - gint placeholder; -}; - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <placeholder name='custom-actions'>" -" <menuitem action='image-set-as-background'/>" -" </placeholder>" -" </popup>" -"</ui>"; - -G_DEFINE_TYPE ( - EAttachmentHandlerImage, - e_attachment_handler_image, - E_TYPE_ATTACHMENT_HANDLER) - -static void -action_image_set_as_background_saved_cb (EAttachment *attachment, - GAsyncResult *result, - EAttachmentHandler *handler) -{ - GDesktopBackgroundStyle style; - EAttachmentView *view; - GSettings *settings; - GtkWidget *dialog; - GFile *file; - gpointer parent; - gchar *uri; - GError *error = NULL; - - view = e_attachment_handler_get_view (handler); - settings = g_settings_new ("org.gnome.desktop.background"); - - file = e_attachment_save_finish (attachment, result, &error); - - if (error != NULL) - goto error; - - uri = g_file_get_uri (file); - g_settings_set_string (settings, "picture-uri", uri); - g_free (uri); - - style = g_settings_get_enum (settings, "picture-options"); - if (style == G_DESKTOP_BACKGROUND_STYLE_NONE) - g_settings_set_enum ( - settings, "picture-options", - G_DESKTOP_BACKGROUND_STYLE_WALLPAPER); - - g_object_unref (file); - - goto exit; - -error: - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "<big><b>%s</b></big>", - _("Could not set as background")); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); - -exit: - g_object_unref (settings); - g_object_unref (handler); -} - -static void -action_image_set_as_background_cb (GtkAction *action, - EAttachmentHandler *handler) -{ - EAttachmentView *view; - EAttachment *attachment; - GFile *destination; - GList *selected; - const gchar *path; - - view = e_attachment_handler_get_view (handler); - selected = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (selected) == 1); - attachment = E_ATTACHMENT (selected->data); - - /* Save the image under the user's Pictures directory. */ - path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES); - destination = g_file_new_for_path (path); - g_mkdir_with_parents (path, 0755); - - e_attachment_save_async ( - attachment, destination, (GAsyncReadyCallback) - action_image_set_as_background_saved_cb, - g_object_ref (handler)); - - g_object_unref (destination); - - g_list_foreach (selected, (GFunc) g_object_unref, NULL); - g_list_free (selected); -} - -static GtkActionEntry standard_entries[] = { - - { "image-set-as-background", - NULL, - N_("Set as _Background"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_image_set_as_background_cb) } -}; - -static void -attachment_handler_image_update_actions_cb (EAttachmentView *view, - EAttachmentHandler *handler) -{ - EAttachment *attachment; - GFileInfo *file_info; - GtkActionGroup *action_group; - const gchar *content_type; - gchar *mime_type; - GList *selected; - gboolean visible = FALSE; - - selected = e_attachment_view_get_selected_attachments (view); - - if (g_list_length (selected) != 1) - goto exit; - - attachment = E_ATTACHMENT (selected->data); - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - goto exit; - - if (e_attachment_get_loading (attachment)) - goto exit; - - if (e_attachment_get_saving (attachment)) - goto exit; - - content_type = g_file_info_get_content_type (file_info); - - mime_type = g_content_type_get_mime_type (content_type); - visible = (g_ascii_strncasecmp (mime_type, "image/", 6) == 0); - g_free (mime_type); - -exit: - action_group = e_attachment_view_get_action_group (view, "image"); - gtk_action_group_set_visible (action_group, visible); - - g_list_foreach (selected, (GFunc) g_object_unref, NULL); - g_list_free (selected); -} - -static void -attachment_handler_image_constructed (GObject *object) -{ - EAttachmentHandler *handler; - EAttachmentView *view; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - GError *error = NULL; - - handler = E_ATTACHMENT_HANDLER (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_attachment_handler_image_parent_class)->constructed (object); - - view = e_attachment_handler_get_view (handler); - - action_group = e_attachment_view_add_action_group (view, "image"); - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), object); - - ui_manager = e_attachment_view_get_ui_manager (view); - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - g_signal_connect ( - view, "update-actions", - G_CALLBACK (attachment_handler_image_update_actions_cb), - object); -} - -static void -e_attachment_handler_image_class_init (EAttachmentHandlerImageClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAttachmentHandlerImagePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->constructed = attachment_handler_image_constructed; -} - -static void -e_attachment_handler_image_init (EAttachmentHandlerImage *handler) -{ - handler->priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler); -} diff --git a/widgets/misc/e-attachment-handler-image.h b/widgets/misc/e-attachment-handler-image.h deleted file mode 100644 index bade5cec5e..0000000000 --- a/widgets/misc/e-attachment-handler-image.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * e-attachment-handler-image.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_HANDLER_IMAGE_H -#define E_ATTACHMENT_HANDLER_IMAGE_H - -#include <misc/e-attachment-handler.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_HANDLER_IMAGE \ - (e_attachment_handler_image_get_type ()) -#define E_ATTACHMENT_HANDLER_IMAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImage)) -#define E_ATTACHMENT_HANDLER_IMAGE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImageClass)) -#define E_IS_ATTACHMENT_HANDLER_IMAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE)) -#define E_IS_ATTACHMENT_HANDLER_IMAGE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_HANDLER_IMAGE)) -#define E_ATTACHMENT_HANDLER_IMAGE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImageClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentHandlerImage EAttachmentHandlerImage; -typedef struct _EAttachmentHandlerImageClass EAttachmentHandlerImageClass; -typedef struct _EAttachmentHandlerImagePrivate EAttachmentHandlerImagePrivate; - -struct _EAttachmentHandlerImage { - EAttachmentHandler parent; - EAttachmentHandlerImagePrivate *priv; -}; - -struct _EAttachmentHandlerImageClass { - EAttachmentHandlerClass parent_class; -}; - -GType e_attachment_handler_image_get_type (void); - -G_END_DECLS - -#endif /* E_ATTACHMENT_HANDLER_IMAGE_H */ diff --git a/widgets/misc/e-attachment-handler-sendto.c b/widgets/misc/e-attachment-handler-sendto.c deleted file mode 100644 index f0fe698713..0000000000 --- a/widgets/misc/e-attachment-handler-sendto.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * e-attachment-handler-sendto.c - * - * Copyright (C) 2009 Matthew Barnes - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-handler-sendto.h" - -#include <errno.h> - -#include <glib/gi18n-lib.h> - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <placeholder name='custom-actions'>" -" <menuitem action='sendto'/>" -" </placeholder>" -" </popup>" -"</ui>"; - -G_DEFINE_TYPE ( - EAttachmentHandlerSendto, - e_attachment_handler_sendto, - E_TYPE_ATTACHMENT_HANDLER) - -static void -sendto_save_finished_cb (EAttachment *attachment, - GAsyncResult *result, - EAttachmentHandler *handler) -{ - EAttachmentView *view; - EAttachmentStore *store; - GtkWidget *dialog; - gchar **uris; - gpointer parent; - gchar *arguments; - gchar *command_line; - guint n_uris = 1; - GError *error = NULL; - - view = e_attachment_handler_get_view (handler); - store = e_attachment_view_get_store (view); - - uris = e_attachment_store_get_uris_finish (store, result, &error); - - if (uris != NULL) - n_uris = g_strv_length (uris); - - if (error != NULL) - goto error; - - arguments = g_strjoinv (" ", uris); - command_line = g_strdup_printf ("nautilus-sendto %s", arguments); - - g_message ("Command: %s", command_line); - g_spawn_command_line_async (command_line, &error); - - g_free (command_line); - g_free (arguments); - - if (error != NULL) - goto error; - - goto exit; - -error: - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "<big><b>%s</b></big>", - ngettext ("Could not send attachment", - "Could not send attachments", n_uris)); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); - -exit: - g_object_unref (handler); - g_strfreev (uris); -} - -static void -action_sendto_cb (GtkAction *action, - EAttachmentHandler *handler) -{ - EAttachmentView *view; - EAttachmentStore *store; - GList *selected; - - view = e_attachment_handler_get_view (handler); - store = e_attachment_view_get_store (view); - - selected = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (selected != NULL); - - e_attachment_store_get_uris_async ( - store, selected, (GAsyncReadyCallback) - sendto_save_finished_cb, g_object_ref (handler)); - - g_list_foreach (selected, (GFunc) g_object_unref, NULL); - g_list_free (selected); -} - -static GtkActionEntry standard_entries[] = { - - { "sendto", - "document-send", - N_("_Send To..."), - NULL, - N_("Send the selected attachments somewhere"), - G_CALLBACK (action_sendto_cb) } -}; - -static void -attachment_handler_sendto_update_actions_cb (EAttachmentView *view, - EAttachmentHandler *handler) -{ - GtkActionGroup *action_group; - GList *selected, *iter; - gboolean visible = FALSE; - gchar *program; - - program = g_find_program_in_path ("nautilus-sendto"); - selected = e_attachment_view_get_selected_attachments (view); - - if (program == NULL || selected == NULL) - goto exit; - - /* Make sure no file transfers are in progress. */ - for (iter = selected; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - - if (e_attachment_get_loading (attachment)) - goto exit; - - if (e_attachment_get_saving (attachment)) - goto exit; - } - - visible = TRUE; - -exit: - action_group = e_attachment_view_get_action_group (view, "sendto"); - gtk_action_group_set_visible (action_group, visible); - - g_list_foreach (selected, (GFunc) g_object_unref, NULL); - g_list_free (selected); - - g_free (program); -} - -static void -attachment_handler_sendto_constructed (GObject *object) -{ - EAttachmentHandler *handler; - EAttachmentView *view; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - GError *error = NULL; - - handler = E_ATTACHMENT_HANDLER (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_attachment_handler_sendto_parent_class)->constructed (object); - - view = e_attachment_handler_get_view (handler); - ui_manager = e_attachment_view_get_ui_manager (view); - - action_group = gtk_action_group_new ("sendto"); - gtk_action_group_set_translation_domain ( - action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), object); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - g_signal_connect ( - view, "update-actions", - G_CALLBACK (attachment_handler_sendto_update_actions_cb), - object); -} - -static void -e_attachment_handler_sendto_class_init (EAttachmentHandlerSendtoClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - object_class->constructed = attachment_handler_sendto_constructed; -} - -static void -e_attachment_handler_sendto_init (EAttachmentHandlerSendto *handler) -{ -} diff --git a/widgets/misc/e-attachment-handler-sendto.h b/widgets/misc/e-attachment-handler-sendto.h deleted file mode 100644 index 9ae272ad7a..0000000000 --- a/widgets/misc/e-attachment-handler-sendto.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * e-attachment-handler-sendto.h - * - * Copyright (C) 2009 Matthew Barnes - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_ATTACHMENT_HANDLER_SENDTO_H -#define E_ATTACHMENT_HANDLER_SENDTO_H - -#include <misc/e-attachment-handler.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_HANDLER_SENDTO \ - (e_attachment_handler_sendto_get_type ()) -#define E_ATTACHMENT_HANDLER_SENDTO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendto)) -#define E_ATTACHMENT_HANDLER_SENDTO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendtoClass)) -#define E_IS_ATTACHMENT_HANDLER_SENDTO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO)) -#define E_IS_ATTACHMENT_HANDLER_SENDTO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_HANDLER_SENDTO)) -#define E_ATTACHMENT_HANDLER_SENDTO_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendtoClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentHandlerSendto EAttachmentHandlerSendto; -typedef struct _EAttachmentHandlerSendtoClass EAttachmentHandlerSendtoClass; - -struct _EAttachmentHandlerSendto { - EAttachmentHandler parent; -}; - -struct _EAttachmentHandlerSendtoClass { - EAttachmentHandlerClass parent_class; -}; - -GType e_attachment_handler_sendto_get_type (void); - -G_END_DECLS - -#endif /* E_ATTACHMENT_HANDLER_SENDTO_H */ diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c deleted file mode 100644 index 87b9abddb5..0000000000 --- a/widgets/misc/e-attachment-handler.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * e-attachment-handler.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-handler.h" - -#define E_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerPrivate)) - -struct _EAttachmentHandlerPrivate { - gpointer placeholder; -}; - -G_DEFINE_TYPE ( - EAttachmentHandler, - e_attachment_handler, - E_TYPE_EXTENSION) - -static void -attachment_handler_constructed (GObject *object) -{ - EAttachmentView *view; - EAttachmentHandler *handler; - GdkDragAction drag_actions; - GtkTargetList *target_list; - const GtkTargetEntry *targets; - guint n_targets; - - handler = E_ATTACHMENT_HANDLER (object); - drag_actions = e_attachment_handler_get_drag_actions (handler); - targets = e_attachment_handler_get_target_table (handler, &n_targets); - - view = e_attachment_handler_get_view (handler); - - target_list = e_attachment_view_get_target_list (view); - gtk_target_list_add_table (target_list, targets, n_targets); - - e_attachment_view_add_drag_actions (view, drag_actions); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_attachment_handler_parent_class)->constructed (object); -} - -static void -e_attachment_handler_class_init (EAttachmentHandlerClass *class) -{ - GObjectClass *object_class; - EExtensionClass *extension_class; - - g_type_class_add_private (class, sizeof (EAttachmentHandlerPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->constructed = attachment_handler_constructed; - - extension_class = E_EXTENSION_CLASS (class); - extension_class->extensible_type = E_TYPE_ATTACHMENT_VIEW; -} - -static void -e_attachment_handler_init (EAttachmentHandler *handler) -{ - handler->priv = E_ATTACHMENT_HANDLER_GET_PRIVATE (handler); -} - -EAttachmentView * -e_attachment_handler_get_view (EAttachmentHandler *handler) -{ - EExtensible *extensible; - - /* This is purely a convenience function. */ - - g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), NULL); - - extensible = e_extension_get_extensible (E_EXTENSION (handler)); - - return E_ATTACHMENT_VIEW (extensible); -} - -GdkDragAction -e_attachment_handler_get_drag_actions (EAttachmentHandler *handler) -{ - EAttachmentHandlerClass *class; - - g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), 0); - - class = E_ATTACHMENT_HANDLER_GET_CLASS (handler); - - if (class->get_drag_actions != NULL) - return class->get_drag_actions (handler); - - return 0; -} - -const GtkTargetEntry * -e_attachment_handler_get_target_table (EAttachmentHandler *handler, - guint *n_targets) -{ - EAttachmentHandlerClass *class; - - g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), NULL); - - class = E_ATTACHMENT_HANDLER_GET_CLASS (handler); - - if (class->get_target_table != NULL) - return class->get_target_table (handler, n_targets); - - if (n_targets != NULL) - *n_targets = 0; - - return NULL; -} diff --git a/widgets/misc/e-attachment-handler.h b/widgets/misc/e-attachment-handler.h deleted file mode 100644 index 301f789b07..0000000000 --- a/widgets/misc/e-attachment-handler.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * e-attachment-handler.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_HANDLER_H -#define E_ATTACHMENT_HANDLER_H - -#include <libebackend/libebackend.h> - -#include <misc/e-attachment-view.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_HANDLER \ - (e_attachment_handler_get_type ()) -#define E_ATTACHMENT_HANDLER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandler)) -#define E_ATTACHMENT_HANDLER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerClass)) -#define E_IS_ATTACHMENT_HANDLER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_HANDLER)) -#define E_IS_ATTACHMENT_HANDLER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_HANDLER)) -#define E_ATTACHMENT_HANDLER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentHandler EAttachmentHandler; -typedef struct _EAttachmentHandlerClass EAttachmentHandlerClass; -typedef struct _EAttachmentHandlerPrivate EAttachmentHandlerPrivate; - -struct _EAttachmentHandler { - EExtension parent; - EAttachmentHandlerPrivate *priv; -}; - -struct _EAttachmentHandlerClass { - EExtensionClass parent_class; - - GdkDragAction (*get_drag_actions) (EAttachmentHandler *handler); - const GtkTargetEntry * - (*get_target_table) (EAttachmentHandler *handler, - guint *n_targets); -}; - -GType e_attachment_handler_get_type (void); -EAttachmentView * - e_attachment_handler_get_view (EAttachmentHandler *handler); -GdkDragAction e_attachment_handler_get_drag_actions - (EAttachmentHandler *handler); -const GtkTargetEntry * - e_attachment_handler_get_target_table - (EAttachmentHandler *handler, - guint *n_targets); - -G_END_DECLS - -#endif /* E_ATTACHMENT_HANDLER_H */ diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c deleted file mode 100644 index 2be8009e8a..0000000000 --- a/widgets/misc/e-attachment-icon-view.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * e-attachment-icon-view.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-icon-view.h" - -#include <glib/gi18n.h> -#include <libebackend/libebackend.h> - -#include "e-attachment.h" -#include "e-attachment-store.h" -#include "e-attachment-view.h" - -#define E_ATTACHMENT_ICON_VIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconViewPrivate)) - -struct _EAttachmentIconViewPrivate { - EAttachmentViewPrivate view_priv; -}; - -enum { - PROP_0, - PROP_DRAGGING, - PROP_EDITABLE -}; - -static gint icon_size = GTK_ICON_SIZE_DIALOG; - -/* Forward Declarations */ -static void e_attachment_icon_view_interface_init - (EAttachmentViewInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EAttachmentIconView, - e_attachment_icon_view, - GTK_TYPE_ICON_VIEW, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ATTACHMENT_VIEW, - e_attachment_icon_view_interface_init) - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -void -e_attachment_icon_view_set_default_icon_size (gint size) -{ - icon_size = size; -} - -static void -attachment_icon_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_DRAGGING: - e_attachment_view_set_dragging ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_attachment_view_set_editable ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_icon_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_DRAGGING: - g_value_set_boolean ( - value, e_attachment_view_get_dragging ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, e_attachment_view_get_editable ( - E_ATTACHMENT_VIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_icon_view_dispose (GObject *object) -{ - e_attachment_view_dispose (E_ATTACHMENT_VIEW (object)); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->dispose (object); -} - -static void -attachment_icon_view_finalize (GObject *object) -{ - e_attachment_view_finalize (E_ATTACHMENT_VIEW (object)); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->finalize (object); -} - -static void -attachment_icon_view_constructed (GObject *object) -{ - GtkCellLayout *cell_layout; - GtkCellRenderer *renderer; - - cell_layout = GTK_CELL_LAYOUT (object); - - /* This needs to happen after constructor properties are set - * so that GtkCellLayout.get_area() returns something valid. */ - - renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (renderer, "stock-size", icon_size, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "gicon", - E_ATTACHMENT_STORE_COLUMN_ICON); - - renderer = gtk_cell_renderer_text_new (); - g_object_set ( - renderer, "alignment", PANGO_ALIGN_CENTER, - "wrap-mode", PANGO_WRAP_WORD, "wrap-width", 150, - "yalign", 0.0, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "text", - E_ATTACHMENT_STORE_COLUMN_CAPTION); - - renderer = gtk_cell_renderer_progress_new (); - g_object_set (renderer, "text", _("Loading"), NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "value", - E_ATTACHMENT_STORE_COLUMN_PERCENT); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "visible", - E_ATTACHMENT_STORE_COLUMN_LOADING); - - renderer = gtk_cell_renderer_progress_new (); - g_object_set (renderer, "text", _("Saving"), NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "value", - E_ATTACHMENT_STORE_COLUMN_PERCENT); - - gtk_cell_layout_add_attribute ( - cell_layout, renderer, "visible", - E_ATTACHMENT_STORE_COLUMN_SAVING); - - e_extensible_load_extensions (E_EXTENSIBLE (object)); -} - -static gboolean -attachment_icon_view_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_button_press_event (view, event)) - return TRUE; - - /* Chain up to parent's button_press_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - button_press_event (widget, event); -} - -static gboolean -attachment_icon_view_button_release_event (GtkWidget *widget, - GdkEventButton *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_button_release_event (view, event)) - return TRUE; - - /* Chain up to parent's button_release_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - button_release_event (widget, event); -} - -static gboolean -attachment_icon_view_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_motion_notify_event (view, event)) - return TRUE; - - /* Chain up to parent's motion_notify_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - motion_notify_event (widget, event); -} - -static gboolean -attachment_icon_view_key_press_event (GtkWidget *widget, - GdkEventKey *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_key_press_event (view, event)) - return TRUE; - - /* Chain up to parent's key_press_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - key_press_event (widget, event); -} - -static void -attachment_icon_view_drag_begin (GtkWidget *widget, - GdkDragContext *context) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - /* Chain up to parent's drag_begin() method. */ - GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - drag_begin (widget, context); - - e_attachment_view_drag_begin (view, context); -} - -static void -attachment_icon_view_drag_end (GtkWidget *widget, - GdkDragContext *context) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - /* Chain up to parent's drag_end() method. */ - GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - drag_end (widget, context); - - e_attachment_view_drag_end (view, context); -} - -static void -attachment_icon_view_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_drag_data_get ( - view, context, selection, info, time); -} - -static gboolean -attachment_icon_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - return e_attachment_view_drag_motion (view, context, x, y, time); -} - -static gboolean -attachment_icon_view_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (!e_attachment_view_drag_drop (view, context, x, y, time)) - return FALSE; - - /* Chain up to parent's drag_drop() method. */ - return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)-> - drag_drop (widget, context, x, y, time); -} - -static void -attachment_icon_view_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_drag_data_received ( - view, context, x, y, selection, info, time); -} - -static gboolean -attachment_icon_view_popup_menu (GtkWidget *widget) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_show_popup_menu (view, NULL, NULL, NULL); - - return TRUE; -} - -static void -attachment_icon_view_item_activated (GtkIconView *icon_view, - GtkTreePath *path) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (icon_view); - - e_attachment_view_open_path (view, path, NULL); -} - -static EAttachmentViewPrivate * -attachment_icon_view_get_private (EAttachmentView *view) -{ - EAttachmentIconViewPrivate *priv; - - priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (view); - - return &priv->view_priv; -} - -static EAttachmentStore * -attachment_icon_view_get_store (EAttachmentView *view) -{ - GtkIconView *icon_view; - GtkTreeModel *model; - - icon_view = GTK_ICON_VIEW (view); - model = gtk_icon_view_get_model (icon_view); - - return E_ATTACHMENT_STORE (model); -} - -static GtkTreePath * -attachment_icon_view_get_path_at_pos (EAttachmentView *view, - gint x, - gint y) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - return gtk_icon_view_get_path_at_pos (icon_view, x, y); -} - -static GList * -attachment_icon_view_get_selected_paths (EAttachmentView *view) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - return gtk_icon_view_get_selected_items (icon_view); -} - -static gboolean -attachment_icon_view_path_is_selected (EAttachmentView *view, - GtkTreePath *path) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - return gtk_icon_view_path_is_selected (icon_view, path); -} - -static void -attachment_icon_view_select_path (EAttachmentView *view, - GtkTreePath *path) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_select_path (icon_view, path); -} - -static void -attachment_icon_view_unselect_path (EAttachmentView *view, - GtkTreePath *path) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_unselect_path (icon_view, path); -} - -static void -attachment_icon_view_select_all (EAttachmentView *view) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_select_all (icon_view); -} - -static void -attachment_icon_view_unselect_all (EAttachmentView *view) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_unselect_all (icon_view); -} - -static void -attachment_icon_view_drag_source_set (EAttachmentView *view, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_enable_model_drag_source ( - icon_view, start_button_mask, targets, n_targets, actions); -} - -static void -attachment_icon_view_drag_dest_set (EAttachmentView *view, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_enable_model_drag_dest ( - icon_view, targets, n_targets, actions); -} - -static void -attachment_icon_view_drag_source_unset (EAttachmentView *view) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_unset_model_drag_source (icon_view); -} - -static void -attachment_icon_view_drag_dest_unset (EAttachmentView *view) -{ - GtkIconView *icon_view; - - icon_view = GTK_ICON_VIEW (view); - - gtk_icon_view_unset_model_drag_dest (icon_view); -} - -static void -e_attachment_icon_view_class_init (EAttachmentIconViewClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkIconViewClass *icon_view_class; - - g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_icon_view_set_property; - object_class->get_property = attachment_icon_view_get_property; - object_class->dispose = attachment_icon_view_dispose; - object_class->finalize = attachment_icon_view_finalize; - object_class->constructed = attachment_icon_view_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->button_press_event = attachment_icon_view_button_press_event; - widget_class->button_release_event = attachment_icon_view_button_release_event; - widget_class->motion_notify_event = attachment_icon_view_motion_notify_event; - widget_class->key_press_event = attachment_icon_view_key_press_event; - widget_class->drag_begin = attachment_icon_view_drag_begin; - widget_class->drag_end = attachment_icon_view_drag_end; - widget_class->drag_data_get = attachment_icon_view_drag_data_get; - widget_class->drag_motion = attachment_icon_view_drag_motion; - widget_class->drag_drop = attachment_icon_view_drag_drop; - widget_class->drag_data_received = attachment_icon_view_drag_data_received; - widget_class->popup_menu = attachment_icon_view_popup_menu; - - icon_view_class = GTK_ICON_VIEW_CLASS (class); - icon_view_class->item_activated = attachment_icon_view_item_activated; - - g_object_class_override_property ( - object_class, PROP_DRAGGING, "dragging"); - - g_object_class_override_property ( - object_class, PROP_EDITABLE, "editable"); -} - -static void -e_attachment_icon_view_init (EAttachmentIconView *icon_view) -{ - icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view); - - e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view)); - - gtk_icon_view_set_selection_mode ( - GTK_ICON_VIEW (icon_view), GTK_SELECTION_MULTIPLE); -} - -static void -e_attachment_icon_view_interface_init (EAttachmentViewInterface *interface) -{ - interface->get_private = attachment_icon_view_get_private; - interface->get_store = attachment_icon_view_get_store; - - interface->get_path_at_pos = attachment_icon_view_get_path_at_pos; - interface->get_selected_paths = attachment_icon_view_get_selected_paths; - interface->path_is_selected = attachment_icon_view_path_is_selected; - interface->select_path = attachment_icon_view_select_path; - interface->unselect_path = attachment_icon_view_unselect_path; - interface->select_all = attachment_icon_view_select_all; - interface->unselect_all = attachment_icon_view_unselect_all; - - interface->drag_source_set = attachment_icon_view_drag_source_set; - interface->drag_dest_set = attachment_icon_view_drag_dest_set; - interface->drag_source_unset = attachment_icon_view_drag_source_unset; - interface->drag_dest_unset = attachment_icon_view_drag_dest_unset; -} - -GtkWidget * -e_attachment_icon_view_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT_ICON_VIEW, NULL); -} diff --git a/widgets/misc/e-attachment-icon-view.h b/widgets/misc/e-attachment-icon-view.h deleted file mode 100644 index e89992fb76..0000000000 --- a/widgets/misc/e-attachment-icon-view.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * e-attachment-icon-view.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_ICON_VIEW_H -#define E_ATTACHMENT_ICON_VIEW_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_ICON_VIEW \ - (e_attachment_icon_view_get_type ()) -#define E_ATTACHMENT_ICON_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconView)) -#define E_ATTACHMENT_ICON_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconView)) -#define E_IS_ATTACHMENT_ICON_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_ICON_VIEW)) -#define E_IS_ATTACHMENT_ICON_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_ICON_VIEW)) -#define E_ATTACHMENT_ICON_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_ICON_VIEW)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentIconView EAttachmentIconView; -typedef struct _EAttachmentIconViewClass EAttachmentIconViewClass; -typedef struct _EAttachmentIconViewPrivate EAttachmentIconViewPrivate; - -struct _EAttachmentIconView { - GtkIconView parent; - EAttachmentIconViewPrivate *priv; -}; - -struct _EAttachmentIconViewClass { - GtkIconViewClass parent_class; -}; - -GType e_attachment_icon_view_get_type (void); -GtkWidget * e_attachment_icon_view_new (void); -void e_attachment_icon_view_set_default_icon_size - (gint size); -G_END_DECLS - -#endif /* E_ATTACHMENT_ICON_VIEW_H */ diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c deleted file mode 100644 index a3c4efb187..0000000000 --- a/widgets/misc/e-attachment-paned.c +++ /dev/null @@ -1,904 +0,0 @@ -/* - * e-attachment-paned.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-paned.h" - -#include <glib/gi18n.h> - -#include "e-attachment-view.h" -#include "e-attachment-store.h" -#include "e-attachment-icon-view.h" -#include "e-attachment-tree-view.h" - -#define E_ATTACHMENT_PANED_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedPrivate)) - -#define NUM_VIEWS 2 - -/* Initial height of the lower pane. */ -static gint initial_height = 150; - -struct _EAttachmentPanedPrivate { - GtkTreeModel *model; - GtkWidget *expander; - GtkWidget *notebook; - GtkWidget *combo_box; - GtkWidget *controls_container; - GtkWidget *icon_view; - GtkWidget *tree_view; - GtkWidget *show_hide_label; - GtkWidget *status_icon; - GtkWidget *status_label; - GtkWidget *content_area; - - gint active_view; - gboolean expanded; - gboolean resize_toplevel; -}; - -enum { - PROP_0, - PROP_ACTIVE_VIEW, - PROP_DRAGGING, - PROP_EDITABLE, - PROP_EXPANDED, - PROP_RESIZE_TOPLEVEL -}; - -/* Forward Declarations */ -static void e_attachment_paned_interface_init - (EAttachmentViewInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EAttachmentPaned, - e_attachment_paned, - GTK_TYPE_VPANED, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ATTACHMENT_VIEW, - e_attachment_paned_interface_init)) - -void -e_attachment_paned_set_default_height (gint height) -{ - initial_height = height; -} - -static void -attachment_paned_notify_cb (EAttachmentPaned *paned, - GParamSpec *pspec, - GtkExpander *expander) -{ - GtkAllocation toplevel_allocation; - GtkWidget *toplevel; - GtkWidget *child; - GtkLabel *label; - const gchar *text; - - label = GTK_LABEL (paned->priv->show_hide_label); - - /* Update the expander label. */ - if (gtk_expander_get_expanded (expander)) - text = _("Hide Attachment _Bar"); - else - text = _("Show Attachment _Bar"); - - gtk_label_set_text_with_mnemonic (label, text); - - /* Resize the top-level window if required conditions are met. - * This is based on gtk_expander_resize_toplevel(), but adapted - * to the fact our GtkExpander has no direct child widget. */ - - if (!e_attachment_paned_get_resize_toplevel (paned)) - return; - - if (!gtk_widget_get_realized (GTK_WIDGET (paned))) - return; - - child = gtk_paned_get_child2 (GTK_PANED (paned)); - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (paned)); - - if (toplevel == NULL) - return; - - if (!gtk_widget_get_realized (GTK_WIDGET (toplevel))) - return; - - gtk_widget_get_allocation (toplevel, &toplevel_allocation); - - if (gtk_expander_get_expanded (expander)) { - GtkRequisition child_requisition; - - gtk_widget_get_preferred_size ( - child, &child_requisition, NULL); - - toplevel_allocation.height += child_requisition.height; - } else { - GtkAllocation child_allocation; - - gtk_widget_get_allocation (child, &child_allocation); - - toplevel_allocation.height -= child_allocation.height; - } - - gtk_window_resize ( - GTK_WINDOW (toplevel), - toplevel_allocation.width, - toplevel_allocation.height); -} - -static void -attachment_paned_update_status (EAttachmentPaned *paned) -{ - EAttachmentView *view; - EAttachmentStore *store; - GtkExpander *expander; - GtkLabel *label; - guint num_attachments; - guint64 total_size; - gchar *display_size; - gchar *markup; - - view = E_ATTACHMENT_VIEW (paned); - store = e_attachment_view_get_store (view); - expander = GTK_EXPANDER (paned->priv->expander); - label = GTK_LABEL (paned->priv->status_label); - - num_attachments = e_attachment_store_get_num_attachments (store); - total_size = e_attachment_store_get_total_size (store); - display_size = g_format_size (total_size); - - if (total_size > 0) - markup = g_strdup_printf ( - "<b>%d</b> %s (%s)", num_attachments, ngettext ( - "Attachment", "Attachments", num_attachments), - display_size); - else - markup = g_strdup_printf ( - "<b>%d</b> %s", num_attachments, ngettext ( - "Attachment", "Attachments", num_attachments)); - gtk_label_set_markup (label, markup); - g_free (markup); - - g_free (display_size); - - if (num_attachments > 0) { - gtk_widget_show (paned->priv->status_icon); - gtk_widget_show (paned->priv->status_label); - gtk_expander_set_expanded (expander, TRUE); - } else { - gtk_widget_hide (paned->priv->status_icon); - gtk_widget_hide (paned->priv->status_label); - gtk_expander_set_expanded (expander, FALSE); - } -} - -static void -attachment_paned_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVE_VIEW: - e_attachment_paned_set_active_view ( - E_ATTACHMENT_PANED (object), - g_value_get_int (value)); - return; - - case PROP_DRAGGING: - e_attachment_view_set_dragging ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_attachment_view_set_editable ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EXPANDED: - e_attachment_paned_set_expanded ( - E_ATTACHMENT_PANED (object), - g_value_get_boolean (value)); - return; - - case PROP_RESIZE_TOPLEVEL: - e_attachment_paned_set_resize_toplevel ( - E_ATTACHMENT_PANED (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_paned_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVE_VIEW: - g_value_set_int ( - value, - e_attachment_paned_get_active_view ( - E_ATTACHMENT_PANED (object))); - return; - - case PROP_DRAGGING: - g_value_set_boolean ( - value, - e_attachment_view_get_dragging ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, - e_attachment_view_get_editable ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EXPANDED: - g_value_set_boolean ( - value, - e_attachment_paned_get_expanded ( - E_ATTACHMENT_PANED (object))); - return; - - case PROP_RESIZE_TOPLEVEL: - g_value_set_boolean ( - value, - e_attachment_paned_get_resize_toplevel ( - E_ATTACHMENT_PANED (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_paned_dispose (GObject *object) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (object); - - if (priv->model != NULL) { - e_attachment_store_remove_all (E_ATTACHMENT_STORE (priv->model)); - g_object_unref (priv->model); - priv->model = NULL; - } - - if (priv->expander != NULL) { - g_object_unref (priv->expander); - priv->expander = NULL; - } - - if (priv->notebook != NULL) { - g_object_unref (priv->notebook); - priv->notebook = NULL; - } - - if (priv->combo_box != NULL) { - g_object_unref (priv->combo_box); - priv->combo_box = NULL; - } - - if (priv->icon_view != NULL) { - g_object_unref (priv->icon_view); - priv->icon_view = NULL; - } - - if (priv->tree_view != NULL) { - g_object_unref (priv->tree_view); - priv->tree_view = NULL; - } - - if (priv->show_hide_label != NULL) { - g_object_unref (priv->show_hide_label); - priv->show_hide_label = NULL; - } - - if (priv->status_icon != NULL) { - g_object_unref (priv->status_icon); - priv->status_icon = NULL; - } - - if (priv->status_label != NULL) { - g_object_unref (priv->status_label); - priv->status_label = NULL; - } - - if (priv->content_area != NULL) { - g_object_unref (priv->content_area); - priv->content_area = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_paned_parent_class)->dispose (object); -} - -static void -attachment_paned_constructed (GObject *object) -{ - EAttachmentPanedPrivate *priv; - GSettings *settings; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (object); - - settings = g_settings_new ("org.gnome.evolution.shell"); - - /* Set up property-to-property bindings. */ - - g_object_bind_property ( - object, "active-view", - priv->combo_box, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "active-view", - priv->notebook, "page", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "dragging", - priv->icon_view, "dragging", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "dragging", - priv->tree_view, "dragging", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "editable", - priv->icon_view, "editable", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "editable", - priv->tree_view, "editable", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->expander, "expanded", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->combo_box, "sensitive", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - object, "expanded", - priv->notebook, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Set up property-to-GSettings bindings. */ - g_settings_bind ( - settings, "attachment-view", - object, "active-view", - G_SETTINGS_BIND_DEFAULT); - - g_object_unref (settings); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_attachment_paned_parent_class)->constructed (object); -} - -static EAttachmentViewPrivate * -attachment_paned_get_private (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - return e_attachment_view_get_private (view); -} - -static EAttachmentStore * -attachment_paned_get_store (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - return e_attachment_view_get_store (view); -} - -static GtkTreePath * -attachment_paned_get_path_at_pos (EAttachmentView *view, - gint x, - gint y) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - return e_attachment_view_get_path_at_pos (view, x, y); -} - -static GList * -attachment_paned_get_selected_paths (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - return e_attachment_view_get_selected_paths (view); -} - -static gboolean -attachment_paned_path_is_selected (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - return e_attachment_view_path_is_selected (view, path); -} - -static void -attachment_paned_select_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - e_attachment_view_select_path (view, path); -} - -static void -attachment_paned_unselect_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - e_attachment_view_unselect_path (view, path); -} - -static void -attachment_paned_select_all (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - e_attachment_view_select_all (view); -} - -static void -attachment_paned_unselect_all (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - e_attachment_view_unselect_all (view); -} - -static void -attachment_paned_update_actions (EAttachmentView *view) -{ - EAttachmentPanedPrivate *priv; - - priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); - view = E_ATTACHMENT_VIEW (priv->icon_view); - - e_attachment_view_update_actions (view); -} - -static void -e_attachment_paned_class_init (EAttachmentPanedClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAttachmentPanedPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_paned_set_property; - object_class->get_property = attachment_paned_get_property; - object_class->dispose = attachment_paned_dispose; - object_class->constructed = attachment_paned_constructed; - - g_object_class_install_property ( - object_class, - PROP_ACTIVE_VIEW, - g_param_spec_int ( - "active-view", - "Active View", - NULL, - 0, - NUM_VIEWS, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - g_object_class_override_property ( - object_class, PROP_DRAGGING, "dragging"); - - g_object_class_override_property ( - object_class, PROP_EDITABLE, "editable"); - - g_object_class_install_property ( - object_class, - PROP_EXPANDED, - g_param_spec_boolean ( - "expanded", - "Expanded", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_RESIZE_TOPLEVEL, - g_param_spec_boolean ( - "resize-toplevel", - "Resize-Toplevel", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_attachment_paned_init (EAttachmentPaned *paned) -{ - EAttachmentView *view; - GtkSizeGroup *size_group; - GtkWidget *container; - GtkWidget *widget; - GtkAction *action; - - paned->priv = E_ATTACHMENT_PANED_GET_PRIVATE (paned); - paned->priv->model = e_attachment_store_new (); - - /* Keep the expander label and combo box the same height. */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); - - /* Construct the Attachment Views */ - - container = GTK_WIDGET (paned); - - widget = gtk_notebook_new (); - gtk_widget_set_size_request (widget, -1, initial_height); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE); - paned->priv->notebook = g_object_ref (widget); - gtk_widget_hide (widget); - - container = paned->priv->notebook; - - 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_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); - gtk_widget_show (widget); - - container = widget; - - widget = e_attachment_icon_view_new (); - gtk_widget_set_can_focus (widget, TRUE); - gtk_icon_view_set_model (GTK_ICON_VIEW (widget), paned->priv->model); - gtk_container_add (GTK_CONTAINER (container), widget); - paned->priv->icon_view = g_object_ref (widget); - gtk_widget_show (widget); - - container = paned->priv->notebook; - - 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_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); - gtk_widget_show (widget); - - container = widget; - - widget = e_attachment_tree_view_new (); - gtk_widget_set_can_focus (widget, TRUE); - gtk_tree_view_set_model (GTK_TREE_VIEW (widget), paned->priv->model); - gtk_container_add (GTK_CONTAINER (container), widget); - paned->priv->tree_view = g_object_ref (widget); - gtk_widget_show (widget); - - /* Construct the Controls */ - - container = GTK_WIDGET (paned); - - widget = gtk_vbox_new (FALSE, 6); - gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE); - paned->priv->content_area = g_object_ref (widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_hbox_new (FALSE, 6); - gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); - paned->priv->controls_container = widget; - gtk_widget_show (widget); - - container = widget; - - widget = gtk_expander_new (NULL); - gtk_expander_set_spacing (GTK_EXPANDER (widget), 0); - gtk_expander_set_label_fill (GTK_EXPANDER (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - paned->priv->expander = g_object_ref (widget); - gtk_widget_show (widget); - - /* The "Add Attachment" button proxies the "add" action from - * one of the two attachment views. Doesn't matter which. */ - widget = gtk_button_new (); - view = E_ATTACHMENT_VIEW (paned->priv->icon_view); - action = e_attachment_view_get_action (view, "add"); - gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = gtk_combo_box_text_new (); - gtk_size_group_add_widget (size_group, widget); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("Icon View")); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("List View")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - paned->priv->combo_box = g_object_ref (widget); - gtk_widget_show (widget); - - container = paned->priv->expander; - - widget = gtk_hbox_new (FALSE, 6); - gtk_size_group_add_widget (size_group, widget); - gtk_expander_set_label_widget (GTK_EXPANDER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_label_new_with_mnemonic (_("Show Attachment _Bar")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - paned->priv->show_hide_label = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_alignment_new (0.5, 0.5, 0.0, 1.0); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_hbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new_from_icon_name ( - "mail-attachment", GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - paned->priv->status_icon = g_object_ref (widget); - gtk_widget_hide (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - paned->priv->status_label = g_object_ref (widget); - gtk_widget_hide (widget); - - g_signal_connect_swapped ( - paned->priv->expander, "notify::expanded", - G_CALLBACK (attachment_paned_notify_cb), paned); - - g_signal_connect_swapped ( - paned->priv->model, "notify::num-attachments", - G_CALLBACK (attachment_paned_update_status), paned); - - g_signal_connect_swapped ( - paned->priv->model, "notify::total-size", - G_CALLBACK (attachment_paned_update_status), paned); - - g_object_unref (size_group); -} - -static void -e_attachment_paned_interface_init (EAttachmentViewInterface *interface) -{ - interface->get_private = attachment_paned_get_private; - interface->get_store = attachment_paned_get_store; - interface->get_path_at_pos = attachment_paned_get_path_at_pos; - interface->get_selected_paths = attachment_paned_get_selected_paths; - interface->path_is_selected = attachment_paned_path_is_selected; - interface->select_path = attachment_paned_select_path; - interface->unselect_path = attachment_paned_unselect_path; - interface->select_all = attachment_paned_select_all; - interface->unselect_all = attachment_paned_unselect_all; - interface->update_actions = attachment_paned_update_actions; -} - -GtkWidget * -e_attachment_paned_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT_PANED, NULL); -} - -GtkWidget * -e_attachment_paned_get_content_area (EAttachmentPaned *paned) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL); - - return paned->priv->content_area; -} - -gint -e_attachment_paned_get_active_view (EAttachmentPaned *paned) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), 0); - - return paned->priv->active_view; -} - -void -e_attachment_paned_set_active_view (EAttachmentPaned *paned, - gint active_view) -{ - EAttachmentView *source; - EAttachmentView *target; - - g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); - g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS); - - if (active_view == paned->priv->active_view) - return; - - paned->priv->active_view = active_view; - - /* Synchronize the item selection of the view we're - * switching TO with the view we're switching FROM. */ - if (active_view == 0) { - /* from tree view to icon view */ - source = E_ATTACHMENT_VIEW (paned->priv->tree_view); - target = E_ATTACHMENT_VIEW (paned->priv->icon_view); - } else { - /* from icon view to tree view */ - source = E_ATTACHMENT_VIEW (paned->priv->icon_view); - target = E_ATTACHMENT_VIEW (paned->priv->tree_view); - } - - e_attachment_view_sync_selection (source, target); - - g_object_notify (G_OBJECT (paned), "active-view"); -} - -gboolean -e_attachment_paned_get_expanded (EAttachmentPaned *paned) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), FALSE); - - return paned->priv->expanded; -} - -void -e_attachment_paned_set_expanded (EAttachmentPaned *paned, - gboolean expanded) -{ - g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); - - if (paned->priv->expanded == expanded) - return; - - paned->priv->expanded = expanded; - - g_object_notify (G_OBJECT (paned), "expanded"); -} - -gboolean -e_attachment_paned_get_resize_toplevel (EAttachmentPaned *paned) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), FALSE); - - return paned->priv->resize_toplevel; -} - -void -e_attachment_paned_set_resize_toplevel (EAttachmentPaned *paned, - gboolean resize_toplevel) -{ - g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); - - if (paned->priv->resize_toplevel == resize_toplevel) - return; - - paned->priv->resize_toplevel = resize_toplevel; - - g_object_notify (G_OBJECT (paned), "resize-toplevel"); -} - -void -e_attachment_paned_drag_data_received (EAttachmentPaned *paned, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time) -{ - g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); - - /* XXX Dirty hack for forwarding drop events. */ - g_signal_emit_by_name ( - paned->priv->icon_view, "drag-data-received", - context, x, y, selection, info, time); -} - -GtkWidget * -e_attachment_paned_get_controls_container (EAttachmentPaned *paned) -{ - return paned->priv->controls_container; -} - -GtkWidget * -e_attachment_paned_get_view_combo (EAttachmentPaned *paned) -{ - return paned->priv->combo_box; -} - diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h deleted file mode 100644 index 7daffd5508..0000000000 --- a/widgets/misc/e-attachment-paned.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * e-attachment-paned.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_PANED_H -#define E_ATTACHMENT_PANED_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_PANED \ - (e_attachment_paned_get_type ()) -#define E_ATTACHMENT_PANED(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPaned)) -#define E_ATTACHMENT_PANED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedClass)) -#define E_IS_ATTACHMENT_PANED(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_PANED)) -#define E_IS_ATTACHMENT_PANED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_PANED)) -#define E_ATTACHMENT_PANED_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentPaned EAttachmentPaned; -typedef struct _EAttachmentPanedClass EAttachmentPanedClass; -typedef struct _EAttachmentPanedPrivate EAttachmentPanedPrivate; - -struct _EAttachmentPaned { - GtkVPaned parent; - EAttachmentPanedPrivate *priv; -}; - -struct _EAttachmentPanedClass { - GtkVPanedClass parent_class; -}; - -GType e_attachment_paned_get_type (void); -GtkWidget * e_attachment_paned_new (void); -GtkWidget * e_attachment_paned_get_content_area - (EAttachmentPaned *paned); -gint e_attachment_paned_get_active_view - (EAttachmentPaned *paned); -void e_attachment_paned_set_active_view - (EAttachmentPaned *paned, - gint active_view); -gboolean e_attachment_paned_get_expanded (EAttachmentPaned *paned); -void e_attachment_paned_set_expanded (EAttachmentPaned *paned, - gboolean expanded); -gboolean e_attachment_paned_get_resize_toplevel - (EAttachmentPaned *paned); -void e_attachment_paned_set_resize_toplevel - (EAttachmentPaned *paned, - gboolean resize_toplevel); -void e_attachment_paned_drag_data_received - (EAttachmentPaned *paned, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time); -GtkWidget * e_attachment_paned_get_controls_container - (EAttachmentPaned *paned); -GtkWidget * e_attachment_paned_get_view_combo - (EAttachmentPaned *paned); -void e_attachment_paned_set_default_height - (gint height); - -G_END_DECLS - -#endif /* E_ATTACHMENT_PANED_H */ diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c deleted file mode 100644 index 95465eba81..0000000000 --- a/widgets/misc/e-attachment-store.c +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * e-attachment-store.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-store.h" - -#include <errno.h> -#include <glib/gi18n.h> - -#include "e-util/e-util.h" -#include "e-util/e-mktemp.h" - -#define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStorePrivate)) - -struct _EAttachmentStorePrivate { - GHashTable *attachment_index; - - guint ignore_row_changed : 1; -}; - -enum { - PROP_0, - PROP_NUM_ATTACHMENTS, - PROP_NUM_LOADING, - PROP_TOTAL_SIZE -}; - -G_DEFINE_TYPE ( - EAttachmentStore, - e_attachment_store, - GTK_TYPE_LIST_STORE) - -static void -attachment_store_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_NUM_ATTACHMENTS: - g_value_set_uint ( - value, - e_attachment_store_get_num_attachments ( - E_ATTACHMENT_STORE (object))); - return; - - case PROP_NUM_LOADING: - g_value_set_uint ( - value, - e_attachment_store_get_num_loading ( - E_ATTACHMENT_STORE (object))); - return; - - case PROP_TOTAL_SIZE: - g_value_set_uint64 ( - value, - e_attachment_store_get_total_size ( - E_ATTACHMENT_STORE (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_store_dispose (GObject *object) -{ - e_attachment_store_remove_all (E_ATTACHMENT_STORE (object)); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_store_parent_class)->dispose (object); -} - -static void -attachment_store_finalize (GObject *object) -{ - EAttachmentStorePrivate *priv; - - priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); - - g_hash_table_destroy (priv->attachment_index); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_attachment_store_parent_class)->finalize (object); -} - -static void -e_attachment_store_class_init (EAttachmentStoreClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAttachmentStorePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->get_property = attachment_store_get_property; - object_class->dispose = attachment_store_dispose; - object_class->finalize = attachment_store_finalize; - - g_object_class_install_property ( - object_class, - PROP_NUM_ATTACHMENTS, - g_param_spec_uint ( - "num-attachments", - "Num Attachments", - NULL, - 0, - G_MAXUINT, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_NUM_LOADING, - g_param_spec_uint ( - "num-loading", - "Num Loading", - NULL, - 0, - G_MAXUINT, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_TOTAL_SIZE, - g_param_spec_uint64 ( - "total-size", - "Total Size", - NULL, - 0, - G_MAXUINT64, - 0, - G_PARAM_READABLE)); -} - -static void -e_attachment_store_init (EAttachmentStore *store) -{ - GType types[E_ATTACHMENT_STORE_NUM_COLUMNS]; - GHashTable *attachment_index; - gint column = 0; - - attachment_index = g_hash_table_new_full ( - g_direct_hash, g_direct_equal, - (GDestroyNotify) g_object_unref, - (GDestroyNotify) gtk_tree_row_reference_free); - - store->priv = E_ATTACHMENT_STORE_GET_PRIVATE (store); - store->priv->attachment_index = attachment_index; - - types[column++] = E_TYPE_ATTACHMENT; /* COLUMN_ATTACHMENT */ - types[column++] = G_TYPE_STRING; /* COLUMN_CAPTION */ - types[column++] = G_TYPE_STRING; /* COLUMN_CONTENT_TYPE */ - types[column++] = G_TYPE_STRING; /* COLUMN_DESCRIPTION */ - types[column++] = G_TYPE_ICON; /* COLUMN_ICON */ - types[column++] = G_TYPE_BOOLEAN; /* COLUMN_LOADING */ - types[column++] = G_TYPE_INT; /* COLUMN_PERCENT */ - types[column++] = G_TYPE_BOOLEAN; /* COLUMN_SAVING */ - types[column++] = G_TYPE_UINT64; /* COLUMN_SIZE */ - - g_assert (column == E_ATTACHMENT_STORE_NUM_COLUMNS); - - gtk_list_store_set_column_types ( - GTK_LIST_STORE (store), G_N_ELEMENTS (types), types); -} - -GtkTreeModel * -e_attachment_store_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT_STORE, NULL); -} - -void -e_attachment_store_add_attachment (EAttachmentStore *store, - EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - gtk_list_store_append (GTK_LIST_STORE (store), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (store), &iter, - E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, attachment, -1); - - model = GTK_TREE_MODEL (store); - path = gtk_tree_model_get_path (model, &iter); - reference = gtk_tree_row_reference_new (model, path); - gtk_tree_path_free (path); - - g_hash_table_insert ( - store->priv->attachment_index, - g_object_ref (attachment), reference); - - /* This lets the attachment tell us when to update. */ - e_attachment_set_reference (attachment, reference); - - g_object_freeze_notify (G_OBJECT (store)); - g_object_notify (G_OBJECT (store), "num-attachments"); - g_object_notify (G_OBJECT (store), "total-size"); - g_object_thaw_notify (G_OBJECT (store)); -} - -gboolean -e_attachment_store_remove_attachment (EAttachmentStore *store, - EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GHashTable *hash_table; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), FALSE); - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - hash_table = store->priv->attachment_index; - reference = g_hash_table_lookup (hash_table, attachment); - - if (reference == NULL) - return FALSE; - - if (!gtk_tree_row_reference_valid (reference)) { - g_hash_table_remove (hash_table, attachment); - return FALSE; - } - - e_attachment_cancel (attachment); - e_attachment_set_reference (attachment, NULL); - - 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); - - gtk_list_store_remove (GTK_LIST_STORE (store), &iter); - g_hash_table_remove (hash_table, attachment); - - g_object_freeze_notify (G_OBJECT (store)); - g_object_notify (G_OBJECT (store), "num-attachments"); - g_object_notify (G_OBJECT (store), "total-size"); - g_object_thaw_notify (G_OBJECT (store)); - - return TRUE; -} - -void -e_attachment_store_remove_all (EAttachmentStore *store) -{ - GList *list, *iter; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - - if (!g_hash_table_size (store->priv->attachment_index)) - return; - - g_object_freeze_notify (G_OBJECT (store)); - - list = e_attachment_store_get_attachments (store); - for (iter = list; iter; iter = iter->next) { - EAttachment *attachment = iter->data; - - e_attachment_cancel (attachment); - g_hash_table_remove (store->priv->attachment_index, iter->data); - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - gtk_list_store_clear (GTK_LIST_STORE (store)); - - g_object_notify (G_OBJECT (store), "num-attachments"); - g_object_notify (G_OBJECT (store), "total-size"); - g_object_thaw_notify (G_OBJECT (store)); -} - -void -e_attachment_store_add_to_multipart (EAttachmentStore *store, - CamelMultipart *multipart, - const gchar *default_charset) -{ - GList *list, *iter; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (CAMEL_MULTIPART (multipart)); - - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - - /* Skip the attachment if it's still loading. */ - if (!e_attachment_get_loading (attachment)) - e_attachment_add_to_multipart ( - attachment, multipart, default_charset); - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -GList * -e_attachment_store_get_attachments (EAttachmentStore *store) -{ - GList *list = NULL; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); - - model = GTK_TREE_MODEL (store); - valid = gtk_tree_model_get_iter_first (model, &iter); - - while (valid) { - EAttachment *attachment; - gint column_id; - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - - list = g_list_prepend (list, attachment); - - valid = gtk_tree_model_iter_next (model, &iter); - } - - return g_list_reverse (list); -} - -guint -e_attachment_store_get_num_attachments (EAttachmentStore *store) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - - return g_hash_table_size (store->priv->attachment_index); -} - -guint -e_attachment_store_get_num_loading (EAttachmentStore *store) -{ - GList *list, *iter; - guint num_loading = 0; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - - if (e_attachment_get_loading (attachment)) - num_loading++; - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - return num_loading; -} - -goffset -e_attachment_store_get_total_size (EAttachmentStore *store) -{ - GList *list, *iter; - goffset total_size = 0; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - GFileInfo *file_info; - - file_info = e_attachment_get_file_info (attachment); - if (file_info != NULL) - total_size += g_file_info_get_size (file_info); - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - return total_size; -} - -void -e_attachment_store_run_load_dialog (EAttachmentStore *store, - GtkWindow *parent) -{ - GtkFileChooser *file_chooser; - GtkWidget *dialog; - GtkWidget *option; - GSList *files, *iter; - const gchar *disposition; - gboolean active; - gint response; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (GTK_IS_WINDOW (parent)); - - dialog = gtk_file_chooser_dialog_new ( - _("Add Attachment"), parent, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("A_ttach"), GTK_RESPONSE_OK, NULL); - - file_chooser = GTK_FILE_CHOOSER (dialog); - gtk_file_chooser_set_local_only (file_chooser, FALSE); - gtk_file_chooser_set_select_multiple (file_chooser, TRUE); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); - - option = gtk_check_button_new_with_mnemonic ( - _("_Suggest automatic display of attachment")); - gtk_file_chooser_set_extra_widget (file_chooser, option); - gtk_widget_show (option); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - if (response != GTK_RESPONSE_OK) - goto exit; - - files = gtk_file_chooser_get_files (file_chooser); - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option)); - disposition = active ? "inline" : "attachment"; - - for (iter = files; iter != NULL; iter = g_slist_next (iter)) { - EAttachment *attachment; - GFile *file = iter->data; - - attachment = e_attachment_new (); - e_attachment_set_file (attachment, file); - e_attachment_set_disposition (attachment, disposition); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - } - - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); - -exit: - gtk_widget_destroy (dialog); -} - -GFile * -e_attachment_store_run_save_dialog (EAttachmentStore *store, - GList *attachment_list, - GtkWindow *parent) -{ - GtkFileChooser *file_chooser; - GtkFileChooserAction action; - GtkWidget *dialog; - GFile *destination; - const gchar *title; - gint response; - guint length; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); - - length = g_list_length (attachment_list); - - if (length == 0) - return NULL; - - title = ngettext ("Save Attachment", "Save Attachments", length); - - if (length == 1) - action = GTK_FILE_CHOOSER_ACTION_SAVE; - else - action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; - - dialog = gtk_file_chooser_dialog_new ( - title, parent, action, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); - - file_chooser = GTK_FILE_CHOOSER (dialog); - gtk_file_chooser_set_local_only (file_chooser, FALSE); - gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); - - if (action == GTK_FILE_CHOOSER_ACTION_SAVE) { - EAttachment *attachment; - GFileInfo *file_info; - const gchar *name = NULL; - - attachment = attachment_list->data; - file_info = e_attachment_get_file_info (attachment); - if (file_info != NULL) - name = g_file_info_get_display_name (file_info); - if (name == NULL) - /* Translators: Default attachment filename. */ - name = _("attachment.dat"); - gtk_file_chooser_set_current_name (file_chooser, name); - } - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - if (response == GTK_RESPONSE_OK) - destination = gtk_file_chooser_get_file (file_chooser); - else - destination = NULL; - - gtk_widget_destroy (dialog); - - return destination; -} - -/******************** e_attachment_store_get_uris_async() ********************/ - -typedef struct _UriContext UriContext; - -struct _UriContext { - GSimpleAsyncResult *simple; - GList *attachment_list; - GError *error; - gchar **uris; - gint index; -}; - -static UriContext * -attachment_store_uri_context_new (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data) -{ - UriContext *uri_context; - GSimpleAsyncResult *simple; - guint length; - gchar **uris; - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_attachment_store_get_uris_async); - - /* Add one for NULL terminator. */ - length = g_list_length (attachment_list) + 1; - uris = g_malloc0 (sizeof (gchar *) * length); - - uri_context = g_slice_new0 (UriContext); - uri_context->simple = simple; - uri_context->attachment_list = g_list_copy (attachment_list); - uri_context->uris = uris; - - g_list_foreach ( - uri_context->attachment_list, - (GFunc) g_object_ref, NULL); - - return uri_context; -} - -static void -attachment_store_uri_context_free (UriContext *uri_context) -{ - g_object_unref (uri_context->simple); - - /* The attachment list should be empty now. */ - g_warn_if_fail (uri_context->attachment_list == NULL); - - /* So should the error. */ - g_warn_if_fail (uri_context->error == NULL); - - g_strfreev (uri_context->uris); - - g_slice_free (UriContext, uri_context); -} - -static void -attachment_store_get_uris_save_cb (EAttachment *attachment, - GAsyncResult *result, - UriContext *uri_context) -{ - GSimpleAsyncResult *simple; - GFile *file; - gchar **uris; - gchar *uri; - GError *error = NULL; - - file = e_attachment_save_finish (attachment, result, &error); - - /* Remove the attachment from the list. */ - uri_context->attachment_list = g_list_remove ( - uri_context->attachment_list, attachment); - g_object_unref (attachment); - - if (file != NULL) { - uri = g_file_get_uri (file); - uri_context->uris[uri_context->index++] = uri; - g_object_unref (file); - - } else if (error != NULL) { - /* If this is the first error, cancel the other jobs. */ - if (uri_context->error == NULL) { - g_propagate_error (&uri_context->error, error); - g_list_foreach ( - uri_context->attachment_list, - (GFunc) e_attachment_cancel, NULL); - error = NULL; - - /* Otherwise, we can only report back one error. So if - * this is something other than cancellation, dump it to - * the terminal. */ - } else if (!g_error_matches ( - error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s", error->message); - } - - if (error != NULL) - g_error_free (error); - - /* If there's still jobs running, let them finish. */ - if (uri_context->attachment_list != NULL) - return; - - /* Steal the URI list. */ - uris = uri_context->uris; - uri_context->uris = NULL; - - /* And the error. */ - error = uri_context->error; - uri_context->error = NULL; - - simple = uri_context->simple; - - if (error == NULL) - g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); - else - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - - attachment_store_uri_context_free (uri_context); -} - -void -e_attachment_store_get_uris_async (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GFile *temp_directory; - UriContext *uri_context; - GList *iter, *trash = NULL; - gchar *template; - gchar *path; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - - uri_context = attachment_store_uri_context_new ( - store, attachment_list, callback, user_data); - - /* Grab the copied attachment list. */ - attachment_list = uri_context->attachment_list; - - /* First scan the list for attachments with a GFile. */ - for (iter = attachment_list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - GFile *file; - gchar *uri; - - file = e_attachment_get_file (attachment); - if (file == NULL) - continue; - - uri = g_file_get_uri (file); - uri_context->uris[uri_context->index++] = uri; - - /* Mark the list node for deletion. */ - trash = g_list_prepend (trash, iter); - g_object_unref (attachment); - } - - /* Expunge the list. */ - for (iter = trash; iter != NULL; iter = iter->next) { - GList *link = iter->data; - attachment_list = g_list_delete_link (attachment_list, link); - } - g_list_free (trash); - - uri_context->attachment_list = attachment_list; - - /* If we got them all then we're done. */ - if (attachment_list == NULL) { - GSimpleAsyncResult *simple; - gchar **uris; - - /* Steal the URI list. */ - uris = uri_context->uris; - uri_context->uris = NULL; - - simple = uri_context->simple; - g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); - g_simple_async_result_complete (simple); - - attachment_store_uri_context_free (uri_context); - return; - } - - /* Any remaining attachments in the list should have MIME parts - * only, so we need to save them all to a temporary directory. - * We use a directory so the files can retain their basenames. - * XXX This could trigger a blocking temp directory cleanup. */ - template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mkdtemp (template); - g_free (template); - - /* XXX Let's hope errno got set properly. */ - if (path == NULL) { - GSimpleAsyncResult *simple; - - simple = uri_context->simple; - g_simple_async_result_set_error ( - simple, G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - g_simple_async_result_complete (simple); - - attachment_store_uri_context_free (uri_context); - return; - } - - temp_directory = g_file_new_for_path (path); - - for (iter = attachment_list; iter != NULL; iter = iter->next) - e_attachment_save_async ( - E_ATTACHMENT (iter->data), - temp_directory, (GAsyncReadyCallback) - attachment_store_get_uris_save_cb, - uri_context); - - g_object_unref (temp_directory); - g_free (path); -} - -gchar ** -e_attachment_store_get_uris_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - gchar **uris; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - uris = g_simple_async_result_get_op_res_gpointer (simple); - g_simple_async_result_propagate_error (simple, error); - - return uris; -} - -/********************** e_attachment_store_load_async() **********************/ - -typedef struct _LoadContext LoadContext; - -struct _LoadContext { - GSimpleAsyncResult *simple; - GList *attachment_list; - GError *error; -}; - -static LoadContext * -attachment_store_load_context_new (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data) -{ - LoadContext *load_context; - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_attachment_store_load_async); - - load_context = g_slice_new0 (LoadContext); - load_context->simple = simple; - load_context->attachment_list = g_list_copy (attachment_list); - - g_list_foreach ( - load_context->attachment_list, - (GFunc) g_object_ref, NULL); - - return load_context; -} - -static void -attachment_store_load_context_free (LoadContext *load_context) -{ - g_object_unref (load_context->simple); - - /* The attachment list should be empty now. */ - g_warn_if_fail (load_context->attachment_list == NULL); - - /* So should the error. */ - g_warn_if_fail (load_context->error == NULL); - - g_slice_free (LoadContext, load_context); -} - -static void -attachment_store_load_ready_cb (EAttachment *attachment, - GAsyncResult *result, - LoadContext *load_context) -{ - GSimpleAsyncResult *simple; - GError *error = NULL; - - e_attachment_load_finish (attachment, result, &error); - - /* Remove the attachment from the list. */ - load_context->attachment_list = g_list_remove ( - load_context->attachment_list, attachment); - g_object_unref (attachment); - - if (error != NULL) { - /* If this is the first error, cancel the other jobs. */ - if (load_context->error == NULL) { - g_propagate_error (&load_context->error, error); - g_list_foreach ( - load_context->attachment_list, - (GFunc) e_attachment_cancel, NULL); - error = NULL; - - /* Otherwise, we can only report back one error. So if - * this is something other than cancellation, dump it to - * the terminal. */ - } else if (!g_error_matches ( - error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s", error->message); - } - - if (error != NULL) - g_error_free (error); - - /* If there's still jobs running, let them finish. */ - if (load_context->attachment_list != NULL) - return; - - /* Steal the error. */ - error = load_context->error; - load_context->error = NULL; - - simple = load_context->simple; - - if (error == NULL) - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - else - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - - attachment_store_load_context_free (load_context); -} - -void -e_attachment_store_load_async (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data) -{ - LoadContext *load_context; - GList *iter; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - - load_context = attachment_store_load_context_new ( - store, attachment_list, callback, user_data); - - if (attachment_list == NULL) { - GSimpleAsyncResult *simple; - - simple = load_context->simple; - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - - attachment_store_load_context_free (load_context); - return; - } - - for (iter = attachment_list; iter != NULL; iter = iter->next) { - EAttachment *attachment = E_ATTACHMENT (iter->data); - - e_attachment_store_add_attachment (store, attachment); - - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - attachment_store_load_ready_cb, - load_context); - } -} - -gboolean -e_attachment_store_load_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - gboolean success; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), FALSE); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - success = g_simple_async_result_get_op_res_gboolean (simple); - g_simple_async_result_propagate_error (simple, error); - - return success; -} - -/********************** e_attachment_store_save_async() **********************/ - -typedef struct _SaveContext SaveContext; - -struct _SaveContext { - GSimpleAsyncResult *simple; - GFile *destination; - gchar *filename_prefix; - GFile *fresh_directory; - GFile *trash_directory; - GList *attachment_list; - GError *error; - gchar **uris; - gint index; -}; - -static SaveContext * -attachment_store_save_context_new (EAttachmentStore *store, - GFile *destination, - const gchar *filename_prefix, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SaveContext *save_context; - GSimpleAsyncResult *simple; - GList *attachment_list; - guint length; - gchar **uris; - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_attachment_store_save_async); - - attachment_list = e_attachment_store_get_attachments (store); - - /* Add one for NULL terminator. */ - length = g_list_length (attachment_list) + 1; - uris = g_malloc0 (sizeof (gchar *) * length); - - save_context = g_slice_new0 (SaveContext); - save_context->simple = simple; - save_context->destination = g_object_ref (destination); - save_context->filename_prefix = g_strdup (filename_prefix); - save_context->attachment_list = attachment_list; - save_context->uris = uris; - - return save_context; -} - -static void -attachment_store_save_context_free (SaveContext *save_context) -{ - g_object_unref (save_context->simple); - - /* The attachment list should be empty now. */ - g_warn_if_fail (save_context->attachment_list == NULL); - - /* So should the error. */ - g_warn_if_fail (save_context->error == NULL); - - if (save_context->destination) { - g_object_unref (save_context->destination); - save_context->destination = NULL; - } - - g_free (save_context->filename_prefix); - save_context->filename_prefix = NULL; - - if (save_context->fresh_directory) { - g_object_unref (save_context->fresh_directory); - save_context->fresh_directory = NULL; - } - - if (save_context->trash_directory) { - g_object_unref (save_context->trash_directory); - save_context->trash_directory = NULL; - } - - g_strfreev (save_context->uris); - - g_slice_free (SaveContext, save_context); -} - -static void -attachment_store_move_file (SaveContext *save_context, - GFile *source, - GFile *destination, - GError **error) -{ - gchar *tmpl; - gchar *path; - - g_return_if_fail (save_context != NULL); - g_return_if_fail (source != NULL); - g_return_if_fail (destination != NULL); - g_return_if_fail (error != NULL); - - /* Attachments are all saved to a temporary directory. - * Now we need to move the existing destination directory - * out of the way (if it exists). Instead of testing for - * existence we'll just attempt the move and ignore any - * G_IO_ERROR_NOT_FOUND errors. */ - - /* First, however, we need another temporary directory to - * move the existing destination directory to. Note we're - * not actually creating the directory yet, just picking a - * name for it. The usual raciness with this approach - * applies here (read up on mktemp(3)), but worst case is - * we get a spurious G_IO_ERROR_WOULD_MERGE error and the - * user has to try saving attachments again. */ - tmpl = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mktemp (tmpl); - g_free (tmpl); - - save_context->trash_directory = g_file_new_for_path (path); - g_free (path); - - /* XXX No asynchronous move operation in GIO? */ - g_file_move ( - destination, - save_context->trash_directory, - G_FILE_COPY_NONE, NULL, NULL, NULL, error); - - if (*error != NULL && !g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - return; - - g_clear_error (error); - - /* Now we can move the file from the temporary directory - * to the user-specified destination. */ - g_file_move ( - source, - destination, - G_FILE_COPY_NONE, NULL, NULL, NULL, error); -} - -static void -attachment_store_save_cb (EAttachment *attachment, - GAsyncResult *result, - SaveContext *save_context) -{ - GSimpleAsyncResult *simple; - GFile *file; - gchar **uris; - GError *error = NULL; - - file = e_attachment_save_finish (attachment, result, &error); - - /* Remove the attachment from the list. */ - save_context->attachment_list = g_list_remove ( - save_context->attachment_list, attachment); - g_object_unref (attachment); - - if (file != NULL) { - /* Assemble the file's final URI from its basename. */ - gchar *basename; - gchar *uri; - GFile *source = NULL, *destination = NULL; - - basename = g_file_get_basename (file); - g_object_unref (file); - - source = g_file_get_child (save_context->fresh_directory, basename); - - if (save_context->filename_prefix && *save_context->filename_prefix) { - gchar *tmp = basename; - - basename = g_strconcat (save_context->filename_prefix, basename, NULL); - g_free (tmp); - } - - file = save_context->destination; - destination = g_file_get_child (file, basename); - uri = g_file_get_uri (destination); - - /* move them file-by-file */ - attachment_store_move_file (save_context, source, destination, &error); - - if (!error) - save_context->uris[save_context->index++] = uri; - - g_object_unref (source); - g_object_unref (destination); - } - - if (error != NULL) { - /* If this is the first error, cancel the other jobs. */ - if (save_context->error == NULL) { - g_propagate_error (&save_context->error, error); - g_list_foreach ( - save_context->attachment_list, - (GFunc) e_attachment_cancel, NULL); - error = NULL; - - /* Otherwise, we can only report back one error. So if - * this is something other than cancellation, dump it to - * the terminal. */ - } else if (!g_error_matches ( - error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s", error->message); - } - - g_clear_error (&error); - - /* If there's still jobs running, let them finish. */ - if (save_context->attachment_list != NULL) - return; - - /* If an error occurred while saving, we're done. */ - if (save_context->error != NULL) { - - /* Steal the error. */ - error = save_context->error; - save_context->error = NULL; - - simple = save_context->simple; - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - - attachment_store_save_context_free (save_context); - return; - } - - if (error != NULL) { - simple = save_context->simple; - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - - attachment_store_save_context_free (save_context); - return; - } - - /* clean-up left directory */ - g_file_delete (save_context->fresh_directory, NULL, NULL); - - /* And the URI list. */ - uris = save_context->uris; - save_context->uris = NULL; - - simple = save_context->simple; - g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); - g_simple_async_result_complete (simple); - - attachment_store_save_context_free (save_context); -} -/* - * @filename_prefix: prefix to use for a file name; can be %NULL for none - **/ -void -e_attachment_store_save_async (EAttachmentStore *store, - GFile *destination, - const gchar *filename_prefix, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SaveContext *save_context; - GList *attachment_list, *iter; - GFile *temp_directory; - gchar *template; - gchar *path; - - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (G_IS_FILE (destination)); - - save_context = attachment_store_save_context_new ( - store, destination, filename_prefix, callback, user_data); - - attachment_list = save_context->attachment_list; - - /* Deal with an empty attachment store. The caller will get - * an empty NULL-terminated list as opposed to NULL, to help - * distinguish it from an error. */ - if (attachment_list == NULL) { - GSimpleAsyncResult *simple; - gchar **uris; - - /* Steal the URI list. */ - uris = save_context->uris; - save_context->uris = NULL; - - simple = save_context->simple; - g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); - g_simple_async_result_complete (simple); - - attachment_store_save_context_free (save_context); - return; - } - - /* Save all attachments to a temporary directory, which we'll - * then move to its proper location. We use a directory so - * files can retain their basenames. - * XXX This could trigger a blocking temp directory cleanup. */ - template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mkdtemp (template); - g_free (template); - - /* XXX Let's hope errno got set properly. */ - if (path == NULL) { - GSimpleAsyncResult *simple; - - simple = save_context->simple; - g_simple_async_result_set_error ( - simple, G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - g_simple_async_result_complete (simple); - - attachment_store_save_context_free (save_context); - return; - } - - temp_directory = g_file_new_for_path (path); - save_context->fresh_directory = temp_directory; - g_free (path); - - for (iter = attachment_list; iter != NULL; iter = iter->next) - e_attachment_save_async ( - E_ATTACHMENT (iter->data), - temp_directory, (GAsyncReadyCallback) - attachment_store_save_cb, save_context); -} - -gchar ** -e_attachment_store_save_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - gchar **uris; - - g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - uris = g_simple_async_result_get_op_res_gpointer (simple); - g_simple_async_result_propagate_error (simple, error); - - return uris; -} diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h deleted file mode 100644 index a963f0558f..0000000000 --- a/widgets/misc/e-attachment-store.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * e-attachment-store.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_STORE_H -#define E_ATTACHMENT_STORE_H - -#include <gtk/gtk.h> -#include <misc/e-attachment.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_STORE \ - (e_attachment_store_get_type ()) -#define E_ATTACHMENT_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStore)) -#define E_ATTACHMENT_STORE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_STORE, EAttachmentStoreClass)) -#define E_IS_ATTACHMENT_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_STORE)) -#define E_IS_ATTACHMENT_STORE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_STORE)) -#define E_ATTACHMENT_STORE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStoreClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentStore EAttachmentStore; -typedef struct _EAttachmentStoreClass EAttachmentStoreClass; -typedef struct _EAttachmentStorePrivate EAttachmentStorePrivate; - -struct _EAttachmentStore { - GtkListStore parent; - EAttachmentStorePrivate *priv; -}; - -struct _EAttachmentStoreClass { - GtkListStoreClass parent_class; -}; - -enum { - E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, /* E_TYPE_ATTACHMENT */ - E_ATTACHMENT_STORE_COLUMN_CAPTION, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_DESCRIPTION, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_ICON, /* G_TYPE_ICON */ - E_ATTACHMENT_STORE_COLUMN_LOADING, /* G_TYPE_BOOLEAN */ - E_ATTACHMENT_STORE_COLUMN_PERCENT, /* G_TYPE_INT */ - E_ATTACHMENT_STORE_COLUMN_SAVING, /* G_TYPE_BOOLEAN */ - E_ATTACHMENT_STORE_COLUMN_SIZE, /* G_TYPE_UINT64 */ - E_ATTACHMENT_STORE_NUM_COLUMNS -}; - -GType e_attachment_store_get_type (void); -GtkTreeModel * e_attachment_store_new (void); -void e_attachment_store_add_attachment - (EAttachmentStore *store, - EAttachment *attachment); -gboolean e_attachment_store_remove_attachment - (EAttachmentStore *store, - EAttachment *attachment); -void e_attachment_store_remove_all (EAttachmentStore *store); -void e_attachment_store_add_to_multipart - (EAttachmentStore *store, - CamelMultipart *multipart, - const gchar *default_charset); -GList * e_attachment_store_get_attachments - (EAttachmentStore *store); -guint e_attachment_store_get_num_attachments - (EAttachmentStore *store); -guint e_attachment_store_get_num_loading - (EAttachmentStore *store); -goffset e_attachment_store_get_total_size - (EAttachmentStore *store); -void e_attachment_store_run_load_dialog - (EAttachmentStore *store, - GtkWindow *parent); -GFile * e_attachment_store_run_save_dialog - (EAttachmentStore *store, - GList *attachment_list, - GtkWindow *parent); - -/* Asynchronous Operations */ -void e_attachment_store_get_uris_async - (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data); -gchar ** e_attachment_store_get_uris_finish - (EAttachmentStore *store, - GAsyncResult *result, - GError **error); -void e_attachment_store_load_async (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_attachment_store_load_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error); -void e_attachment_store_save_async (EAttachmentStore *store, - GFile *destination, - const gchar *filename_prefix, - GAsyncReadyCallback callback, - gpointer user_data); -gchar ** e_attachment_store_save_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* E_ATTACHMENT_STORE_H */ - diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c deleted file mode 100644 index b73751fbbd..0000000000 --- a/widgets/misc/e-attachment-tree-view.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - * e-attachment-tree-view.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-tree-view.h" - -#include <glib/gi18n.h> -#include <libebackend/libebackend.h> - -#include "e-attachment.h" -#include "e-attachment-store.h" -#include "e-attachment-view.h" - -#define E_ATTACHMENT_TREE_VIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewPrivate)) - -struct _EAttachmentTreeViewPrivate { - EAttachmentViewPrivate view_priv; -}; - -enum { - PROP_0, - PROP_DRAGGING, - PROP_EDITABLE -}; - -/* Forward Declarations */ -static void e_attachment_tree_view_interface_init - (EAttachmentViewInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EAttachmentTreeView, - e_attachment_tree_view, - GTK_TYPE_TREE_VIEW, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ATTACHMENT_VIEW, - e_attachment_tree_view_interface_init) - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -static void -attachment_tree_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_DRAGGING: - e_attachment_view_set_dragging ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_attachment_view_set_editable ( - E_ATTACHMENT_VIEW (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_tree_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_DRAGGING: - g_value_set_boolean ( - value, e_attachment_view_get_dragging ( - E_ATTACHMENT_VIEW (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, e_attachment_view_get_editable ( - E_ATTACHMENT_VIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_tree_view_dispose (GObject *object) -{ - e_attachment_view_dispose (E_ATTACHMENT_VIEW (object)); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->dispose (object); -} - -static void -attachment_tree_view_finalize (GObject *object) -{ - e_attachment_view_finalize (E_ATTACHMENT_VIEW (object)); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->finalize (object); -} - -static void -attachment_tree_view_render_size (GtkTreeViewColumn *column, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter) -{ - gchar *display_size = NULL; - gint column_id; - guint64 size; - - column_id = E_ATTACHMENT_STORE_COLUMN_SIZE; - gtk_tree_model_get (model, iter, column_id, &size, -1); - - if (size > 0) - display_size = g_format_size ((goffset) size); - - g_object_set (renderer, "text", display_size, NULL); - - g_free (display_size); -} - -static gboolean -attachment_tree_view_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_button_press_event (view, event)) - return TRUE; - - /* Chain up to parent's button_press_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - button_press_event (widget, event); -} - -static gboolean -attachment_tree_view_button_release_event (GtkWidget *widget, - GdkEventButton *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_button_release_event (view, event)) - return TRUE; - - /* Chain up to parent's button_release_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - button_release_event (widget, event); -} - -static gboolean -attachment_tree_view_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_motion_notify_event (view, event)) - return TRUE; - - /* Chain up to parent's motion_notify_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - motion_notify_event (widget, event); -} - -static gboolean -attachment_tree_view_key_press_event (GtkWidget *widget, - GdkEventKey *event) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (e_attachment_view_key_press_event (view, event)) - return TRUE; - - /* Chain up to parent's key_press_event() method. */ - return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - key_press_event (widget, event); -} - -static void -attachment_tree_view_drag_begin (GtkWidget *widget, - GdkDragContext *context) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - /* Chain up to parent's drag_begin() method. */ - GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - drag_begin (widget, context); - - e_attachment_view_drag_begin (view, context); -} - -static void -attachment_tree_view_drag_end (GtkWidget *widget, - GdkDragContext *context) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - /* Chain up to parent's drag_end() method. */ - GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - drag_end (widget, context); - - e_attachment_view_drag_end (view, context); -} - -static void -attachment_tree_view_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_drag_data_get ( - view, context, selection, info, time); -} - -static gboolean -attachment_tree_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - return e_attachment_view_drag_motion (view, context, x, y, time); -} - -static gboolean -attachment_tree_view_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - if (!e_attachment_view_drag_drop (view, context, x, y, time)) - return FALSE; - - /* Chain up to parent's drag_drop() method. */ - return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)-> - drag_drop (widget, context, x, y, time); -} - -static void -attachment_tree_view_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_drag_data_received ( - view, context, x, y, selection, info, time); -} - -static gboolean -attachment_tree_view_popup_menu (GtkWidget *widget) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - - e_attachment_view_show_popup_menu (view, NULL, NULL, NULL); - - return TRUE; -} - -static void -attachment_tree_view_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column) -{ - EAttachmentView *view = E_ATTACHMENT_VIEW (tree_view); - - e_attachment_view_open_path (view, path, NULL); -} - -static EAttachmentViewPrivate * -attachment_tree_view_get_private (EAttachmentView *view) -{ - EAttachmentTreeViewPrivate *priv; - - priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (view); - - return &priv->view_priv; -} - -static EAttachmentStore * -attachment_tree_view_get_store (EAttachmentView *view) -{ - GtkTreeView *tree_view; - GtkTreeModel *model; - - tree_view = GTK_TREE_VIEW (view); - model = gtk_tree_view_get_model (tree_view); - - return E_ATTACHMENT_STORE (model); -} - -static GtkTreePath * -attachment_tree_view_get_path_at_pos (EAttachmentView *view, - gint x, - gint y) -{ - GtkTreeView *tree_view; - GtkTreePath *path; - gboolean row_exists; - - tree_view = GTK_TREE_VIEW (view); - - row_exists = gtk_tree_view_get_path_at_pos ( - tree_view, x, y, &path, NULL, NULL, NULL); - - return row_exists ? path : NULL; -} - -static GList * -attachment_tree_view_get_selected_paths (EAttachmentView *view) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - return gtk_tree_selection_get_selected_rows (selection, NULL); -} - -static gboolean -attachment_tree_view_path_is_selected (EAttachmentView *view, - GtkTreePath *path) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - return gtk_tree_selection_path_is_selected (selection, path); -} - -static void -attachment_tree_view_select_path (EAttachmentView *view, - GtkTreePath *path) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - gtk_tree_selection_select_path (selection, path); -} - -static void -attachment_tree_view_unselect_path (EAttachmentView *view, - GtkTreePath *path) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - gtk_tree_selection_unselect_path (selection, path); -} - -static void -attachment_tree_view_select_all (EAttachmentView *view) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - gtk_tree_selection_select_all (selection); -} - -static void -attachment_tree_view_unselect_all (EAttachmentView *view) -{ - GtkTreeView *tree_view; - GtkTreeSelection *selection; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); - - gtk_tree_selection_unselect_all (selection); -} - -static void -attachment_tree_view_drag_source_set (EAttachmentView *view, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - GtkTreeView *tree_view; - - tree_view = GTK_TREE_VIEW (view); - - gtk_tree_view_enable_model_drag_source ( - tree_view, start_button_mask, targets, n_targets, actions); -} - -static void -attachment_tree_view_drag_dest_set (EAttachmentView *view, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - GtkTreeView *tree_view; - - tree_view = GTK_TREE_VIEW (view); - - gtk_tree_view_enable_model_drag_dest ( - tree_view, targets, n_targets, actions); -} - -static void -attachment_tree_view_drag_source_unset (EAttachmentView *view) -{ - GtkTreeView *tree_view; - - tree_view = GTK_TREE_VIEW (view); - - gtk_tree_view_unset_rows_drag_source (tree_view); -} - -static void -attachment_tree_view_drag_dest_unset (EAttachmentView *view) -{ - GtkTreeView *tree_view; - - tree_view = GTK_TREE_VIEW (view); - - gtk_tree_view_unset_rows_drag_dest (tree_view); -} - -static void -e_attachment_tree_view_class_init (EAttachmentTreeViewClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkTreeViewClass *tree_view_class; - - g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_tree_view_set_property; - object_class->get_property = attachment_tree_view_get_property; - object_class->dispose = attachment_tree_view_dispose; - object_class->finalize = attachment_tree_view_finalize; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->button_press_event = attachment_tree_view_button_press_event; - widget_class->button_release_event = attachment_tree_view_button_release_event; - widget_class->motion_notify_event = attachment_tree_view_motion_notify_event; - widget_class->key_press_event = attachment_tree_view_key_press_event; - widget_class->drag_begin = attachment_tree_view_drag_begin; - widget_class->drag_end = attachment_tree_view_drag_end; - widget_class->drag_data_get = attachment_tree_view_drag_data_get; - widget_class->drag_motion = attachment_tree_view_drag_motion; - widget_class->drag_drop = attachment_tree_view_drag_drop; - widget_class->drag_data_received = attachment_tree_view_drag_data_received; - widget_class->popup_menu = attachment_tree_view_popup_menu; - - tree_view_class = GTK_TREE_VIEW_CLASS (class); - tree_view_class->row_activated = attachment_tree_view_row_activated; - - g_object_class_override_property ( - object_class, PROP_DRAGGING, "dragging"); - - g_object_class_override_property ( - object_class, PROP_EDITABLE, "editable"); -} - -static void -e_attachment_tree_view_init (EAttachmentTreeView *tree_view) -{ - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - tree_view->priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (tree_view); - - e_attachment_view_init (E_ATTACHMENT_VIEW (tree_view)); - - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); - - /* Name Column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_column_set_spacing (column, 3); - gtk_tree_view_column_set_title (column, _("Description")); - gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); - - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - - g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL); - - gtk_tree_view_column_add_attribute ( - column, renderer, "gicon", - E_ATTACHMENT_STORE_COLUMN_ICON); - - renderer = gtk_cell_renderer_text_new (); - g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - - gtk_tree_view_column_add_attribute ( - column, renderer, "text", - E_ATTACHMENT_STORE_COLUMN_DESCRIPTION); - - renderer = gtk_cell_renderer_progress_new (); - g_object_set (renderer, "text", _("Loading"), NULL); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - - gtk_tree_view_column_add_attribute ( - column, renderer, "value", - E_ATTACHMENT_STORE_COLUMN_PERCENT); - - gtk_tree_view_column_add_attribute ( - column, renderer, "visible", - E_ATTACHMENT_STORE_COLUMN_LOADING); - - renderer = gtk_cell_renderer_progress_new (); - g_object_set (renderer, "text", _("Saving"), NULL); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - - gtk_tree_view_column_add_attribute ( - column, renderer, "value", - E_ATTACHMENT_STORE_COLUMN_PERCENT); - - gtk_tree_view_column_add_attribute ( - column, renderer, "visible", - E_ATTACHMENT_STORE_COLUMN_SAVING); - - /* Size Column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Size")); - gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - - gtk_tree_view_column_set_cell_data_func ( - column, renderer, (GtkTreeCellDataFunc) - attachment_tree_view_render_size, NULL, NULL); - - /* Type Column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Type")); - gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - - gtk_tree_view_column_add_attribute ( - column, renderer, "text", - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE); - - e_extensible_load_extensions (E_EXTENSIBLE (tree_view)); -} - -static void -e_attachment_tree_view_interface_init (EAttachmentViewInterface *interface) -{ - interface->get_private = attachment_tree_view_get_private; - interface->get_store = attachment_tree_view_get_store; - - interface->get_path_at_pos = attachment_tree_view_get_path_at_pos; - interface->get_selected_paths = attachment_tree_view_get_selected_paths; - interface->path_is_selected = attachment_tree_view_path_is_selected; - interface->select_path = attachment_tree_view_select_path; - interface->unselect_path = attachment_tree_view_unselect_path; - interface->select_all = attachment_tree_view_select_all; - interface->unselect_all = attachment_tree_view_unselect_all; - - interface->drag_source_set = attachment_tree_view_drag_source_set; - interface->drag_dest_set = attachment_tree_view_drag_dest_set; - interface->drag_source_unset = attachment_tree_view_drag_source_unset; - interface->drag_dest_unset = attachment_tree_view_drag_dest_unset; -} - -GtkWidget * -e_attachment_tree_view_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT_TREE_VIEW, NULL); -} diff --git a/widgets/misc/e-attachment-tree-view.h b/widgets/misc/e-attachment-tree-view.h deleted file mode 100644 index 4300ffa71f..0000000000 --- a/widgets/misc/e-attachment-tree-view.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * e-attachment-tree-view.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_TREE_VIEW_H -#define E_ATTACHMENT_TREE_VIEW_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_TREE_VIEW \ - (e_attachment_tree_view_get_type ()) -#define E_ATTACHMENT_TREE_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeView)) -#define E_ATTACHMENT_TREE_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewClass)) -#define E_IS_ATTACHMENT_TREE_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_TREE_VIEW)) -#define E_IS_ATTACHMENT_TREE_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_TREE_VIEW)) -#define E_ATTACHMENT_TREE_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentTreeView EAttachmentTreeView; -typedef struct _EAttachmentTreeViewClass EAttachmentTreeViewClass; -typedef struct _EAttachmentTreeViewPrivate EAttachmentTreeViewPrivate; - -struct _EAttachmentTreeView { - GtkTreeView parent; - EAttachmentTreeViewPrivate *priv; -}; - -struct _EAttachmentTreeViewClass { - GtkTreeViewClass parent_class; -}; - -GType e_attachment_tree_view_get_type (void); -GtkWidget * e_attachment_tree_view_new (void); - -G_END_DECLS - -#endif /* E_ATTACHMENT_TREE_VIEW_H */ diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c deleted file mode 100644 index e8f9af8fdb..0000000000 --- a/widgets/misc/e-attachment-view.c +++ /dev/null @@ -1,1907 +0,0 @@ -/* - * e-attachment-view.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment-view.h" - -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> - -#include "e-util/e-selection.h" -#include "e-util/e-ui-manager.h" -#include "e-util/e-util.h" - -#include "e-attachment-dialog.h" -#include "e-attachment-handler-image.h" -#include "e-attachment-handler-sendto.h" - -enum { - UPDATE_ACTIONS, - LAST_SIGNAL -}; - -/* Note: Do not use the info field. */ -static GtkTargetEntry target_table[] = { - { (gchar *) "_NETSCAPE_URL", 0, 0 } -}; - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <menuitem action='cancel'/>" -" <menuitem action='save-as'/>" -" <menuitem action='remove'/>" -" <menuitem action='properties'/>" -" <separator/>" -" <placeholder name='inline-actions'>" -" <menuitem action='show'/>" -" <menuitem action='show-all'/>" -" <separator/>" -" <menuitem action='hide'/>" -" <menuitem action='hide-all'/>" -" </placeholder>" -" <separator/>" -" <placeholder name='custom-actions'/>" -" <separator/>" -" <menuitem action='add'/>" -" <separator/>" -" <placeholder name='open-actions'/>" -" <menuitem action='open-with'/>" -" </popup>" -"</ui>"; - -static gulong signals[LAST_SIGNAL]; - -G_DEFINE_INTERFACE ( - EAttachmentView, - e_attachment_view, - GTK_TYPE_WIDGET) - -static void -action_add_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentStore *store; - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - store = e_attachment_view_get_store (view); - e_attachment_store_run_load_dialog (store, parent); -} - -static void -action_cancel_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachment *attachment; - GList *list; - - list = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (list) == 1); - attachment = list->data; - - e_attachment_cancel (attachment); - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_hide_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachment *attachment; - GList *list; - - list = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (list) == 1); - attachment = list->data; - - e_attachment_set_shown (attachment, FALSE); - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_hide_all_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentStore *store; - GList *list, *iter; - - store = e_attachment_view_get_store (view); - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment; - - attachment = E_ATTACHMENT (iter->data); - e_attachment_set_shown (attachment, FALSE); - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_open_with_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachment *attachment; - EAttachmentStore *store; - GtkWidget *dialog; - GtkTreePath *path; - GtkTreeIter iter; - GAppInfo *app_info = NULL; - GFileInfo *file_info; - GList *list; - gpointer parent; - const gchar *content_type; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - list = e_attachment_view_get_selected_paths (view); - g_return_if_fail (g_list_length (list) == 1); - path = list->data; - - store = e_attachment_view_get_store (view); - gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_get ( - GTK_TREE_MODEL (store), &iter, - E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, &attachment, -1); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - file_info = e_attachment_get_file_info (attachment); - g_return_if_fail (file_info != NULL); - - content_type = g_file_info_get_content_type (file_info); - - dialog = gtk_app_chooser_dialog_new_for_content_type ( - parent, 0, content_type); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - GtkAppChooser *app_chooser = GTK_APP_CHOOSER (dialog); - app_info = gtk_app_chooser_get_app_info (app_chooser); - } - gtk_widget_destroy (dialog); - - if (app_info != NULL) { - e_attachment_view_open_path (view, path, app_info); - g_object_unref (app_info); - } - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); -} - -static void -action_open_with_app_info_cb (GtkAction *action, - EAttachmentView *view) -{ - GAppInfo *app_info; - GtkTreePath *path; - GList *list; - - list = e_attachment_view_get_selected_paths (view); - g_return_if_fail (g_list_length (list) == 1); - path = list->data; - - app_info = g_object_get_data (G_OBJECT (action), "app-info"); - g_return_if_fail (G_IS_APP_INFO (app_info)); - - e_attachment_view_open_path (view, path, app_info); - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); -} - -static void -action_properties_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachment *attachment; - GtkWidget *dialog; - GList *list; - gpointer parent; - - list = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (list) == 1); - attachment = list->data; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - dialog = e_attachment_dialog_new (parent, attachment); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_remove_cb (GtkAction *action, - EAttachmentView *view) -{ - e_attachment_view_remove_selected (view, FALSE); -} - -static void -action_save_all_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentStore *store; - GList *list, *iter; - GFile *destination; - gpointer parent; - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - /* XXX We lose the previous selection. */ - e_attachment_view_select_all (view); - list = e_attachment_view_get_selected_attachments (view); - e_attachment_view_unselect_all (view); - - destination = e_attachment_store_run_save_dialog ( - store, list, parent); - - if (destination == NULL) - goto exit; - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - - e_attachment_save_async ( - attachment, destination, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); - } - - g_object_unref (destination); - -exit: - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_save_as_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentStore *store; - GList *list, *iter; - GFile *destination; - gpointer parent; - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - list = e_attachment_view_get_selected_attachments (view); - - destination = e_attachment_store_run_save_dialog ( - store, list, parent); - - if (destination == NULL) - goto exit; - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - - e_attachment_save_async ( - attachment, destination, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); - } - - g_object_unref (destination); - -exit: - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_show_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachment *attachment; - GList *list; - - list = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (list) == 1); - attachment = list->data; - - e_attachment_set_shown (attachment, TRUE); - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -action_show_all_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentStore *store; - GList *list, *iter; - - store = e_attachment_view_get_store (view); - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment; - - attachment = E_ATTACHMENT (iter->data); - e_attachment_set_shown (attachment, TRUE); - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static GtkActionEntry standard_entries[] = { - - { "cancel", - GTK_STOCK_CANCEL, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_cancel_cb) }, - - { "open-with", - NULL, - N_("Open With Other Application..."), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_open_with_cb) }, - - { "save-all", - GTK_STOCK_SAVE_AS, - N_("S_ave All"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_save_all_cb) }, - - { "save-as", - GTK_STOCK_SAVE_AS, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_save_as_cb) }, - - /* Alternate "save-all" label, for when - * the attachment store has one row. */ - { "save-one", - GTK_STOCK_SAVE_AS, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_save_all_cb) }, -}; - -static GtkActionEntry editable_entries[] = { - - { "add", - GTK_STOCK_ADD, - N_("A_dd Attachment..."), - NULL, - N_("Attach a file"), - G_CALLBACK (action_add_cb) }, - - { "properties", - GTK_STOCK_PROPERTIES, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_properties_cb) }, - - { "remove", - GTK_STOCK_REMOVE, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_remove_cb) } -}; - -static GtkActionEntry inline_entries[] = { - - { "hide", - NULL, - N_("_Hide"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_hide_cb) }, - - { "hide-all", - NULL, - N_("Hid_e All"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_hide_all_cb) }, - - { "show", - NULL, - N_("_View Inline"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_show_cb) }, - - { "show-all", - NULL, - N_("Vie_w All Inline"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_show_all_cb) } -}; - -static void -attachment_view_netscape_url (EAttachmentView *view, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - static GdkAtom atom = GDK_NONE; - EAttachmentStore *store; - EAttachment *attachment; - const gchar *data; - gpointer parent; - gchar *copied_data; - gchar **strv; - gint length; - - if (G_UNLIKELY (atom == GDK_NONE)) - atom = gdk_atom_intern_static_string ("_NETSCAPE_URL"); - - if (gtk_selection_data_get_target (selection_data) != atom) - return; - - g_signal_stop_emission_by_name (view, "drag-data-received"); - - /* _NETSCAPE_URL is represented as "URI\nTITLE" */ - - data = (const gchar *) gtk_selection_data_get_data (selection_data); - length = gtk_selection_data_get_length (selection_data); - - copied_data = g_strndup (data, length); - strv = g_strsplit (copied_data, "\n", 2); - g_free (copied_data); - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - attachment = e_attachment_new_for_uri (strv[0]); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - - g_strfreev (strv); - - gtk_drag_finish (drag_context, TRUE, FALSE, time); -} - -static void -attachment_view_text_calendar (EAttachmentView *view, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - EAttachmentStore *store; - EAttachment *attachment; - CamelMimePart *mime_part; - GdkAtom data_type; - GdkAtom target; - const gchar *data; - gpointer parent; - gchar *content_type; - gint length; - - target = gtk_selection_data_get_target (selection_data); - if (!e_targets_include_calendar (&target, 1)) - return; - - g_signal_stop_emission_by_name (view, "drag-data-received"); - - data = (const gchar *) gtk_selection_data_get_data (selection_data); - length = gtk_selection_data_get_length (selection_data); - data_type = gtk_selection_data_get_data_type (selection_data); - - mime_part = camel_mime_part_new (); - - content_type = gdk_atom_name (data_type); - camel_mime_part_set_content (mime_part, data, length, content_type); - camel_mime_part_set_disposition (mime_part, "inline"); - g_free (content_type); - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - attachment = e_attachment_new (); - e_attachment_set_mime_part (attachment, mime_part); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - - g_object_unref (mime_part); - - gtk_drag_finish (drag_context, TRUE, FALSE, time); -} - -static void -attachment_view_text_x_vcard (EAttachmentView *view, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - EAttachmentStore *store; - EAttachment *attachment; - CamelMimePart *mime_part; - GdkAtom data_type; - GdkAtom target; - const gchar *data; - gpointer parent; - gchar *content_type; - gint length; - - target = gtk_selection_data_get_target (selection_data); - if (!e_targets_include_directory (&target, 1)) - return; - - g_signal_stop_emission_by_name (view, "drag-data-received"); - - data = (const gchar *) gtk_selection_data_get_data (selection_data); - length = gtk_selection_data_get_length (selection_data); - data_type = gtk_selection_data_get_data_type (selection_data); - - mime_part = camel_mime_part_new (); - - content_type = gdk_atom_name (data_type); - camel_mime_part_set_content (mime_part, data, length, content_type); - camel_mime_part_set_disposition (mime_part, "inline"); - g_free (content_type); - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - attachment = e_attachment_new (); - e_attachment_set_mime_part (attachment, mime_part); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - - g_object_unref (mime_part); - - gtk_drag_finish (drag_context, TRUE, FALSE, time); -} - -static void -attachment_view_uris (EAttachmentView *view, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - EAttachmentStore *store; - gpointer parent; - gchar **uris; - gint ii; - - uris = gtk_selection_data_get_uris (selection_data); - - if (uris == NULL) - return; - - g_signal_stop_emission_by_name (view, "drag-data-received"); - - store = e_attachment_view_get_store (view); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - for (ii = 0; uris[ii] != NULL; ii++) { - EAttachment *attachment; - - attachment = e_attachment_new_for_uri (uris[ii]); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - } - - g_strfreev (uris); - - gtk_drag_finish (drag_context, TRUE, FALSE, time); -} - -static void -attachment_view_update_actions (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - EAttachment *attachment; - EAttachmentStore *store; - GtkActionGroup *action_group; - GtkAction *action; - GList *list, *iter; - guint n_shown = 0; - guint n_hidden = 0; - guint n_selected; - gboolean busy = FALSE; - gboolean can_show = FALSE; - gboolean shown = FALSE; - gboolean visible; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - priv = e_attachment_view_get_private (view); - - store = e_attachment_view_get_store (view); - list = e_attachment_store_get_attachments (store); - - for (iter = list; iter != NULL; iter = iter->next) { - attachment = iter->data; - - if (!e_attachment_get_can_show (attachment)) - continue; - - if (e_attachment_get_shown (attachment)) - n_shown++; - else - n_hidden++; - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - list = e_attachment_view_get_selected_attachments (view); - n_selected = g_list_length (list); - - if (n_selected == 1) { - attachment = g_object_ref (list->data); - busy |= e_attachment_get_loading (attachment); - busy |= e_attachment_get_saving (attachment); - can_show = e_attachment_get_can_show (attachment); - shown = e_attachment_get_shown (attachment); - } else - attachment = NULL; - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - action = e_attachment_view_get_action (view, "cancel"); - gtk_action_set_visible (action, busy); - - action = e_attachment_view_get_action (view, "hide"); - gtk_action_set_visible (action, can_show && shown); - - /* Show this action if there are multiple viewable - * attachments, and at least one of them is shown. */ - visible = (n_shown + n_hidden > 1) && (n_shown > 0); - action = e_attachment_view_get_action (view, "hide-all"); - gtk_action_set_visible (action, visible); - - action = e_attachment_view_get_action (view, "open-with"); - gtk_action_set_visible (action, !busy && n_selected == 1); - - action = e_attachment_view_get_action (view, "properties"); - gtk_action_set_visible (action, !busy && n_selected == 1); - - action = e_attachment_view_get_action (view, "remove"); - gtk_action_set_visible (action, !busy && n_selected > 0); - - action = e_attachment_view_get_action (view, "save-as"); - gtk_action_set_visible (action, !busy && n_selected > 0); - - action = e_attachment_view_get_action (view, "show"); - gtk_action_set_visible (action, can_show && !shown); - - /* Show this action if there are multiple viewable - * attachments, and at least one of them is hidden. */ - visible = (n_shown + n_hidden > 1) && (n_hidden > 0); - action = e_attachment_view_get_action (view, "show-all"); - gtk_action_set_visible (action, visible); - - /* Clear out the "openwith" action group. */ - gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); - action_group = e_attachment_view_get_action_group (view, "openwith"); - e_action_group_remove_all_actions (action_group); - gtk_ui_manager_ensure_update (priv->ui_manager); - - if (attachment == NULL || busy) - return; - - list = e_attachment_list_apps (attachment); - - for (iter = list; iter != NULL; iter = iter->next) { - GAppInfo *app_info = iter->data; - GtkAction *action; - GIcon *app_icon; - const gchar *app_executable; - const gchar *app_name; - gchar *action_tooltip; - gchar *action_label; - gchar *action_name; - - app_executable = g_app_info_get_executable (app_info); - app_icon = g_app_info_get_icon (app_info); - app_name = g_app_info_get_name (app_info); - - action_name = g_strdup_printf ("open-with-%s", app_executable); - action_label = g_strdup_printf (_("Open With \"%s\""), app_name); - - action_tooltip = g_strdup_printf ( - _("Open this attachment in %s"), app_name); - - action = gtk_action_new ( - action_name, action_label, action_tooltip, NULL); - - gtk_action_set_gicon (action, app_icon); - - g_object_set_data_full ( - G_OBJECT (action), - "app-info", g_object_ref (app_info), - (GDestroyNotify) g_object_unref); - - g_object_set_data_full ( - G_OBJECT (action), - "attachment", g_object_ref (attachment), - (GDestroyNotify) g_object_unref); - - g_signal_connect ( - action, "activate", - G_CALLBACK (action_open_with_app_info_cb), view); - - gtk_action_group_add_action (action_group, action); - - gtk_ui_manager_add_ui ( - priv->ui_manager, priv->merge_id, - "/context/open-actions", action_name, - action_name, GTK_UI_MANAGER_AUTO, FALSE); - - g_free (action_name); - g_free (action_label); - g_free (action_tooltip); - } - - g_object_unref (attachment); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -static void -attachment_view_init_drag_dest (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - GtkTargetList *target_list; - - priv = e_attachment_view_get_private (view); - - target_list = gtk_target_list_new ( - target_table, G_N_ELEMENTS (target_table)); - - gtk_target_list_add_uri_targets (target_list, 0); - e_target_list_add_calendar_targets (target_list, 0); - e_target_list_add_directory_targets (target_list, 0); - - priv->target_list = target_list; - priv->drag_actions = GDK_ACTION_COPY; -} - -static void -e_attachment_view_default_init (EAttachmentViewInterface *interface) -{ - interface->update_actions = attachment_view_update_actions; - - g_object_interface_install_property ( - interface, - g_param_spec_boolean ( - "dragging", - "Dragging", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_interface_install_property ( - interface, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - signals[UPDATE_ACTIONS] = g_signal_new ( - "update-actions", - G_TYPE_FROM_INTERFACE (interface), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EAttachmentViewInterface, update_actions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* Register known handler types. */ - e_attachment_handler_image_get_type (); - e_attachment_handler_sendto_get_type (); -} - -void -e_attachment_view_init (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - GError *error = NULL; - - priv = e_attachment_view_get_private (view); - - ui_manager = e_ui_manager_new (); - priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); - priv->ui_manager = ui_manager; - - action_group = e_attachment_view_add_action_group (view, "standard"); - - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), view); - - action_group = e_attachment_view_add_action_group (view, "editable"); - - g_object_bind_property ( - view, "editable", - action_group, "visible", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - gtk_action_group_add_actions ( - action_group, editable_entries, - G_N_ELEMENTS (editable_entries), view); - - action_group = e_attachment_view_add_action_group (view, "inline"); - - gtk_action_group_add_actions ( - action_group, inline_entries, - G_N_ELEMENTS (inline_entries), view); - gtk_action_group_set_visible (action_group, FALSE); - - e_attachment_view_add_action_group (view, "openwith"); - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here implies a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); - - attachment_view_init_drag_dest (view); - - e_attachment_view_drag_source_set (view); - - /* Connect built-in drag and drop handlers. */ - - g_signal_connect ( - view, "drag-data-received", - G_CALLBACK (attachment_view_netscape_url), NULL); - - g_signal_connect ( - view, "drag-data-received", - G_CALLBACK (attachment_view_text_calendar), NULL); - - g_signal_connect ( - view, "drag-data-received", - G_CALLBACK (attachment_view_text_x_vcard), NULL); - - g_signal_connect ( - view, "drag-data-received", - G_CALLBACK (attachment_view_uris), NULL); -} - -void -e_attachment_view_dispose (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - priv = e_attachment_view_get_private (view); - - if (priv->target_list != NULL) { - gtk_target_list_unref (priv->target_list); - priv->target_list = NULL; - } - - if (priv->ui_manager != NULL) { - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - } -} - -void -e_attachment_view_finalize (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - priv = e_attachment_view_get_private (view); - - g_list_foreach (priv->event_list, (GFunc) gdk_event_free, NULL); - g_list_free (priv->event_list); - - g_list_foreach (priv->selected, (GFunc) g_object_unref, NULL); - g_list_free (priv->selected); -} - -EAttachmentViewPrivate * -e_attachment_view_get_private (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_val_if_fail (interface->get_private != NULL, NULL); - - return interface->get_private (view); -} - -EAttachmentStore * -e_attachment_view_get_store (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_val_if_fail (interface->get_store != NULL, NULL); - - return interface->get_store (view); -} - -gboolean -e_attachment_view_get_editable (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - - priv = e_attachment_view_get_private (view); - - return priv->editable; -} - -void -e_attachment_view_set_editable (EAttachmentView *view, - gboolean editable) -{ - EAttachmentViewPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - priv = e_attachment_view_get_private (view); - - priv->editable = editable; - - if (editable) - e_attachment_view_drag_dest_set (view); - else - e_attachment_view_drag_dest_unset (view); - - g_object_notify (G_OBJECT (view), "editable"); -} - -gboolean -e_attachment_view_get_dragging (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - - priv = e_attachment_view_get_private (view); - - return priv->dragging; -} - -void -e_attachment_view_set_dragging (EAttachmentView *view, - gboolean dragging) -{ - EAttachmentViewPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - priv = e_attachment_view_get_private (view); - - priv->dragging = dragging; - - g_object_notify (G_OBJECT (view), "dragging"); -} - -GtkTargetList * -e_attachment_view_get_target_list (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - priv = e_attachment_view_get_private (view); - - return priv->target_list; -} - -GdkDragAction -e_attachment_view_get_drag_actions (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), 0); - - priv = e_attachment_view_get_private (view); - - return priv->drag_actions; -} - -void -e_attachment_view_add_drag_actions (EAttachmentView *view, - GdkDragAction drag_actions) -{ - EAttachmentViewPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - priv = e_attachment_view_get_private (view); - - priv->drag_actions |= drag_actions; -} - -GList * -e_attachment_view_get_selected_attachments (EAttachmentView *view) -{ - EAttachmentStore *store; - GtkTreeModel *model; - GList *list, *item; - gint column_id; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - list = e_attachment_view_get_selected_paths (view); - store = e_attachment_view_get_store (view); - model = GTK_TREE_MODEL (store); - - /* Convert the GtkTreePaths to EAttachments. */ - for (item = list; item != NULL; item = item->next) { - EAttachment *attachment; - GtkTreePath *path; - GtkTreeIter iter; - - path = item->data; - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - gtk_tree_path_free (path); - - item->data = attachment; - } - - return list; -} - -void -e_attachment_view_open_path (EAttachmentView *view, - GtkTreePath *path, - GAppInfo *app_info) -{ - EAttachmentStore *store; - EAttachment *attachment; - GtkTreeModel *model; - GtkTreeIter iter; - gpointer parent; - gint column_id; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (path != NULL); - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - store = e_attachment_view_get_store (view); - model = GTK_TREE_MODEL (store); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - e_attachment_open_async ( - attachment, app_info, (GAsyncReadyCallback) - e_attachment_open_handle_error, parent); - - g_object_unref (attachment); -} - -void -e_attachment_view_remove_selected (EAttachmentView *view, - gboolean select_next) -{ - EAttachmentStore *store; - GtkTreeModel *model; - GList *list, *item; - gint column_id; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - list = e_attachment_view_get_selected_paths (view); - store = e_attachment_view_get_store (view); - model = GTK_TREE_MODEL (store); - - /* Remove attachments in reverse order to avoid invalidating - * tree paths as we iterate over the list. Note, the list is - * probably already sorted but we sort again just to be safe. */ - list = g_list_reverse (g_list_sort ( - list, (GCompareFunc) gtk_tree_path_compare)); - - for (item = list; item != NULL; item = item->next) { - EAttachment *attachment; - GtkTreePath *path = item->data; - GtkTreeIter iter; - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - e_attachment_store_remove_attachment (store, attachment); - g_object_unref (attachment); - } - - /* If we only removed one attachment, try to select another. */ - if (select_next && g_list_length (list) == 1) { - GtkTreePath *path = list->data; - - e_attachment_view_select_path (view, path); - if (!e_attachment_view_path_is_selected (view, path)) - if (gtk_tree_path_prev (path)) - e_attachment_view_select_path (view, path); - } - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); -} - -gboolean -e_attachment_view_button_press_event (EAttachmentView *view, - GdkEventButton *event) -{ - EAttachmentViewPrivate *priv; - GtkTreePath *path; - gboolean editable; - gboolean handled = FALSE; - gboolean path_is_selected = FALSE; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - priv = e_attachment_view_get_private (view); - - if (g_list_find (priv->event_list, event) != NULL) - return FALSE; - - if (priv->event_list != NULL) { - /* Save the event to be propagated in order. */ - priv->event_list = g_list_append ( - priv->event_list, - gdk_event_copy ((GdkEvent *) event)); - return TRUE; - } - - editable = e_attachment_view_get_editable (view); - path = e_attachment_view_get_path_at_pos (view, event->x, event->y); - path_is_selected = e_attachment_view_path_is_selected (view, path); - - if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { - GList *list, *iter; - gboolean busy = FALSE; - - list = e_attachment_view_get_selected_attachments (view); - - for (iter = list; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - busy |= e_attachment_get_loading (attachment); - busy |= e_attachment_get_saving (attachment); - } - - /* Prepare for dragging if the clicked item is selected - * and none of the selected items are loading or saving. */ - if (path_is_selected && !busy) { - priv->start_x = event->x; - priv->start_y = event->y; - priv->event_list = g_list_append ( - priv->event_list, - gdk_event_copy ((GdkEvent *) event)); - handled = TRUE; - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - } - - if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { - /* If the user clicked on a selected item, retain the - * current selection. If the user clicked on an unselected - * item, select the clicked item only. If the user did not - * click on an item, clear the current selection. */ - if (path == NULL) - e_attachment_view_unselect_all (view); - else if (!path_is_selected) { - e_attachment_view_unselect_all (view); - e_attachment_view_select_path (view, path); - } - - /* Non-editable attachment views should only show a - * popup menu when right-clicking on an attachment, - * but editable views can show the menu any time. */ - if (path != NULL || editable) { - e_attachment_view_show_popup_menu ( - view, event, NULL, NULL); - handled = TRUE; - } - } - - if (path != NULL) - gtk_tree_path_free (path); - - return handled; -} - -gboolean -e_attachment_view_button_release_event (EAttachmentView *view, - GdkEventButton *event) -{ - EAttachmentViewPrivate *priv; - GtkWidget *widget = GTK_WIDGET (view); - GList *iter; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - priv = e_attachment_view_get_private (view); - - for (iter = priv->event_list; iter != NULL; iter = iter->next) { - GdkEvent *event = iter->data; - - gtk_propagate_event (widget, event); - gdk_event_free (event); - } - - g_list_free (priv->event_list); - priv->event_list = NULL; - - return FALSE; -} - -gboolean -e_attachment_view_motion_notify_event (EAttachmentView *view, - GdkEventMotion *event) -{ - EAttachmentViewPrivate *priv; - GtkWidget *widget = GTK_WIDGET (view); - GtkTargetList *targets; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - priv = e_attachment_view_get_private (view); - - if (priv->event_list == NULL) - return FALSE; - - if (!gtk_drag_check_threshold ( - widget, priv->start_x, priv->start_y, event->x, event->y)) - return TRUE; - - g_list_foreach (priv->event_list, (GFunc) gdk_event_free, NULL); - g_list_free (priv->event_list); - priv->event_list = NULL; - - targets = gtk_drag_source_get_target_list (widget); - - gtk_drag_begin ( - widget, targets, GDK_ACTION_COPY, 1, (GdkEvent *) event); - - return TRUE; -} - -gboolean -e_attachment_view_key_press_event (EAttachmentView *view, - GdkEventKey *event) -{ - gboolean editable; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - editable = e_attachment_view_get_editable (view); - - if (event->keyval == GDK_KEY_Delete && editable) { - e_attachment_view_remove_selected (view, TRUE); - return TRUE; - } - - return FALSE; -} - -GtkTreePath * -e_attachment_view_get_path_at_pos (EAttachmentView *view, - gint x, - gint y) -{ - EAttachmentViewInterface *interface; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_val_if_fail (interface->get_path_at_pos != NULL, NULL); - - return interface->get_path_at_pos (view, x, y); -} - -GList * -e_attachment_view_get_selected_paths (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_val_if_fail (interface->get_selected_paths != NULL, NULL); - - return interface->get_selected_paths (view); -} - -gboolean -e_attachment_view_path_is_selected (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentViewInterface *interface; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - - /* Handle NULL paths gracefully. */ - if (path == NULL) - return FALSE; - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_val_if_fail (interface->path_is_selected != NULL, FALSE); - - return interface->path_is_selected (view, path); -} - -void -e_attachment_view_select_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (path != NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_if_fail (interface->select_path != NULL); - - interface->select_path (view, path); -} - -void -e_attachment_view_unselect_path (EAttachmentView *view, - GtkTreePath *path) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (path != NULL); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_if_fail (interface->unselect_path != NULL); - - interface->unselect_path (view, path); -} - -void -e_attachment_view_select_all (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_if_fail (interface->select_all != NULL); - - interface->select_all (view); -} - -void -e_attachment_view_unselect_all (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - g_return_if_fail (interface->unselect_all != NULL); - - interface->unselect_all (view); -} - -void -e_attachment_view_sync_selection (EAttachmentView *view, - EAttachmentView *target) -{ - GList *list, *iter; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (E_IS_ATTACHMENT_VIEW (target)); - - list = e_attachment_view_get_selected_paths (view); - e_attachment_view_unselect_all (target); - - for (iter = list; iter != NULL; iter = iter->next) - e_attachment_view_select_path (target, iter->data); - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); -} - -void -e_attachment_view_drag_source_set (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - GtkTargetEntry *targets; - GtkTargetList *list; - gint n_targets; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - if (interface->drag_source_set == NULL) - return; - - list = gtk_target_list_new (NULL, 0); - gtk_target_list_add_uri_targets (list, 0); - targets = gtk_target_table_new_from_list (list, &n_targets); - - interface->drag_source_set ( - view, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_target_table_free (targets, n_targets); - gtk_target_list_unref (list); -} - -void -e_attachment_view_drag_source_unset (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - if (interface->drag_source_unset == NULL) - return; - - interface->drag_source_unset (view); -} - -void -e_attachment_view_drag_begin (EAttachmentView *view, - GdkDragContext *context) -{ - EAttachmentViewPrivate *priv; - guint n_selected; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - - priv = e_attachment_view_get_private (view); - - e_attachment_view_set_dragging (view, TRUE); - - g_warn_if_fail (priv->selected == NULL); - priv->selected = e_attachment_view_get_selected_attachments (view); - n_selected = g_list_length (priv->selected); - - if (n_selected > 1) - gtk_drag_set_icon_stock ( - context, GTK_STOCK_DND_MULTIPLE, 0, 0); - - else if (n_selected == 1) { - EAttachment *attachment; - GtkIconTheme *icon_theme; - GtkIconInfo *icon_info; - GIcon *icon; - gint width, height; - - attachment = E_ATTACHMENT (priv->selected->data); - icon = e_attachment_get_icon (attachment); - g_return_if_fail (icon != NULL); - - icon_theme = gtk_icon_theme_get_default (); - gtk_icon_size_lookup (GTK_ICON_SIZE_DND, &width, &height); - - icon_info = gtk_icon_theme_lookup_by_gicon ( - icon_theme, icon, MIN (width, height), - GTK_ICON_LOOKUP_USE_BUILTIN); - - if (icon_info != NULL) { - GdkPixbuf *pixbuf; - GError *error = NULL; - - pixbuf = gtk_icon_info_load_icon (icon_info, &error); - - if (pixbuf != NULL) { - gtk_drag_set_icon_pixbuf ( - context, pixbuf, 0, 0); - g_object_unref (pixbuf); - } else if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - gtk_icon_info_free (icon_info); - } - } -} - -void -e_attachment_view_drag_end (EAttachmentView *view, - GdkDragContext *context) -{ - EAttachmentViewPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - - priv = e_attachment_view_get_private (view); - - e_attachment_view_set_dragging (view, FALSE); - - g_list_foreach (priv->selected, (GFunc) g_object_unref, NULL); - g_list_free (priv->selected); - priv->selected = NULL; -} - -static void -attachment_view_got_uris_cb (EAttachmentStore *store, - GAsyncResult *result, - gpointer user_data) -{ - struct { - gchar **uris; - gboolean done; - } *status = user_data; - - /* XXX Since this is a best-effort function, - * should we care about errors? */ - status->uris = e_attachment_store_get_uris_finish ( - store, result, NULL); - - status->done = TRUE; -} - -void -e_attachment_view_drag_data_get (EAttachmentView *view, - GdkDragContext *context, - GtkSelectionData *selection, - guint info, - guint time) -{ - EAttachmentViewPrivate *priv; - EAttachmentStore *store; - - struct { - gchar **uris; - gboolean done; - } status; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - g_return_if_fail (selection != NULL); - - status.uris = NULL; - status.done = FALSE; - - priv = e_attachment_view_get_private (view); - store = e_attachment_view_get_store (view); - - if (priv->selected == NULL) - return; - - e_attachment_store_get_uris_async ( - store, priv->selected, (GAsyncReadyCallback) - attachment_view_got_uris_cb, &status); - - /* We can't return until we have results, so crank - * the main loop until the callback gets triggered. */ - while (!status.done) - if (gtk_main_iteration ()) - break; - - if (status.uris != NULL) - gtk_selection_data_set_uris (selection, status.uris); - - g_strfreev (status.uris); -} - -void -e_attachment_view_drag_dest_set (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - EAttachmentViewInterface *interface; - GtkTargetEntry *targets; - gint n_targets; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - if (interface->drag_dest_set == NULL) - return; - - priv = e_attachment_view_get_private (view); - - targets = gtk_target_table_new_from_list ( - priv->target_list, &n_targets); - - interface->drag_dest_set ( - view, targets, n_targets, priv->drag_actions); - - gtk_target_table_free (targets, n_targets); -} - -void -e_attachment_view_drag_dest_unset (EAttachmentView *view) -{ - EAttachmentViewInterface *interface; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - interface = E_ATTACHMENT_VIEW_GET_INTERFACE (view); - if (interface->drag_dest_unset == NULL) - return; - - interface->drag_dest_unset (view); -} - -gboolean -e_attachment_view_drag_motion (EAttachmentView *view, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EAttachmentViewPrivate *priv; - GdkDragAction actions; - GdkDragAction chosen_action; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE); - - priv = e_attachment_view_get_private (view); - - /* Disallow drops if we're not editable. */ - if (!e_attachment_view_get_editable (view)) - return FALSE; - - /* Disallow drops if we initiated the drag. - * This helps prevent duplicate attachments. */ - if (e_attachment_view_get_dragging (view)) - return FALSE; - - actions = gdk_drag_context_get_actions (context); - actions &= priv->drag_actions; - chosen_action = gdk_drag_context_get_suggested_action (context); - - if (chosen_action == GDK_ACTION_ASK) { - GdkDragAction mask; - - mask = GDK_ACTION_COPY | GDK_ACTION_MOVE; - if ((actions & mask) != mask) - chosen_action = GDK_ACTION_COPY; - } - - gdk_drag_status (context, chosen_action, time); - - return (chosen_action != 0); -} - -gboolean -e_attachment_view_drag_drop (EAttachmentView *view, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); - g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE); - - /* Disallow drops if we initiated the drag. - * This helps prevent duplicate attachments. */ - return !e_attachment_view_get_dragging (view); -} - -void -e_attachment_view_drag_data_received (EAttachmentView *view, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - GdkAtom atom; - gchar *name; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (GDK_IS_DRAG_CONTEXT (drag_context)); - - /* Drop handlers are supposed to stop further emission of the - * "drag-data-received" signal if they can handle the data. If - * we get this far it means none of the handlers were successful, - * so report the drop as failed. */ - - atom = gtk_selection_data_get_target (selection_data); - - name = gdk_atom_name (atom); - g_warning ("Unknown selection target: %s", name); - g_free (name); - - gtk_drag_finish (drag_context, FALSE, FALSE, time); -} - -GtkAction * -e_attachment_view_get_action (EAttachmentView *view, - const gchar *action_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - g_return_val_if_fail (action_name != NULL, NULL); - - ui_manager = e_attachment_view_get_ui_manager (view); - - return e_lookup_action (ui_manager, action_name); -} - -GtkActionGroup * -e_attachment_view_add_action_group (EAttachmentView *view, - const gchar *group_name) -{ - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - const gchar *domain; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_attachment_view_get_ui_manager (view); - domain = GETTEXT_PACKAGE; - - action_group = gtk_action_group_new (group_name); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - return action_group; -} - -GtkActionGroup * -e_attachment_view_get_action_group (EAttachmentView *view, - const gchar *group_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_attachment_view_get_ui_manager (view); - - return e_lookup_action_group (ui_manager, group_name); -} - -GtkWidget * -e_attachment_view_get_popup_menu (EAttachmentView *view) -{ - GtkUIManager *ui_manager; - GtkWidget *menu; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - ui_manager = e_attachment_view_get_ui_manager (view); - menu = gtk_ui_manager_get_widget (ui_manager, "/context"); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu; -} - -GtkUIManager * -e_attachment_view_get_ui_manager (EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); - - priv = e_attachment_view_get_private (view); - - return priv->ui_manager; -} - -void -e_attachment_view_show_popup_menu (EAttachmentView *view, - GdkEventButton *event, - GtkMenuPositionFunc func, - gpointer user_data) -{ - GtkWidget *menu; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - e_attachment_view_update_actions (view); - - menu = e_attachment_view_get_popup_menu (view); - - if (event != NULL) - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, event->button, event->time); - else - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, 0, gtk_get_current_event_time ()); -} - -void -e_attachment_view_update_actions (EAttachmentView *view) -{ - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - g_signal_emit (view, signals[UPDATE_ACTIONS], 0); -} diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h deleted file mode 100644 index 87274d0c63..0000000000 --- a/widgets/misc/e-attachment-view.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * e-attachment-view.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_VIEW_H -#define E_ATTACHMENT_VIEW_H - -#include <gtk/gtk.h> -#include <misc/e-attachment-store.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT_VIEW \ - (e_attachment_view_get_type ()) -#define E_ATTACHMENT_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_VIEW, EAttachmentView)) -#define E_ATTACHMENT_VIEW_INTERFACE(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_VIEW, EAttachmentViewInterface)) -#define E_IS_ATTACHMENT_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_VIEW)) -#define E_IS_ATTACHMENT_VIEW_INTERFACE(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_VIEW)) -#define E_ATTACHMENT_VIEW_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE \ - ((obj), E_TYPE_ATTACHMENT_VIEW, EAttachmentViewInterface)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentView EAttachmentView; -typedef struct _EAttachmentViewInterface EAttachmentViewInterface; -typedef struct _EAttachmentViewPrivate EAttachmentViewPrivate; - -struct _EAttachmentViewInterface { - GTypeInterface parent_interface; - - /* General Methods */ - EAttachmentViewPrivate * - (*get_private) (EAttachmentView *view); - EAttachmentStore * - (*get_store) (EAttachmentView *view); - - /* Selection Methods */ - GtkTreePath * (*get_path_at_pos) (EAttachmentView *view, - gint x, - gint y); - GList * (*get_selected_paths) (EAttachmentView *view); - gboolean (*path_is_selected) (EAttachmentView *view, - GtkTreePath *path); - void (*select_path) (EAttachmentView *view, - GtkTreePath *path); - void (*unselect_path) (EAttachmentView *view, - GtkTreePath *path); - void (*select_all) (EAttachmentView *view); - void (*unselect_all) (EAttachmentView *view); - - /* Drag and Drop Methods */ - void (*drag_source_set) (EAttachmentView *view, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); - void (*drag_dest_set) (EAttachmentView *view, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); - void (*drag_source_unset) (EAttachmentView *view); - void (*drag_dest_unset) (EAttachmentView *view); - - /* Signals */ - void (*update_actions) (EAttachmentView *view); -}; - -struct _EAttachmentViewPrivate { - - /* Drag Destination */ - GtkTargetList *target_list; - GdkDragAction drag_actions; - - /* Popup Menu Management */ - GtkUIManager *ui_manager; - guint merge_id; - - /* Multi-DnD State */ - GList *event_list; - GList *selected; - gint start_x; - gint start_y; - - guint dragging : 1; - guint editable : 1; -}; - -GType e_attachment_view_get_type (void); - -void e_attachment_view_init (EAttachmentView *view); -void e_attachment_view_dispose (EAttachmentView *view); -void e_attachment_view_finalize (EAttachmentView *view); - -EAttachmentViewPrivate * - e_attachment_view_get_private (EAttachmentView *view); -EAttachmentStore * - e_attachment_view_get_store (EAttachmentView *view); -gboolean e_attachment_view_get_dragging (EAttachmentView *view); -void e_attachment_view_set_dragging (EAttachmentView *view, - gboolean dragging); -gboolean e_attachment_view_get_editable (EAttachmentView *view); -void e_attachment_view_set_editable (EAttachmentView *view, - gboolean editable); -GtkTargetList * e_attachment_view_get_target_list - (EAttachmentView *view); -GdkDragAction e_attachment_view_get_drag_actions - (EAttachmentView *view); -void e_attachment_view_add_drag_actions - (EAttachmentView *view, - GdkDragAction drag_actions); -GList * e_attachment_view_get_selected_attachments - (EAttachmentView *view); -void e_attachment_view_open_path (EAttachmentView *view, - GtkTreePath *path, - GAppInfo *app_info); -void e_attachment_view_remove_selected - (EAttachmentView *view, - gboolean select_next); - -/* Event Support */ -gboolean e_attachment_view_button_press_event - (EAttachmentView *view, - GdkEventButton *event); -gboolean e_attachment_view_button_release_event - (EAttachmentView *view, - GdkEventButton *event); -gboolean e_attachment_view_motion_notify_event - (EAttachmentView *view, - GdkEventMotion *event); -gboolean e_attachment_view_key_press_event - (EAttachmentView *view, - GdkEventKey *event); - -/* Selection Management */ -GtkTreePath * e_attachment_view_get_path_at_pos - (EAttachmentView *view, - gint x, - gint y); -GList * e_attachment_view_get_selected_paths - (EAttachmentView *view); -gboolean e_attachment_view_path_is_selected - (EAttachmentView *view, - GtkTreePath *path); -void e_attachment_view_select_path (EAttachmentView *view, - GtkTreePath *path); -void e_attachment_view_unselect_path (EAttachmentView *view, - GtkTreePath *path); -void e_attachment_view_select_all (EAttachmentView *view); -void e_attachment_view_unselect_all (EAttachmentView *view); -void e_attachment_view_sync_selection - (EAttachmentView *view, - EAttachmentView *target); - -/* Drag Source Support */ -void e_attachment_view_drag_source_set - (EAttachmentView *view); -void e_attachment_view_drag_source_unset - (EAttachmentView *view); -void e_attachment_view_drag_begin (EAttachmentView *view, - GdkDragContext *context); -void e_attachment_view_drag_end (EAttachmentView *view, - GdkDragContext *context); -void e_attachment_view_drag_data_get (EAttachmentView *view, - GdkDragContext *context, - GtkSelectionData *selection, - guint info, - guint time); - -/* Drag Destination Support */ -void e_attachment_view_drag_dest_set (EAttachmentView *view); -void e_attachment_view_drag_dest_unset - (EAttachmentView *view); -gboolean e_attachment_view_drag_motion (EAttachmentView *view, - GdkDragContext *context, - gint x, - gint y, - guint time); -gboolean e_attachment_view_drag_drop (EAttachmentView *view, - GdkDragContext *context, - gint x, - gint y, - guint time); -void e_attachment_view_drag_data_received - (EAttachmentView *view, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time); - -/* Popup Menu Management */ -GtkAction * e_attachment_view_get_action (EAttachmentView *view, - const gchar *action_name); -GtkActionGroup *e_attachment_view_add_action_group - (EAttachmentView *view, - const gchar *group_name); -GtkActionGroup *e_attachment_view_get_action_group - (EAttachmentView *view, - const gchar *group_name); -GtkWidget * e_attachment_view_get_popup_menu - (EAttachmentView *view); -GtkUIManager * e_attachment_view_get_ui_manager - (EAttachmentView *view); -void e_attachment_view_show_popup_menu - (EAttachmentView *view, - GdkEventButton *event, - GtkMenuPositionFunc func, - gpointer user_data); -void e_attachment_view_update_actions - (EAttachmentView *view); - -G_END_DECLS - -#endif /* E_ATTACHMENT_VIEW_H */ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c deleted file mode 100644 index 4ebaef3747..0000000000 --- a/widgets/misc/e-attachment.c +++ /dev/null @@ -1,2883 +0,0 @@ -/* - * e-attachment.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-attachment.h" - -#include <errno.h> -#include <glib/gi18n.h> -#include <glib/gstdio.h> - -#include <libedataserver/libedataserver.h> - -#include "e-util/e-icon-factory.h" -#include "e-util/e-util.h" -#include "e-util/e-mktemp.h" -#include "e-attachment-store.h" - -#define E_ATTACHMENT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) - -/* Fallback Icon */ -#define DEFAULT_ICON_NAME "mail-attachment" - -/* Emblems */ -#define EMBLEM_CANCELLED "gtk-cancel" -#define EMBLEM_LOADING "emblem-downloads" -#define EMBLEM_SAVING "document-save" -#define EMBLEM_ENCRYPT_WEAK "security-low" -#define EMBLEM_ENCRYPT_STRONG "security-high" -#define EMBLEM_ENCRYPT_UNKNOWN "security-medium" -#define EMBLEM_SIGN_BAD "stock_signature-bad" -#define EMBLEM_SIGN_GOOD "stock_signature-ok" -#define EMBLEM_SIGN_UNKNOWN "stock_signature" - -/* Attributes needed for EAttachmentStore columns. */ -#define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*" - -struct _EAttachmentPrivate { - GFile *file; - GIcon *icon; - GFileInfo *file_info; - GCancellable *cancellable; - CamelMimePart *mime_part; - guint emblem_timeout_id; - gchar *disposition; - gint percent; - gint64 last_percent_notify; /* to avoid excessive notifications */ - - guint can_show : 1; - guint loading : 1; - guint saving : 1; - guint shown : 1; - - camel_cipher_validity_encrypt_t encrypted; - camel_cipher_validity_sign_t signed_; - - /* This is a reference to our row in an EAttachmentStore, - * serving as a means of broadcasting "row-changed" signals. - * If we are removed from the store, we lazily free the - * reference when it is found to be to be invalid. */ - GtkTreeRowReference *reference; -}; - -enum { - PROP_0, - PROP_CAN_SHOW, - PROP_DISPOSITION, - PROP_ENCRYPTED, - PROP_FILE, - PROP_FILE_INFO, - PROP_ICON, - PROP_LOADING, - PROP_MIME_PART, - PROP_PERCENT, - PROP_REFERENCE, - PROP_SAVING, - PROP_SHOWN, - PROP_SIGNED -}; - -G_DEFINE_TYPE ( - EAttachment, - e_attachment, - G_TYPE_OBJECT) - -static gboolean -create_system_thumbnail (EAttachment *attachment, - GIcon **icon) -{ - GFile *file; - GFile *icon_file; - gchar *thumbnail = NULL; - - g_return_val_if_fail (attachment != NULL, FALSE); - g_return_val_if_fail (icon != NULL, FALSE); - - file = e_attachment_get_file (attachment); - - if (file && g_file_has_uri_scheme (file, "file")) { - gchar *path = g_file_get_path (file); - if (path) { - thumbnail = e_icon_factory_create_thumbnail (path); - g_free (path); - } - } - - if (thumbnail == NULL) - return FALSE; - - icon_file = g_file_new_for_path (thumbnail); - - if (*icon) - g_object_unref (*icon); - - *icon = g_file_icon_new (icon_file); - - g_object_unref (icon_file); - - if (file) { - GFileInfo *file_info; - const gchar *attribute; - - file_info = e_attachment_get_file_info (attachment); - attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH; - - if (file_info != NULL) - g_file_info_set_attribute_byte_string ( - file_info, attribute, thumbnail); - } - - g_free (thumbnail); - - return TRUE; -} - -static gchar * -attachment_get_default_charset (void) -{ - GSettings *settings; - gchar *charset; - - /* XXX This doesn't really belong here. */ - - settings = g_settings_new ("org.gnome.evolution.mail"); - charset = g_settings_get_string (settings, "composer-charset"); - if (charset == NULL || *charset == '\0') { - g_free (charset); - /* FIXME This was "/apps/evolution/mail/format/charset", - * not sure it relates to "charset" */ - charset = g_settings_get_string (settings, "charset"); - if (charset == NULL || *charset == '\0') { - g_free (charset); - charset = NULL; - } - } - g_object_unref (settings); - - if (charset == NULL) - charset = g_strdup (camel_iconv_locale_charset ()); - - if (charset == NULL) - charset = g_strdup ("us-ascii"); - - return charset; -} - -static void -attachment_update_file_info_columns (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - GFileInfo *file_info; - const gchar *content_type; - const gchar *description; - const gchar *display_name; - gchar *content_desc; - gchar *display_size; - gchar *caption; - goffset size; - - reference = e_attachment_get_reference (attachment); - if (!gtk_tree_row_reference_valid (reference)) - return; - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - return; - - 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); - - content_type = g_file_info_get_content_type (file_info); - display_name = g_file_info_get_display_name (file_info); - size = g_file_info_get_size (file_info); - - content_desc = g_content_type_get_description (content_type); - display_size = g_format_size (size); - - description = e_attachment_get_description (attachment); - if (description == NULL || *description == '\0') - description = display_name; - - if (size > 0) - caption = g_strdup_printf ( - "%s\n(%s)", description, display_size); - else - caption = g_strdup (description); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_desc, - E_ATTACHMENT_STORE_COLUMN_DESCRIPTION, description, - E_ATTACHMENT_STORE_COLUMN_SIZE, size, - -1); - - g_free (content_desc); - g_free (display_size); - g_free (caption); -} - -static void -attachment_update_icon_column (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - GFileInfo *file_info; - GCancellable *cancellable; - GIcon *icon = NULL; - const gchar *emblem_name = NULL; - const gchar *thumbnail_path = NULL; - - reference = e_attachment_get_reference (attachment); - if (!gtk_tree_row_reference_valid (reference)) - return; - - 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); - - cancellable = attachment->priv->cancellable; - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) { - icon = g_file_info_get_icon (file_info); - thumbnail_path = g_file_info_get_attribute_byte_string ( - file_info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); - } - - /* Prefer the thumbnail if we have one. */ - if (thumbnail_path != NULL && *thumbnail_path != '\0') { - GFile *file; - - file = g_file_new_for_path (thumbnail_path); - icon = g_file_icon_new (file); - g_object_unref (file); - - /* Try the system thumbnailer. */ - } else if (create_system_thumbnail (attachment, &icon)) { - /* Nothing to do, just use the icon. */ - - /* Else use the standard icon for the content type. */ - } else if (icon != NULL) - g_object_ref (icon); - - /* Last ditch fallback. (GFileInfo not yet loaded?) */ - else - icon = g_themed_icon_new (DEFAULT_ICON_NAME); - - /* Pick an emblem, limit one. Choices listed by priority. */ - - if (g_cancellable_is_cancelled (cancellable)) - emblem_name = EMBLEM_CANCELLED; - - else if (e_attachment_get_loading (attachment)) - emblem_name = EMBLEM_LOADING; - - else if (e_attachment_get_saving (attachment)) - emblem_name = EMBLEM_SAVING; - - else if (e_attachment_get_encrypted (attachment)) - switch (e_attachment_get_encrypted (attachment)) { - case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK: - emblem_name = EMBLEM_ENCRYPT_WEAK; - break; - - case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED: - emblem_name = EMBLEM_ENCRYPT_UNKNOWN; - break; - - case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG: - emblem_name = EMBLEM_ENCRYPT_STRONG; - break; - - default: - g_warn_if_reached (); - break; - } - - else if (e_attachment_get_signed (attachment)) - switch (e_attachment_get_signed (attachment)) { - case CAMEL_CIPHER_VALIDITY_SIGN_GOOD: - emblem_name = EMBLEM_SIGN_GOOD; - break; - - case CAMEL_CIPHER_VALIDITY_SIGN_BAD: - emblem_name = EMBLEM_SIGN_BAD; - break; - - case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN: - case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY: - emblem_name = EMBLEM_SIGN_UNKNOWN; - break; - - default: - g_warn_if_reached (); - break; - } - - if (emblem_name != NULL) { - GIcon *emblemed_icon; - GEmblem *emblem; - - emblemed_icon = g_themed_icon_new (emblem_name); - emblem = g_emblem_new (emblemed_icon); - g_object_unref (emblemed_icon); - - emblemed_icon = g_emblemed_icon_new (icon, emblem); - g_object_unref (emblem); - g_object_unref (icon); - - icon = emblemed_icon; - } - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - E_ATTACHMENT_STORE_COLUMN_ICON, icon, - -1); - - /* Cache the icon to reuse for things like drag-n-drop. */ - if (attachment->priv->icon != NULL) - g_object_unref (attachment->priv->icon); - attachment->priv->icon = icon; - g_object_notify (G_OBJECT (attachment), "icon"); -} - -static void -attachment_update_progress_columns (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean loading; - gboolean saving; - gint percent; - - reference = e_attachment_get_reference (attachment); - if (!gtk_tree_row_reference_valid (reference)) - return; - - 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); - - /* Don't show progress bars until we have progress to report. */ - percent = e_attachment_get_percent (attachment); - loading = e_attachment_get_loading (attachment) && (percent > 0); - saving = e_attachment_get_saving (attachment) && (percent > 0); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - E_ATTACHMENT_STORE_COLUMN_LOADING, loading, - E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, - E_ATTACHMENT_STORE_COLUMN_SAVING, saving, - -1); -} - -static void -attachment_set_loading (EAttachment *attachment, - gboolean loading) -{ - GtkTreeRowReference *reference; - - reference = e_attachment_get_reference (attachment); - - attachment->priv->percent = 0; - attachment->priv->loading = loading; - attachment->priv->last_percent_notify = 0; - - g_object_freeze_notify (G_OBJECT (attachment)); - g_object_notify (G_OBJECT (attachment), "percent"); - g_object_notify (G_OBJECT (attachment), "loading"); - g_object_thaw_notify (G_OBJECT (attachment)); - - if (gtk_tree_row_reference_valid (reference)) { - GtkTreeModel *model; - model = gtk_tree_row_reference_get_model (reference); - g_object_notify (G_OBJECT (model), "num-loading"); - } -} - -static void -attachment_set_saving (EAttachment *attachment, - gboolean saving) -{ - attachment->priv->percent = 0; - attachment->priv->saving = saving; - attachment->priv->last_percent_notify = 0; - - g_object_freeze_notify (G_OBJECT (attachment)); - g_object_notify (G_OBJECT (attachment), "percent"); - g_object_notify (G_OBJECT (attachment), "saving"); - g_object_thaw_notify (G_OBJECT (attachment)); -} - -static void -attachment_progress_cb (goffset current_num_bytes, - goffset total_num_bytes, - EAttachment *attachment) -{ - gint new_percent; - - /* Avoid dividing by zero. */ - if (total_num_bytes == 0) - return; - - /* do not notify too often, 5 times per second is sufficient */ - if (g_get_monotonic_time () - attachment->priv->last_percent_notify < 200000) - return; - - attachment->priv->last_percent_notify = g_get_monotonic_time (); - - new_percent = (current_num_bytes * 100) / total_num_bytes; - - if (new_percent != attachment->priv->percent) { - attachment->priv->percent = new_percent; - g_object_notify (G_OBJECT (attachment), "percent"); - } -} - -static gboolean -attachment_cancelled_timeout_cb (EAttachment *attachment) -{ - attachment->priv->emblem_timeout_id = 0; - g_cancellable_reset (attachment->priv->cancellable); - - attachment_update_icon_column (attachment); - - return FALSE; -} - -static void -attachment_cancelled_cb (EAttachment *attachment) -{ - /* Reset the GCancellable after one second. This causes a - * cancel emblem to be briefly shown on the attachment icon - * as visual feedback that an operation was cancelled. */ - - if (attachment->priv->emblem_timeout_id > 0) - g_source_remove (attachment->priv->emblem_timeout_id); - - attachment->priv->emblem_timeout_id = g_timeout_add_seconds ( - 1, (GSourceFunc) attachment_cancelled_timeout_cb, attachment); - - attachment_update_icon_column (attachment); -} - -static void -attachment_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CAN_SHOW: - e_attachment_set_can_show ( - E_ATTACHMENT (object), - g_value_get_boolean (value)); - return; - - case PROP_DISPOSITION: - e_attachment_set_disposition ( - E_ATTACHMENT (object), - g_value_get_string (value)); - return; - - case PROP_ENCRYPTED: - e_attachment_set_encrypted ( - E_ATTACHMENT (object), - g_value_get_int (value)); - return; - - case PROP_FILE: - e_attachment_set_file ( - E_ATTACHMENT (object), - g_value_get_object (value)); - return; - - case PROP_SHOWN: - e_attachment_set_shown ( - E_ATTACHMENT (object), - g_value_get_boolean (value)); - return; - - case PROP_MIME_PART: - e_attachment_set_mime_part ( - E_ATTACHMENT (object), - g_value_get_boxed (value)); - return; - - case PROP_REFERENCE: - e_attachment_set_reference ( - E_ATTACHMENT (object), - g_value_get_boxed (value)); - return; - - case PROP_SIGNED: - e_attachment_set_signed ( - E_ATTACHMENT (object), - g_value_get_int (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CAN_SHOW: - g_value_set_boolean ( - value, e_attachment_get_can_show ( - E_ATTACHMENT (object))); - return; - - case PROP_DISPOSITION: - g_value_set_string ( - value, e_attachment_get_disposition ( - E_ATTACHMENT (object))); - return; - - case PROP_ENCRYPTED: - g_value_set_int ( - value, e_attachment_get_encrypted ( - E_ATTACHMENT (object))); - return; - - case PROP_FILE: - g_value_set_object ( - value, e_attachment_get_file ( - E_ATTACHMENT (object))); - return; - - case PROP_FILE_INFO: - g_value_set_object ( - value, e_attachment_get_file_info ( - E_ATTACHMENT (object))); - return; - - case PROP_ICON: - g_value_set_object ( - value, e_attachment_get_icon ( - E_ATTACHMENT (object))); - return; - - case PROP_SHOWN: - g_value_set_boolean ( - value, e_attachment_get_shown ( - E_ATTACHMENT (object))); - return; - - case PROP_LOADING: - g_value_set_boolean ( - value, e_attachment_get_loading ( - E_ATTACHMENT (object))); - return; - - case PROP_MIME_PART: - g_value_set_boxed ( - value, e_attachment_get_mime_part ( - E_ATTACHMENT (object))); - return; - - case PROP_PERCENT: - g_value_set_int ( - value, e_attachment_get_percent ( - E_ATTACHMENT (object))); - return; - - case PROP_REFERENCE: - g_value_set_boxed ( - value, e_attachment_get_reference ( - E_ATTACHMENT (object))); - return; - - case PROP_SAVING: - g_value_set_boolean ( - value, e_attachment_get_saving ( - E_ATTACHMENT (object))); - return; - - case PROP_SIGNED: - g_value_set_int ( - value, e_attachment_get_signed ( - E_ATTACHMENT (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_dispose (GObject *object) -{ - EAttachmentPrivate *priv; - - priv = E_ATTACHMENT_GET_PRIVATE (object); - - if (priv->file != NULL) { - g_object_unref (priv->file); - priv->file = NULL; - } - - if (priv->icon != NULL) { - g_object_unref (priv->icon); - priv->icon = NULL; - } - - if (priv->file_info != NULL) { - g_object_unref (priv->file_info); - priv->file_info = NULL; - } - - if (priv->cancellable != NULL) { - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - if (priv->mime_part != NULL) { - g_object_unref (priv->mime_part); - priv->mime_part = NULL; - } - - if (priv->emblem_timeout_id > 0) { - g_source_remove (priv->emblem_timeout_id); - priv->emblem_timeout_id = 0; - } - - /* This accepts NULL arguments. */ - gtk_tree_row_reference_free (priv->reference); - priv->reference = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_attachment_parent_class)->dispose (object); -} - -static void -attachment_finalize (GObject *object) -{ - EAttachmentPrivate *priv; - - priv = E_ATTACHMENT_GET_PRIVATE (object); - - g_free (priv->disposition); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_attachment_parent_class)->finalize (object); -} - -static void -e_attachment_class_init (EAttachmentClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAttachmentPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_set_property; - object_class->get_property = attachment_get_property; - object_class->dispose = attachment_dispose; - object_class->finalize = attachment_finalize; - - g_object_class_install_property ( - object_class, - PROP_CAN_SHOW, - g_param_spec_boolean ( - "can-show", - "Can Show", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_DISPOSITION, - g_param_spec_string ( - "disposition", - "Disposition", - NULL, - "attachment", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - /* FIXME Define a GEnumClass for this. */ - g_object_class_install_property ( - object_class, - PROP_ENCRYPTED, - g_param_spec_int ( - "encrypted", - "Encrypted", - NULL, - CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE, - CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG, - CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_FILE, - g_param_spec_object ( - "file", - "File", - NULL, - G_TYPE_FILE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_FILE_INFO, - g_param_spec_object ( - "file-info", - "File Info", - NULL, - G_TYPE_FILE_INFO, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_ICON, - g_param_spec_object ( - "icon", - "Icon", - NULL, - G_TYPE_ICON, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_LOADING, - g_param_spec_boolean ( - "loading", - "Loading", - NULL, - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_MIME_PART, - g_param_spec_object ( - "mime-part", - "MIME Part", - NULL, - CAMEL_TYPE_MIME_PART, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_PERCENT, - g_param_spec_int ( - "percent", - "Percent", - NULL, - 0, - 100, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_REFERENCE, - g_param_spec_boxed ( - "reference", - "Reference", - NULL, - GTK_TYPE_TREE_ROW_REFERENCE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SAVING, - g_param_spec_boolean ( - "saving", - "Saving", - NULL, - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_SHOWN, - g_param_spec_boolean ( - "shown", - "Shown", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - /* FIXME Define a GEnumClass for this. */ - g_object_class_install_property ( - object_class, - PROP_SIGNED, - g_param_spec_int ( - "signed", - "Signed", - NULL, - CAMEL_CIPHER_VALIDITY_SIGN_NONE, - CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY, - CAMEL_CIPHER_VALIDITY_SIGN_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_attachment_init (EAttachment *attachment) -{ - attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment); - attachment->priv->cancellable = g_cancellable_new (); - attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; - attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE; - - g_signal_connect ( - attachment, "notify::encrypted", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect ( - attachment, "notify::file-info", - G_CALLBACK (attachment_update_file_info_columns), NULL); - - g_signal_connect ( - attachment, "notify::file-info", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect ( - attachment, "notify::loading", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect ( - attachment, "notify::loading", - G_CALLBACK (attachment_update_progress_columns), NULL); - - g_signal_connect ( - attachment, "notify::percent", - G_CALLBACK (attachment_update_progress_columns), NULL); - - g_signal_connect ( - attachment, "notify::reference", - G_CALLBACK (attachment_update_file_info_columns), NULL); - - g_signal_connect ( - attachment, "notify::reference", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect ( - attachment, "notify::reference", - G_CALLBACK (attachment_update_progress_columns), NULL); - - g_signal_connect ( - attachment, "notify::saving", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect ( - attachment, "notify::saving", - G_CALLBACK (attachment_update_progress_columns), NULL); - - g_signal_connect ( - attachment, "notify::signed", - G_CALLBACK (attachment_update_icon_column), NULL); - - g_signal_connect_swapped ( - attachment->priv->cancellable, "cancelled", - G_CALLBACK (attachment_cancelled_cb), attachment); -} - -EAttachment * -e_attachment_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT, NULL); -} - -EAttachment * -e_attachment_new_for_path (const gchar *path) -{ - EAttachment *attachment; - GFile *file; - - g_return_val_if_fail (path != NULL, NULL); - - file = g_file_new_for_path (path); - attachment = g_object_new (E_TYPE_ATTACHMENT, "file", file, NULL); - g_object_unref (file); - - return attachment; -} - -EAttachment * -e_attachment_new_for_uri (const gchar *uri) -{ - EAttachment *attachment; - GFile *file; - - g_return_val_if_fail (uri != NULL, NULL); - - file = g_file_new_for_uri (uri); - attachment = g_object_new (E_TYPE_ATTACHMENT, "file", file, NULL); - g_object_unref (file); - - return attachment; -} - -EAttachment * -e_attachment_new_for_message (CamelMimeMessage *message) -{ - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - EAttachment *attachment; - GString *description; - const gchar *subject; - - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - - mime_part = camel_mime_part_new (); - camel_mime_part_set_disposition (mime_part, "inline"); - subject = camel_mime_message_get_subject (message); - - /* To Translators: This text is set as a description of an attached - * message when, for example, attaching it to a composer. When the - * message to be attached has also filled Subject, then this text is - * of form "Attached message - Subject", otherwise it's left as is. */ - description = g_string_new (_("Attached message")); - if (subject != NULL) - g_string_append_printf (description, " - %s", subject); - camel_mime_part_set_description (mime_part, description->str); - g_string_free (description, TRUE); - - wrapper = CAMEL_DATA_WRAPPER (message); - camel_medium_set_content (CAMEL_MEDIUM (mime_part), wrapper); - camel_mime_part_set_content_type (mime_part, "message/rfc822"); - - attachment = e_attachment_new (); - e_attachment_set_mime_part (attachment, mime_part); - g_object_unref (mime_part); - - return attachment; -} - -void -e_attachment_add_to_multipart (EAttachment *attachment, - CamelMultipart *multipart, - const gchar *default_charset) -{ - CamelContentType *content_type; - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - - /* XXX EMsgComposer might be a better place for this function. */ - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (CAMEL_IS_MULTIPART (multipart)); - - /* Still loading? Too bad. */ - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part == NULL) - return; - - content_type = camel_mime_part_get_content_type (mime_part); - wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - - if (CAMEL_IS_MULTIPART (wrapper)) - goto exit; - - /* For text content, determine the best encoding and character set. */ - if (camel_content_type_is (content_type, "text", "*")) { - CamelTransferEncoding encoding; - CamelStream *filtered_stream; - CamelMimeFilter *filter; - CamelStream *stream; - const gchar *charset; - - charset = camel_content_type_param (content_type, "charset"); - - /* Determine the best encoding by writing the MIME - * part to a NULL stream with a "bestenc" filter. */ - stream = camel_stream_null_new (); - filtered_stream = camel_stream_filter_new (stream); - filter = camel_mime_filter_bestenc_new ( - CAMEL_BESTENC_GET_ENCODING); - camel_stream_filter_add ( - CAMEL_STREAM_FILTER (filtered_stream), - CAMEL_MIME_FILTER (filter)); - camel_data_wrapper_decode_to_stream_sync ( - wrapper, filtered_stream, NULL, NULL); - g_object_unref (filtered_stream); - g_object_unref (stream); - - /* Retrieve the best encoding from the filter. */ - encoding = camel_mime_filter_bestenc_get_best_encoding ( - CAMEL_MIME_FILTER_BESTENC (filter), - CAMEL_BESTENC_8BIT); - camel_mime_part_set_encoding (mime_part, encoding); - g_object_unref (filter); - - if (encoding == CAMEL_TRANSFER_ENCODING_7BIT) { - /* The text fits within us-ascii, so this is safe. - * FIXME Check that this isn't iso-2022-jp? */ - default_charset = "us-ascii"; - - } else if (charset == NULL && default_charset == NULL) { - default_charset = attachment_get_default_charset (); - /* FIXME Check that this fits within the - * default_charset and if not, find one - * that does and/or allow the user to - * specify. */ - } - - if (charset == NULL) { - gchar *type; - - camel_content_type_set_param ( - content_type, "charset", default_charset); - type = camel_content_type_format (content_type); - camel_mime_part_set_content_type (mime_part, type); - g_free (type); - } - - /* Otherwise, unless it's a message/rfc822, Base64 encode it. */ - } else if (!CAMEL_IS_MIME_MESSAGE (wrapper)) - camel_mime_part_set_encoding ( - mime_part, CAMEL_TRANSFER_ENCODING_BASE64); - -exit: - camel_multipart_add_part (multipart, mime_part); -} - -void -e_attachment_cancel (EAttachment *attachment) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - g_cancellable_cancel (attachment->priv->cancellable); -} - -gboolean -e_attachment_get_can_show (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->can_show; -} - -void -e_attachment_set_can_show (EAttachment *attachment, - gboolean can_show) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - attachment->priv->can_show = can_show; - - g_object_notify (G_OBJECT (attachment), "can-show"); -} - -const gchar * -e_attachment_get_disposition (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->disposition; -} - -void -e_attachment_set_disposition (EAttachment *attachment, - const gchar *disposition) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - g_free (attachment->priv->disposition); - attachment->priv->disposition = g_strdup (disposition); - - g_object_notify (G_OBJECT (attachment), "disposition"); -} - -GFile * -e_attachment_get_file (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->file; -} - -void -e_attachment_set_file (EAttachment *attachment, - GFile *file) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - if (file != NULL) { - g_return_if_fail (G_IS_FILE (file)); - g_object_ref (file); - } - - if (attachment->priv->file != NULL) - g_object_unref (attachment->priv->file); - - attachment->priv->file = file; - - g_object_notify (G_OBJECT (attachment), "file"); -} - -GFileInfo * -e_attachment_get_file_info (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->file_info; -} - -void -e_attachment_set_file_info (EAttachment *attachment, - GFileInfo *file_info) -{ - GtkTreeRowReference *reference; - GIcon *icon; - - reference = e_attachment_get_reference (attachment); - - if (file_info != NULL) - g_object_ref (file_info); - - if (attachment->priv->file_info != NULL) - g_object_unref (attachment->priv->file_info); - - attachment->priv->file_info = file_info; - - /* If the GFileInfo contains a GThemedIcon, append a - * fallback icon name to ensure we display something. */ - icon = g_file_info_get_icon (file_info); - if (G_IS_THEMED_ICON (icon)) - g_themed_icon_append_name ( - G_THEMED_ICON (icon), DEFAULT_ICON_NAME); - - g_object_notify (G_OBJECT (attachment), "file-info"); - - /* Tell the EAttachmentStore its total size changed. */ - if (gtk_tree_row_reference_valid (reference)) { - GtkTreeModel *model; - model = gtk_tree_row_reference_get_model (reference); - g_object_notify (G_OBJECT (model), "total-size"); - } -} - -/** - * e_attachment_get_mime_type: - * - * Returns mime_type part of the file_info as a newly allocated string, - * which should be freed with g_free(). - * Returns NULL, if mime_type not found or set on the attachment. - **/ -gchar * -e_attachment_get_mime_type (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *content_type; - gchar *mime_type; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - return NULL; - - content_type = g_file_info_get_content_type (file_info); - if (content_type == NULL) - return NULL; - - mime_type = g_content_type_get_mime_type (content_type); - if (!mime_type) - return NULL; - - camel_strdown (mime_type); - - return mime_type; -} - -GIcon * -e_attachment_get_icon (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->icon; -} - -gboolean -e_attachment_get_loading (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->loading; -} - -CamelMimePart * -e_attachment_get_mime_part (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->mime_part; -} - -void -e_attachment_set_mime_part (EAttachment *attachment, - CamelMimePart *mime_part) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - if (mime_part != NULL) { - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - g_object_ref (mime_part); - } - - if (attachment->priv->mime_part != NULL) - g_object_unref (attachment->priv->mime_part); - - attachment->priv->mime_part = mime_part; - - g_object_notify (G_OBJECT (attachment), "mime-part"); -} - -gint -e_attachment_get_percent (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), 0); - - return attachment->priv->percent; -} - -GtkTreeRowReference * -e_attachment_get_reference (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - return attachment->priv->reference; -} - -void -e_attachment_set_reference (EAttachment *attachment, - GtkTreeRowReference *reference) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - if (reference != NULL) - reference = gtk_tree_row_reference_copy (reference); - - gtk_tree_row_reference_free (attachment->priv->reference); - attachment->priv->reference = reference; - - g_object_notify (G_OBJECT (attachment), "reference"); -} - -gboolean -e_attachment_get_saving (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->saving; -} - -gboolean -e_attachment_get_shown (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->shown; -} - -void -e_attachment_set_shown (EAttachment *attachment, - gboolean shown) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - attachment->priv->shown = shown; - - g_object_notify (G_OBJECT (attachment), "shown"); -} - -camel_cipher_validity_encrypt_t -e_attachment_get_encrypted (EAttachment *attachment) -{ - g_return_val_if_fail ( - E_IS_ATTACHMENT (attachment), - CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE); - - return attachment->priv->encrypted; -} - -void -e_attachment_set_encrypted (EAttachment *attachment, - camel_cipher_validity_encrypt_t encrypted) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - attachment->priv->encrypted = encrypted; - - g_object_notify (G_OBJECT (attachment), "encrypted"); -} - -camel_cipher_validity_sign_t -e_attachment_get_signed (EAttachment *attachment) -{ - g_return_val_if_fail ( - E_IS_ATTACHMENT (attachment), - CAMEL_CIPHER_VALIDITY_SIGN_NONE); - - return attachment->priv->signed_; -} - -void -e_attachment_set_signed (EAttachment *attachment, - camel_cipher_validity_sign_t signed_) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - attachment->priv->signed_ = signed_; - - g_object_notify (G_OBJECT (attachment), "signed"); -} - -const gchar * -e_attachment_get_description (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return NULL; - - return g_file_info_get_attribute_string (file_info, attribute); -} - -const gchar * -e_attachment_get_thumbnail_path (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return NULL; - - return g_file_info_get_attribute_byte_string (file_info, attribute); -} - -gboolean -e_attachment_is_rfc822 (EAttachment *attachment) -{ - gchar *mime_type; - gboolean is_rfc822; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - mime_type = e_attachment_get_mime_type (attachment); - is_rfc822 = mime_type && g_ascii_strcasecmp (mime_type, "message/rfc822") == 0; - g_free (mime_type); - - return is_rfc822; -} - -GList * -e_attachment_list_apps (EAttachment *attachment) -{ - GList *app_info_list; - GList *guessed_infos; - GFileInfo *file_info; - const gchar *content_type; - const gchar *display_name; - gboolean type_is_unknown; - gchar *allocated; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - return NULL; - - content_type = g_file_info_get_content_type (file_info); - display_name = g_file_info_get_display_name (file_info); - g_return_val_if_fail (content_type != NULL, NULL); - - app_info_list = g_app_info_get_all_for_type (content_type); - type_is_unknown = g_content_type_is_unknown (content_type); - - if (app_info_list != NULL && !type_is_unknown) - goto exit; - - if (display_name == NULL) - goto exit; - - allocated = g_content_type_guess (display_name, NULL, 0, NULL); - guessed_infos = g_app_info_get_all_for_type (allocated); - app_info_list = g_list_concat (guessed_infos, app_info_list); - g_free (allocated); - -exit: - return app_info_list; -} - -/************************* e_attachment_load_async() *************************/ - -typedef struct _LoadContext LoadContext; - -struct _LoadContext { - EAttachment *attachment; - CamelMimePart *mime_part; - GSimpleAsyncResult *simple; - - GInputStream *input_stream; - GOutputStream *output_stream; - GFileInfo *file_info; - goffset total_num_bytes; - gssize bytes_read; - gchar buffer[4096]; -}; - -/* Forward Declaration */ -static void -attachment_load_stream_read_cb (GInputStream *input_stream, - GAsyncResult *result, - LoadContext *load_context); - -static LoadContext * -attachment_load_context_new (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data) -{ - LoadContext *load_context; - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new ( - G_OBJECT (attachment), callback, - user_data, e_attachment_load_async); - - load_context = g_slice_new0 (LoadContext); - load_context->attachment = g_object_ref (attachment); - load_context->simple = simple; - - attachment_set_loading (load_context->attachment, TRUE); - - return load_context; -} - -static void -attachment_load_context_free (LoadContext *load_context) -{ - g_object_unref (load_context->attachment); - - if (load_context->mime_part != NULL) - g_object_unref (load_context->mime_part); - - if (load_context->simple) - g_object_unref (load_context->simple); - - if (load_context->input_stream != NULL) - g_object_unref (load_context->input_stream); - - if (load_context->output_stream != NULL) - g_object_unref (load_context->output_stream); - - if (load_context->file_info != NULL) - g_object_unref (load_context->file_info); - - g_slice_free (LoadContext, load_context); -} - -static gboolean -attachment_load_check_for_error (LoadContext *load_context, - GError *error) -{ - GSimpleAsyncResult *simple; - - if (error == NULL) - return FALSE; - - simple = load_context->simple; - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - - attachment_load_context_free (load_context); - - return TRUE; -} - -static void -attachment_load_finish (LoadContext *load_context) -{ - GFileInfo *file_info; - EAttachment *attachment; - GMemoryOutputStream *output_stream; - GSimpleAsyncResult *simple; - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - CamelStream *stream; - const gchar *attribute; - const gchar *content_type; - const gchar *display_name; - const gchar *description; - const gchar *disposition; - gchar *mime_type; - gpointer data; - gsize size; - - simple = load_context->simple; - - file_info = load_context->file_info; - attachment = load_context->attachment; - output_stream = G_MEMORY_OUTPUT_STREAM (load_context->output_stream); - - if (e_attachment_is_rfc822 (attachment)) - wrapper = (CamelDataWrapper *) camel_mime_message_new (); - else - wrapper = camel_data_wrapper_new (); - - content_type = g_file_info_get_content_type (file_info); - mime_type = g_content_type_get_mime_type (content_type); - - data = g_memory_output_stream_get_data (output_stream); - size = g_memory_output_stream_get_data_size (output_stream); - - stream = camel_stream_mem_new_with_buffer (data, size); - camel_data_wrapper_construct_from_stream_sync ( - wrapper, stream, NULL, NULL); - camel_data_wrapper_set_mime_type (wrapper, mime_type); - camel_stream_close (stream, NULL, NULL); - g_object_unref (stream); - - mime_part = camel_mime_part_new (); - camel_medium_set_content (CAMEL_MEDIUM (mime_part), wrapper); - - g_object_unref (wrapper); - g_free (mime_type); - - display_name = g_file_info_get_display_name (file_info); - if (display_name != NULL) - camel_mime_part_set_filename (mime_part, display_name); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - description = g_file_info_get_attribute_string (file_info, attribute); - if (description != NULL) - camel_mime_part_set_description (mime_part, description); - - disposition = e_attachment_get_disposition (attachment); - if (disposition != NULL) - camel_mime_part_set_disposition (mime_part, disposition); - - /* Correctly report the size of zero length special files. */ - if (g_file_info_get_size (file_info) == 0) - g_file_info_set_size (file_info, size); - - load_context->mime_part = mime_part; - - g_simple_async_result_set_op_res_gpointer ( - simple, load_context, (GDestroyNotify) attachment_load_context_free); - - g_simple_async_result_complete (simple); - - /* make sure it's freed on operation end */ - load_context->simple = NULL; - g_object_unref (simple); -} - -static void -attachment_load_write_cb (GOutputStream *output_stream, - GAsyncResult *result, - LoadContext *load_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GInputStream *input_stream; - gssize bytes_written; - GError *error = NULL; - - bytes_written = g_output_stream_write_finish ( - output_stream, result, &error); - - if (attachment_load_check_for_error (load_context, error)) - return; - - attachment = load_context->attachment; - cancellable = attachment->priv->cancellable; - input_stream = load_context->input_stream; - - attachment_progress_cb ( - g_seekable_tell (G_SEEKABLE (output_stream)), - load_context->total_num_bytes, attachment); - - if (bytes_written < load_context->bytes_read) { - g_memmove ( - load_context->buffer, - load_context->buffer + bytes_written, - load_context->bytes_read - bytes_written); - load_context->bytes_read -= bytes_written; - - g_output_stream_write_async ( - output_stream, - load_context->buffer, - load_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_load_write_cb, - load_context); - } else - g_input_stream_read_async ( - input_stream, - load_context->buffer, - sizeof (load_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_load_stream_read_cb, - load_context); -} - -static void -attachment_load_stream_read_cb (GInputStream *input_stream, - GAsyncResult *result, - LoadContext *load_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GOutputStream *output_stream; - gssize bytes_read; - GError *error = NULL; - - bytes_read = g_input_stream_read_finish ( - input_stream, result, &error); - - if (attachment_load_check_for_error (load_context, error)) - return; - - if (bytes_read == 0) { - attachment_load_finish (load_context); - return; - } - - attachment = load_context->attachment; - cancellable = attachment->priv->cancellable; - output_stream = load_context->output_stream; - load_context->bytes_read = bytes_read; - - g_output_stream_write_async ( - output_stream, - load_context->buffer, - load_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_load_write_cb, - load_context); -} - -static void -attachment_load_file_read_cb (GFile *file, - GAsyncResult *result, - LoadContext *load_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileInputStream *input_stream; - GOutputStream *output_stream; - GError *error = NULL; - - /* Input stream might be NULL, so don't use cast macro. */ - input_stream = g_file_read_finish (file, result, &error); - load_context->input_stream = (GInputStream *) input_stream; - - if (attachment_load_check_for_error (load_context, error)) - return; - - /* Load the contents into a GMemoryOutputStream. */ - output_stream = g_memory_output_stream_new ( - NULL, 0, g_realloc, g_free); - - attachment = load_context->attachment; - cancellable = attachment->priv->cancellable; - load_context->output_stream = output_stream; - - g_input_stream_read_async ( - load_context->input_stream, - load_context->buffer, - sizeof (load_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_load_stream_read_cb, - load_context); -} - -static void -attachment_load_query_info_cb (GFile *file, - GAsyncResult *result, - LoadContext *load_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileInfo *file_info; - GError *error = NULL; - - attachment = load_context->attachment; - cancellable = attachment->priv->cancellable; - - file_info = g_file_query_info_finish (file, result, &error); - if (attachment_load_check_for_error (load_context, error)) - return; - - e_attachment_set_file_info (attachment, file_info); - load_context->file_info = file_info; - - load_context->total_num_bytes = g_file_info_get_size (file_info); - - g_file_read_async ( - file, G_PRIORITY_DEFAULT, - cancellable, (GAsyncReadyCallback) - attachment_load_file_read_cb, load_context); -} - -#define ATTACHMENT_LOAD_CONTEXT "attachment-load-context-data" - -static void -attachment_load_from_mime_part_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - LoadContext *load_context; - GFileInfo *file_info; - EAttachment *attachment; - CamelContentType *content_type; - CamelMimePart *mime_part; - const gchar *attribute; - const gchar *string; - gchar *allocated; - CamelStream *null; - CamelDataWrapper *dw; - - load_context = g_object_get_data (G_OBJECT (simple), ATTACHMENT_LOAD_CONTEXT); - g_return_if_fail (load_context != NULL); - g_object_set_data (G_OBJECT (simple), ATTACHMENT_LOAD_CONTEXT, NULL); - - attachment = load_context->attachment; - mime_part = e_attachment_get_mime_part (attachment); - - file_info = g_file_info_new (); - load_context->file_info = file_info; - - content_type = camel_mime_part_get_content_type (mime_part); - allocated = camel_content_type_simple (content_type); - if (allocated != NULL) { - GIcon *icon; - gchar *cp; - - /* GIO expects lowercase MIME types. */ - for (cp = allocated; *cp != '\0'; cp++) - *cp = g_ascii_tolower (*cp); - - /* Swap the MIME type for a content type. */ - cp = g_content_type_from_mime_type (allocated); - g_free (allocated); - allocated = cp; - - /* Use the MIME part's filename if we have to. */ - if (g_content_type_is_unknown (allocated)) { - string = camel_mime_part_get_filename (mime_part); - if (string != NULL) { - g_free (allocated); - allocated = g_content_type_guess ( - string, NULL, 0, NULL); - } - } - - g_file_info_set_content_type (file_info, allocated); - - icon = g_content_type_get_icon (allocated); - if (icon != NULL) { - g_file_info_set_icon (file_info, icon); - g_object_unref (icon); - } - } - g_free (allocated); - - /* Strip any path components from the filename. */ - string = camel_mime_part_get_filename (mime_part); - if (string == NULL) - /* Translators: Default attachment filename. */ - string = _("attachment.dat"); - allocated = g_path_get_basename (string); - g_file_info_set_display_name (file_info, allocated); - g_free (allocated); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - string = camel_mime_part_get_description (mime_part); - if (string != NULL) - g_file_info_set_attribute_string ( - file_info, attribute, string); - - dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - null = camel_stream_null_new (); - /* this actually downloads the part and makes it available later */ - camel_data_wrapper_decode_to_stream_sync (dw, null, attachment->priv->cancellable, NULL); - g_file_info_set_size (file_info, CAMEL_STREAM_NULL (null)->written); - g_object_unref (null); - - load_context->mime_part = g_object_ref (mime_part); - - /* make sure it's freed on operation end */ - g_object_unref (load_context->simple); - load_context->simple = NULL; - - g_simple_async_result_set_op_res_gpointer ( - simple, load_context, - (GDestroyNotify) attachment_load_context_free); -} - -void -e_attachment_load_async (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data) -{ - LoadContext *load_context; - GCancellable *cancellable; - CamelMimePart *mime_part; - GFile *file; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - if (e_attachment_get_loading (attachment)) { - g_simple_async_report_error_in_idle ( - G_OBJECT (attachment), callback, user_data, - G_IO_ERROR, G_IO_ERROR_BUSY, - _("A load operation is already in progress")); - return; - } - - if (e_attachment_get_saving (attachment)) { - g_simple_async_report_error_in_idle ( - G_OBJECT (attachment), callback, user_data, - G_IO_ERROR, G_IO_ERROR_BUSY, - _("A save operation is already in progress")); - return; - } - - file = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (file != NULL || mime_part != NULL); - - load_context = attachment_load_context_new ( - attachment, callback, user_data); - - cancellable = attachment->priv->cancellable; - g_cancellable_reset (cancellable); - - if (file != NULL) { - g_file_query_info_async ( - file, ATTACHMENT_QUERY, - G_FILE_QUERY_INFO_NONE,G_PRIORITY_DEFAULT, - cancellable, (GAsyncReadyCallback) - attachment_load_query_info_cb, load_context); - - } else if (mime_part != NULL) { - g_object_set_data (G_OBJECT (load_context->simple), ATTACHMENT_LOAD_CONTEXT, load_context); - - g_simple_async_result_run_in_thread ( - load_context->simple, - attachment_load_from_mime_part_thread, - G_PRIORITY_DEFAULT, - cancellable); - } -} - -gboolean -e_attachment_load_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - const LoadContext *load_context; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - load_context = g_simple_async_result_get_op_res_gpointer (simple); - if (load_context && load_context->mime_part) { - const gchar *string; - - string = camel_mime_part_get_disposition (load_context->mime_part); - e_attachment_set_disposition (attachment, string); - - e_attachment_set_file_info (attachment, load_context->file_info); - e_attachment_set_mime_part (attachment, load_context->mime_part); - } - - g_simple_async_result_propagate_error (simple, error); - - attachment_set_loading (attachment, FALSE); - - return (load_context != NULL); -} - -void -e_attachment_load_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent) -{ - GtkWidget *dialog; - GFileInfo *file_info; - GtkTreeRowReference *reference; - const gchar *display_name; - const gchar *primary_text; - GError *error = NULL; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_return_if_fail (!parent || GTK_IS_WINDOW (parent)); - - if (e_attachment_load_finish (attachment, result, &error)) - return; - - /* XXX Calling EAttachmentStore functions from here violates - * the abstraction, but for now it's not hurting anything. */ - reference = e_attachment_get_reference (attachment); - if (gtk_tree_row_reference_valid (reference)) { - GtkTreeModel *model; - - model = gtk_tree_row_reference_get_model (reference); - - e_attachment_store_remove_attachment ( - E_ATTACHMENT_STORE (model), attachment); - } - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - return; - } - - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - else - display_name = NULL; - - if (display_name != NULL) - primary_text = g_strdup_printf ( - _("Could not load '%s'"), display_name); - else - primary_text = g_strdup_printf ( - _("Could not load the attachment")); - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "<big><b>%s</b></big>", primary_text); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); -} - -gboolean -e_attachment_load (EAttachment *attachment, - GError **error) -{ - EAsyncClosure *closure; - GAsyncResult *result; - gboolean success; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - closure = e_async_closure_new (); - - e_attachment_load_async (attachment, e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - success = e_attachment_load_finish (attachment, result, error); - - e_async_closure_free (closure); - - return success; -} - -/************************* e_attachment_open_async() *************************/ - -typedef struct _OpenContext OpenContext; - -struct _OpenContext { - EAttachment *attachment; - GSimpleAsyncResult *simple; - - GAppInfo *app_info; -}; - -static OpenContext * -attachment_open_context_new (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data) -{ - OpenContext *open_context; - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new ( - G_OBJECT (attachment), callback, - user_data, e_attachment_open_async); - - open_context = g_slice_new0 (OpenContext); - open_context->attachment = g_object_ref (attachment); - open_context->simple = simple; - - return open_context; -} - -static void -attachment_open_context_free (OpenContext *open_context) -{ - g_object_unref (open_context->attachment); - g_object_unref (open_context->simple); - - if (open_context->app_info != NULL) - g_object_unref (open_context->app_info); - - g_slice_free (OpenContext, open_context); -} - -static gboolean -attachment_open_check_for_error (OpenContext *open_context, - GError *error) -{ - GSimpleAsyncResult *simple; - - if (error == NULL) - return FALSE; - - simple = open_context->simple; - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - - attachment_open_context_free (open_context); - - return TRUE; -} - -static void -attachment_open_file (GFile *file, - OpenContext *open_context) -{ - GdkAppLaunchContext *context; - GSimpleAsyncResult *simple; - GdkDisplay *display; - gboolean success; - GError *error = NULL; - - simple = open_context->simple; - - display = gdk_display_get_default (); - context = gdk_display_get_app_launch_context (display); - - if (open_context->app_info != NULL) { - GList *file_list; - - file_list = g_list_prepend (NULL, file); - success = g_app_info_launch ( - open_context->app_info, file_list, - G_APP_LAUNCH_CONTEXT (context), &error); - g_list_free (file_list); - } else { - gchar *uri; - - uri = g_file_get_uri (file); - success = g_app_info_launch_default_for_uri ( - uri, G_APP_LAUNCH_CONTEXT (context), &error); - g_free (uri); - } - - g_object_unref (context); - - g_simple_async_result_set_op_res_gboolean (simple, success); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - attachment_open_context_free (open_context); -} - -static void -attachment_open_save_finished_cb (EAttachment *attachment, - GAsyncResult *result, - OpenContext *open_context) -{ - GFile *file; - gchar *path; - GError *error = NULL; - - file = e_attachment_save_finish (attachment, result, &error); - - if (attachment_open_check_for_error (open_context, error)) - return; - - /* Make the temporary file read-only. - * - * This step is non-critical, so if an error occurs just - * emit a warning and move on. - * - * XXX I haven't figured out how to do this through GIO. - * Attempting to set the "access::can-write" attribute via - * g_file_set_attribute() returned G_IO_ERROR_NOT_SUPPORTED - * and the only other possibility I see is "unix::mode", - * which is obviously not portable. - */ - path = g_file_get_path (file); -#ifndef G_OS_WIN32 - if (g_chmod (path, S_IRUSR | S_IRGRP | S_IROTH) < 0) - g_warning ("%s", g_strerror (errno)); -#endif - g_free (path); - - attachment_open_file (file, open_context); - g_object_unref (file); -} - -static void -attachment_open_save_temporary (OpenContext *open_context) -{ - GFile *temp_directory; - gchar *template; - gchar *path; - GError *error = NULL; - - errno = 0; - - /* Save the file to a temporary directory. - * We use a directory so the files can retain their basenames. - * XXX This could trigger a blocking temp directory cleanup. */ - template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mkdtemp (template); - g_free (template); - - /* XXX Let's hope errno got set properly. */ - if (path == NULL) - g_set_error ( - &error, G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - - /* We already know if there's an error, but this does the cleanup. */ - if (attachment_open_check_for_error (open_context, error)) - return; - - temp_directory = g_file_new_for_path (path); - - e_attachment_save_async ( - open_context->attachment, - temp_directory, (GAsyncReadyCallback) - attachment_open_save_finished_cb, open_context); - - g_object_unref (temp_directory); - g_free (path); -} - -void -e_attachment_open_async (EAttachment *attachment, - GAppInfo *app_info, - GAsyncReadyCallback callback, - gpointer user_data) -{ - OpenContext *open_context; - CamelMimePart *mime_part; - GFile *file; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - file = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (file != NULL || mime_part != NULL); - - open_context = attachment_open_context_new ( - attachment, callback, user_data); - - if (G_IS_APP_INFO (app_info)) - open_context->app_info = g_object_ref (app_info); - - /* If the attachment already references a GFile, we can launch - * the application directly. Otherwise we have to save the MIME - * part to a temporary file and launch the application from that. */ - if (file != NULL) { - attachment_open_file (file, open_context); - - } else if (mime_part != NULL) - attachment_open_save_temporary (open_context); -} - -gboolean -e_attachment_open_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - gboolean success; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - success = g_simple_async_result_get_op_res_gboolean (simple); - g_simple_async_result_propagate_error (simple, error); - - return success; -} - -void -e_attachment_open_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent) -{ - GtkWidget *dialog; - GFileInfo *file_info; - const gchar *display_name; - const gchar *primary_text; - GError *error = NULL; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_return_if_fail (GTK_IS_WINDOW (parent)); - - if (e_attachment_open_finish (attachment, result, &error)) - return; - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - else - display_name = NULL; - - if (display_name != NULL) - primary_text = g_strdup_printf ( - _("Could not open '%s'"), display_name); - else - primary_text = g_strdup_printf ( - _("Could not open the attachment")); - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "<big><b>%s</b></big>", primary_text); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); -} - -gboolean -e_attachment_open (EAttachment *attachment, - GAppInfo *app_info, - GError **error) -{ - EAsyncClosure *closure; - GAsyncResult *result; - gboolean success; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - closure = e_async_closure_new (); - - e_attachment_open_async (attachment, app_info, e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - success = e_attachment_open_finish (attachment, result, error); - - e_async_closure_free (closure); - - return success; -} - -/************************* e_attachment_save_async() *************************/ - -typedef struct _SaveContext SaveContext; - -struct _SaveContext { - EAttachment *attachment; - GSimpleAsyncResult *simple; - - GFile *directory; - GFile *destination; - GInputStream *input_stream; - GOutputStream *output_stream; - goffset total_num_bytes; - gssize bytes_read; - gchar buffer[4096]; - gint count; -}; - -/* Forward Declaration */ -static void -attachment_save_read_cb (GInputStream *input_stream, - GAsyncResult *result, - SaveContext *save_context); - -static SaveContext * -attachment_save_context_new (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SaveContext *save_context; - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new ( - G_OBJECT (attachment), callback, - user_data, e_attachment_save_async); - - save_context = g_slice_new0 (SaveContext); - save_context->attachment = g_object_ref (attachment); - save_context->simple = simple; - - attachment_set_saving (save_context->attachment, TRUE); - - return save_context; -} - -static void -attachment_save_context_free (SaveContext *save_context) -{ - g_object_unref (save_context->attachment); - g_object_unref (save_context->simple); - - if (save_context->directory != NULL) - g_object_unref (save_context->directory); - - if (save_context->destination != NULL) - g_object_unref (save_context->destination); - - if (save_context->input_stream != NULL) - g_object_unref (save_context->input_stream); - - if (save_context->output_stream != NULL) - g_object_unref (save_context->output_stream); - - g_slice_free (SaveContext, save_context); -} - -static gboolean -attachment_save_check_for_error (SaveContext *save_context, - GError *error) -{ - GSimpleAsyncResult *simple; - - if (error == NULL) - return FALSE; - - simple = save_context->simple; - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - - attachment_save_context_free (save_context); - - return TRUE; -} - -static GFile * -attachment_save_new_candidate (SaveContext *save_context) -{ - GFile *candidate; - GFileInfo *file_info; - EAttachment *attachment; - const gchar *display_name = NULL; - gchar *basename; - - attachment = save_context->attachment; - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - if (display_name == NULL) - /* Translators: Default attachment filename. */ - display_name = _("attachment.dat"); - - if (save_context->count == 0) - basename = g_strdup (display_name); - else { - GString *string; - const gchar *ext; - gsize length; - - string = g_string_sized_new (strlen (display_name)); - ext = g_utf8_strchr (display_name, -1, '.'); - - if (ext != NULL) - length = ext - display_name; - else - length = strlen (display_name); - - g_string_append_len (string, display_name, length); - g_string_append_printf (string, " (%d)", save_context->count); - g_string_append (string, (ext != NULL) ? ext : ""); - - basename = g_string_free (string, FALSE); - } - - save_context->count++; - - candidate = g_file_get_child (save_context->directory, basename); - - g_free (basename); - - return candidate; -} - -static void -attachment_save_write_cb (GOutputStream *output_stream, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GInputStream *input_stream; - gssize bytes_written; - GError *error = NULL; - - bytes_written = g_output_stream_write_finish ( - output_stream, result, &error); - - if (attachment_save_check_for_error (save_context, error)) - return; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - input_stream = save_context->input_stream; - - if (bytes_written < save_context->bytes_read) { - g_memmove ( - save_context->buffer, - save_context->buffer + bytes_written, - save_context->bytes_read - bytes_written); - save_context->bytes_read -= bytes_written; - - g_output_stream_write_async ( - output_stream, - save_context->buffer, - save_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_write_cb, - save_context); - } else - g_input_stream_read_async ( - input_stream, - save_context->buffer, - sizeof (save_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_read_cb, - save_context); -} - -static void -attachment_save_read_cb (GInputStream *input_stream, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GOutputStream *output_stream; - gssize bytes_read; - GError *error = NULL; - - bytes_read = g_input_stream_read_finish ( - input_stream, result, &error); - - if (attachment_save_check_for_error (save_context, error)) - return; - - if (bytes_read == 0) { - GSimpleAsyncResult *simple; - GFile *destination; - - /* Steal the destination. */ - destination = save_context->destination; - save_context->destination = NULL; - - simple = save_context->simple; - g_simple_async_result_set_op_res_gpointer ( - simple, destination, (GDestroyNotify) g_object_unref); - g_simple_async_result_complete (simple); - - attachment_save_context_free (save_context); - - return; - } - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - output_stream = save_context->output_stream; - save_context->bytes_read = bytes_read; - - attachment_progress_cb ( - g_seekable_tell (G_SEEKABLE (input_stream)), - save_context->total_num_bytes, attachment); - - g_output_stream_write_async ( - output_stream, - save_context->buffer, - save_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_write_cb, - save_context); -} - -static void -attachment_save_got_output_stream (SaveContext *save_context) -{ - GCancellable *cancellable; - GInputStream *input_stream; - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - CamelStream *stream; - EAttachment *attachment; - GByteArray *buffer; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - mime_part = e_attachment_get_mime_part (attachment); - - /* Decode the MIME part to an in-memory buffer. We have to do - * this because CamelStream is synchronous-only, and using threads - * is dangerous because CamelDataWrapper is not reentrant. */ - buffer = g_byte_array_new (); - stream = camel_stream_mem_new (); - camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), buffer); - wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - camel_data_wrapper_decode_to_stream_sync (wrapper, stream, NULL, NULL); - g_object_unref (stream); - - /* Load the buffer into a GMemoryInputStream. - * But watch out for zero length MIME parts. */ - input_stream = g_memory_input_stream_new (); - if (buffer->len > 0) - g_memory_input_stream_add_data ( - G_MEMORY_INPUT_STREAM (input_stream), - buffer->data, (gssize) buffer->len, - (GDestroyNotify) g_free); - save_context->input_stream = input_stream; - save_context->total_num_bytes = (goffset) buffer->len; - g_byte_array_free (buffer, FALSE); - - g_input_stream_read_async ( - input_stream, - save_context->buffer, - sizeof (save_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_read_cb, - save_context); -} - -static void -attachment_save_create_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileOutputStream *output_stream; - GError *error = NULL; - - /* Output stream might be NULL, so don't use cast macro. */ - output_stream = g_file_create_finish (destination, result, &error); - save_context->output_stream = (GOutputStream *) output_stream; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { - destination = attachment_save_new_candidate (save_context); - - g_file_create_async ( - destination, G_FILE_CREATE_NONE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_create_cb, - save_context); - - g_object_unref (destination); - g_error_free (error); - return; - } - - if (attachment_save_check_for_error (save_context, error)) - return; - - save_context->destination = g_object_ref (destination); - attachment_save_got_output_stream (save_context); -} - -static void -attachment_save_replace_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - GFileOutputStream *output_stream; - GError *error = NULL; - - /* Output stream might be NULL, so don't use cast macro. */ - output_stream = g_file_replace_finish (destination, result, &error); - save_context->output_stream = (GOutputStream *) output_stream; - - if (attachment_save_check_for_error (save_context, error)) - return; - - save_context->destination = g_object_ref (destination); - attachment_save_got_output_stream (save_context); -} - -static void -attachment_save_query_info_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileInfo *file_info; - GFileType file_type; - GError *error = NULL; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - - file_info = g_file_query_info_finish (destination, result, &error); - - /* G_IO_ERROR_NOT_FOUND just means we're creating a new file. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { - g_error_free (error); - goto replace; - } - - if (attachment_save_check_for_error (save_context, error)) - return; - - file_type = g_file_info_get_file_type (file_info); - g_object_unref (file_info); - - if (file_type == G_FILE_TYPE_DIRECTORY) { - save_context->directory = g_object_ref (destination); - destination = attachment_save_new_candidate (save_context); - - g_file_create_async ( - destination, G_FILE_CREATE_NONE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_create_cb, - save_context); - - g_object_unref (destination); - - return; - } - -replace: - g_file_replace_async ( - destination, NULL, FALSE, - G_FILE_CREATE_REPLACE_DESTINATION, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_replace_cb, - save_context); -} - -void -e_attachment_save_async (EAttachment *attachment, - GFile *destination, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SaveContext *save_context; - GCancellable *cancellable; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_FILE (destination)); - - if (e_attachment_get_loading (attachment)) { - g_simple_async_report_error_in_idle ( - G_OBJECT (attachment), callback, user_data, - G_IO_ERROR, G_IO_ERROR_BUSY, - _("A load operation is already in progress")); - return; - } - - if (e_attachment_get_saving (attachment)) { - g_simple_async_report_error_in_idle ( - G_OBJECT (attachment), callback, user_data, - G_IO_ERROR, G_IO_ERROR_BUSY, - _("A save operation is already in progress")); - return; - } - - if (e_attachment_get_mime_part (attachment) == NULL) { - g_simple_async_report_error_in_idle ( - G_OBJECT (attachment), callback, user_data, - G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - _("Attachment contents not loaded")); - return; - } - - save_context = attachment_save_context_new ( - attachment, callback, user_data); - - cancellable = attachment->priv->cancellable; - g_cancellable_reset (cancellable); - - /* First we need to know if destination is a directory. */ - g_file_query_info_async ( - destination, G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, - cancellable, (GAsyncReadyCallback) - attachment_save_query_info_cb, save_context); -} - -GFile * -e_attachment_save_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - GFile *destination; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - destination = g_simple_async_result_get_op_res_gpointer (simple); - if (destination != NULL) - g_object_ref (destination); - g_simple_async_result_propagate_error (simple, error); - - attachment_set_saving (attachment, FALSE); - - return destination; -} - -void -e_attachment_save_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent) -{ - GFile *file; - GFileInfo *file_info; - GtkWidget *dialog; - const gchar *display_name; - const gchar *primary_text; - GError *error = NULL; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_return_if_fail (GTK_IS_WINDOW (parent)); - - file = e_attachment_save_finish (attachment, result, &error); - - if (file != NULL) { - g_object_unref (file); - return; - } - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - else - display_name = NULL; - - if (display_name != NULL) - primary_text = g_strdup_printf ( - _("Could not save '%s'"), display_name); - else - primary_text = g_strdup_printf ( - _("Could not save the attachment")); - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "<big><b>%s</b></big>", primary_text); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); -} - -gboolean -e_attachment_save (EAttachment *attachment, - GFile *in_destination, - GFile **out_destination, - GError **error) -{ - EAsyncClosure *closure; - GAsyncResult *result; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_return_val_if_fail (out_destination != NULL, FALSE); - - closure = e_async_closure_new (); - - e_attachment_save_async (attachment, in_destination, e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - *out_destination = e_attachment_save_finish (attachment, result, error); - - e_async_closure_free (closure); - - return *out_destination != NULL; -} diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h deleted file mode 100644 index 890c13294e..0000000000 --- a/widgets/misc/e-attachment.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * e-attachment.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_H -#define E_ATTACHMENT_H - -#include <gtk/gtk.h> -#include <camel/camel.h> - -/* Standard GObject macros */ -#define E_TYPE_ATTACHMENT \ - (e_attachment_get_type ()) -#define E_ATTACHMENT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT, EAttachment)) -#define E_ATTACHMENT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT, EAttachmentClass)) -#define E_IS_ATTACHMENT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT)) -#define E_IS_ATTACHMENT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT)) -#define E_ATTACHMENT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT, EAttachmentClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachment EAttachment; -typedef struct _EAttachmentClass EAttachmentClass; -typedef struct _EAttachmentPrivate EAttachmentPrivate; - -struct _EAttachment { - GObject parent; - EAttachmentPrivate *priv; -}; - -struct _EAttachmentClass { - GObjectClass parent_class; -}; - -GType e_attachment_get_type (void); -EAttachment * e_attachment_new (void); -EAttachment * e_attachment_new_for_path (const gchar *path); -EAttachment * e_attachment_new_for_uri (const gchar *uri); -EAttachment * e_attachment_new_for_message (CamelMimeMessage *message); -void e_attachment_add_to_multipart (EAttachment *attachment, - CamelMultipart *multipart, - const gchar *default_charset); -void e_attachment_cancel (EAttachment *attachment); -gboolean e_attachment_get_can_show (EAttachment *attachment); -void e_attachment_set_can_show (EAttachment *attachment, - gboolean can_show); -const gchar * e_attachment_get_disposition (EAttachment *attachment); -void e_attachment_set_disposition (EAttachment *attachment, - const gchar *disposition); -GFile * e_attachment_get_file (EAttachment *attachment); -void e_attachment_set_file (EAttachment *attachment, - GFile *file); -GFileInfo * e_attachment_get_file_info (EAttachment *attachment); -void e_attachment_set_file_info (EAttachment *attachment, - GFileInfo *file_info); -gchar * e_attachment_get_mime_type (EAttachment *attachment); -GIcon * e_attachment_get_icon (EAttachment *attachment); -gboolean e_attachment_get_loading (EAttachment *attachment); -CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment); -void e_attachment_set_mime_part (EAttachment *attachment, - CamelMimePart *mime_part); -gint e_attachment_get_percent (EAttachment *attachment); -GtkTreeRowReference * - e_attachment_get_reference (EAttachment *attachment); -void e_attachment_set_reference (EAttachment *attachment, - GtkTreeRowReference *reference); -gboolean e_attachment_get_saving (EAttachment *attachment); -gboolean e_attachment_get_shown (EAttachment *attachment); -void e_attachment_set_shown (EAttachment *attachment, - gboolean shown); -camel_cipher_validity_encrypt_t - e_attachment_get_encrypted (EAttachment *attachment); -void e_attachment_set_encrypted (EAttachment *attachment, - camel_cipher_validity_encrypt_t encrypted); -camel_cipher_validity_sign_t - e_attachment_get_signed (EAttachment *attachment); -void e_attachment_set_signed (EAttachment *attachment, - camel_cipher_validity_sign_t signed_); -const gchar * e_attachment_get_description (EAttachment *attachment); -const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); -gboolean e_attachment_is_rfc822 (EAttachment *attachment); -GList * e_attachment_list_apps (EAttachment *attachment); - -/* Asynchronous Operations */ -void e_attachment_load_async (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_attachment_load_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error); -gboolean e_attachment_load (EAttachment *attachment, - GError **error); -void e_attachment_open_async (EAttachment *attachment, - GAppInfo *app_info, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_attachment_open_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error); -gboolean e_attachment_open (EAttachment *attachment, - GAppInfo *app_info, - GError **error); -void e_attachment_save_async (EAttachment *attachment, - GFile *destination, - GAsyncReadyCallback callback, - gpointer user_data); -GFile * e_attachment_save_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error); -gboolean e_attachment_save (EAttachment *attachment, - GFile *in_destination, - GFile **out_destination, - GError **error); - -/* Handy GAsyncReadyCallback Functions */ -void e_attachment_load_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent); -void e_attachment_open_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent); -void e_attachment_save_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent); - -G_END_DECLS - -#endif /* E_ATTACHMENT_H */ diff --git a/widgets/misc/e-auth-combo-box.c b/widgets/misc/e-auth-combo-box.c deleted file mode 100644 index bd3d8c78ea..0000000000 --- a/widgets/misc/e-auth-combo-box.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * e-auth-combo-box.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-auth-combo-box.h" - -#define E_AUTH_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_AUTH_COMBO_BOX, EAuthComboBoxPrivate)) - -struct _EAuthComboBoxPrivate { - CamelProvider *provider; -}; - -enum { - PROP_0, - PROP_PROVIDER -}; - -enum { - COLUMN_MECHANISM, - COLUMN_DISPLAY_NAME, - COLUMN_STRIKETHROUGH, - COLUMN_AUTHTYPE, - NUM_COLUMNS -}; - -G_DEFINE_TYPE ( - EAuthComboBox, - e_auth_combo_box, - GTK_TYPE_COMBO_BOX) - -static void -auth_combo_box_rebuild_model (EAuthComboBox *combo_box) -{ - GtkComboBox *gtk_combo_box; - CamelProvider *provider; - GtkTreeModel *model; - GList *link; - const gchar *active_id; - - provider = e_auth_combo_box_get_provider (combo_box); - - gtk_combo_box = GTK_COMBO_BOX (combo_box); - model = gtk_combo_box_get_model (gtk_combo_box); - active_id = gtk_combo_box_get_active_id (gtk_combo_box); - - gtk_list_store_clear (GTK_LIST_STORE (model)); - - if (provider == NULL) - return; - - for (link = provider->authtypes; link != NULL; link = link->next) { - CamelServiceAuthType *authtype = link->data; - GtkTreeIter iter; - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - COLUMN_MECHANISM, authtype->authproto, - COLUMN_DISPLAY_NAME, authtype->name, - COLUMN_AUTHTYPE, authtype, - -1); - } - - /* Try selecting the previous mechanism. */ - if (active_id != NULL) - gtk_combo_box_set_active_id (gtk_combo_box, active_id); - - /* Or else fall back to the first mechanism. */ - if (gtk_combo_box_get_active (gtk_combo_box) == -1) - gtk_combo_box_set_active (gtk_combo_box, 0); -} - -static void -auth_combo_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PROVIDER: - e_auth_combo_box_set_provider ( - E_AUTH_COMBO_BOX (object), - g_value_get_pointer (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -auth_combo_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PROVIDER: - g_value_set_pointer ( - value, - e_auth_combo_box_get_provider ( - E_AUTH_COMBO_BOX (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -auth_combo_box_constructed (GObject *object) -{ - GtkComboBox *combo_box; - GtkListStore *list_store; - GtkCellLayout *cell_layout; - GtkCellRenderer *cell_renderer; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_auth_combo_box_parent_class)->constructed (object); - - list_store = gtk_list_store_new ( - NUM_COLUMNS, - G_TYPE_STRING, /* COLUMN_MECHANISM */ - G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */ - G_TYPE_BOOLEAN, /* COLUMN_STRIKETHROUGH */ - G_TYPE_POINTER); /* COLUMN_AUTHTYPE */ - - combo_box = GTK_COMBO_BOX (object); - gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store)); - gtk_combo_box_set_id_column (combo_box, COLUMN_MECHANISM); - g_object_unref (list_store); - - cell_layout = GTK_CELL_LAYOUT (object); - cell_renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE); - - gtk_cell_layout_set_attributes ( - cell_layout, cell_renderer, - "text", COLUMN_DISPLAY_NAME, - "strikethrough", COLUMN_STRIKETHROUGH, - NULL); -} - -static void -e_auth_combo_box_class_init (EAuthComboBoxClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EAuthComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = auth_combo_box_set_property; - object_class->get_property = auth_combo_box_get_property; - object_class->constructed = auth_combo_box_constructed; - - g_object_class_install_property ( - object_class, - PROP_PROVIDER, - g_param_spec_pointer ( - "provider", - "Provider", - "The provider to query for auth mechanisms", - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_auth_combo_box_init (EAuthComboBox *combo_box) -{ - combo_box->priv = E_AUTH_COMBO_BOX_GET_PRIVATE (combo_box); -} - -GtkWidget * -e_auth_combo_box_new (void) -{ - return g_object_new (E_TYPE_AUTH_COMBO_BOX, NULL); -} - -CamelProvider * -e_auth_combo_box_get_provider (EAuthComboBox *combo_box) -{ - g_return_val_if_fail (E_IS_AUTH_COMBO_BOX (combo_box), NULL); - - return combo_box->priv->provider; -} - -void -e_auth_combo_box_set_provider (EAuthComboBox *combo_box, - CamelProvider *provider) -{ - g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box)); - - if (provider == combo_box->priv->provider) - return; - - combo_box->priv->provider = provider; - - g_object_notify (G_OBJECT (combo_box), "provider"); - - auth_combo_box_rebuild_model (combo_box); -} - -void -e_auth_combo_box_update_available (EAuthComboBox *combo_box, - GList *available_authtypes) -{ - GtkComboBox *gtk_combo_box; - GtkTreeModel *model; - GtkTreeIter iter; - gint active_index; - gint available_index = -1; - gint index = 0; - gboolean iter_set; - - g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box)); - - gtk_combo_box = GTK_COMBO_BOX (combo_box); - model = gtk_combo_box_get_model (gtk_combo_box); - active_index = gtk_combo_box_get_active (gtk_combo_box); - - iter_set = gtk_tree_model_get_iter_first (model, &iter); - - while (iter_set) { - CamelServiceAuthType *authtype; - gboolean available; - - gtk_tree_model_get ( - model, &iter, COLUMN_AUTHTYPE, &authtype, -1); - - available = (g_list_find ( - available_authtypes, authtype) != NULL); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - COLUMN_STRIKETHROUGH, !available, -1); - - if (index == active_index && !available) - active_index = -1; - - if (available && available_index == -1) - available_index = index; - - iter_set = gtk_tree_model_iter_next (model, &iter); - index++; - } - - /* If the active combo_box item turned out to be unavailable - * (or there was no active item), select the first available. */ - if (active_index == -1 && available_index != -1) - gtk_combo_box_set_active (gtk_combo_box, available_index); -} diff --git a/widgets/misc/e-auth-combo-box.h b/widgets/misc/e-auth-combo-box.h deleted file mode 100644 index e449f1c06b..0000000000 --- a/widgets/misc/e-auth-combo-box.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * e-auth-combo-box.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_AUTH_COMBO_BOX_H -#define E_AUTH_COMBO_BOX_H - -#include <gtk/gtk.h> -#include <camel/camel.h> - -/* Standard GObject macros */ -#define E_TYPE_AUTH_COMBO_BOX \ - (e_auth_combo_box_get_type ()) -#define E_AUTH_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_AUTH_COMBO_BOX, EAuthComboBox)) -#define E_AUTH_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_AUTH_COMBO_BOX, EAuthComboBoxClass)) -#define E_IS_AUTH_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_AUTH_COMBO_BOX)) -#define E_IS_AUTH_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_AUTH_COMBO_BOX)) -#define E_AUTH_COMBO_BOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_AUTH_COMBO_BOX, EAuthComboBoxClass)) - -G_BEGIN_DECLS - -typedef struct _EAuthComboBox EAuthComboBox; -typedef struct _EAuthComboBoxClass EAuthComboBoxClass; -typedef struct _EAuthComboBoxPrivate EAuthComboBoxPrivate; - -struct _EAuthComboBox { - GtkComboBox parent; - EAuthComboBoxPrivate *priv; -}; - -struct _EAuthComboBoxClass { - GtkComboBoxClass parent_class; -}; - -GType e_auth_combo_box_get_type (void) G_GNUC_CONST; -GtkWidget * e_auth_combo_box_new (void); -CamelProvider * e_auth_combo_box_get_provider (EAuthComboBox *combo_box); -void e_auth_combo_box_set_provider (EAuthComboBox *combo_box, - CamelProvider *provider); -void e_auth_combo_box_update_available - (EAuthComboBox *combo_box, - GList *available_authtypes); - -G_END_DECLS - -#endif /* E_AUTH_COMBO_BOX_H */ - diff --git a/widgets/misc/e-autocomplete-selector.c b/widgets/misc/e-autocomplete-selector.c deleted file mode 100644 index c0bf207bbd..0000000000 --- a/widgets/misc/e-autocomplete-selector.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * e-autocomplete-selector.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-autocomplete-selector.h" - -G_DEFINE_TYPE ( - EAutocompleteSelector, - e_autocomplete_selector, - E_TYPE_SOURCE_SELECTOR) - -static gboolean -autocomplete_selector_get_source_selected (ESourceSelector *selector, - ESource *source) -{ - ESourceAutocomplete *extension; - const gchar *extension_name; - - /* Make sure this source is an address book. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return FALSE; - - extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE; - extension = e_source_get_extension (source, extension_name); - g_return_val_if_fail (E_IS_SOURCE_AUTOCOMPLETE (extension), FALSE); - - return e_source_autocomplete_get_include_me (extension); -} - -static void -autocomplete_selector_set_source_selected (ESourceSelector *selector, - ESource *source, - gboolean selected) -{ - ESourceAutocomplete *extension; - const gchar *extension_name; - - /* Make sure this source is an address book. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return; - - extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE; - extension = e_source_get_extension (source, extension_name); - g_return_if_fail (E_IS_SOURCE_AUTOCOMPLETE (extension)); - - if (selected != e_source_autocomplete_get_include_me (extension)) { - e_source_autocomplete_set_include_me (extension, selected); - e_source_selector_queue_write (selector, source); - } -} - -static void -e_autocomplete_selector_class_init (EAutocompleteSelectorClass *class) -{ - ESourceSelectorClass *source_selector_class; - - source_selector_class = E_SOURCE_SELECTOR_CLASS (class); - source_selector_class->get_source_selected = - autocomplete_selector_get_source_selected; - source_selector_class->set_source_selected = - autocomplete_selector_set_source_selected; -} - -static void -e_autocomplete_selector_init (EAutocompleteSelector *selector) -{ - e_source_selector_set_show_colors ( - E_SOURCE_SELECTOR (selector), FALSE); -} - -GtkWidget * -e_autocomplete_selector_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_AUTOCOMPLETE_SELECTOR, - "extension-name", E_SOURCE_EXTENSION_ADDRESS_BOOK, - "registry", registry, NULL); -} diff --git a/widgets/misc/e-autocomplete-selector.h b/widgets/misc/e-autocomplete-selector.h deleted file mode 100644 index 4e44efc7f3..0000000000 --- a/widgets/misc/e-autocomplete-selector.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * e-autocomplete-selector.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_AUTOCOMPLETE_SELECTOR_H -#define E_AUTOCOMPLETE_SELECTOR_H - -#include <libedataserverui/libedataserverui.h> - -/* Standard GObject macros */ -#define E_TYPE_AUTOCOMPLETE_SELECTOR \ - (e_autocomplete_selector_get_type ()) -#define E_AUTOCOMPLETE_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_AUTOCOMPLETE_SELECTOR, EAutocompleteSelector)) -#define E_AUTOCOMPLETE_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_AUTOCOMPLETE_SELECTOR, EAutocompleteSelectorClass)) -#define E_IS_AUTOCOMPLETE_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_AUTOCOMPLETE_SELECTOR)) -#define E_IS_AUTOCOMPLETE_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_AUTOCOMPLETE_SELECTOR)) -#define E_AUTOCOMPLETE_SELECTOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_AUTOCOMPLETE_SELECTOR, EAutocompleteSelectorClass)) - -G_BEGIN_DECLS - -typedef struct _EAutocompleteSelector EAutocompleteSelector; -typedef struct _EAutocompleteSelectorClass EAutocompleteSelectorClass; -typedef struct _EAutocompleteSelectorPrivate EAutocompleteSelectorPrivate; - -struct _EAutocompleteSelector { - ESourceSelector parent; - EAutocompleteSelectorPrivate *priv; -}; - -struct _EAutocompleteSelectorClass { - ESourceSelectorClass parent_class; -}; - -GType e_autocomplete_selector_get_type - (void) G_GNUC_CONST; -GtkWidget * e_autocomplete_selector_new (ESourceRegistry *registry); - -G_END_DECLS - -#endif /* E_AUTOCOMPLETE_SELECTOR_H */ diff --git a/widgets/misc/e-book-source-config.c b/widgets/misc/e-book-source-config.c deleted file mode 100644 index 56d9771d9f..0000000000 --- a/widgets/misc/e-book-source-config.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * e-book-source-config.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-book-source-config.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#define E_BOOK_SOURCE_CONFIG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_BOOK_SOURCE_CONFIG, EBookSourceConfigPrivate)) - -struct _EBookSourceConfigPrivate { - GtkWidget *default_button; - GtkWidget *autocomplete_button; -}; - -G_DEFINE_TYPE ( - EBookSourceConfig, - e_book_source_config, - E_TYPE_SOURCE_CONFIG) - -static ESource * -book_source_config_ref_default (ESourceConfig *config) -{ - ESourceRegistry *registry; - - registry = e_source_config_get_registry (config); - - return e_source_registry_ref_default_address_book (registry); -} - -static void -book_source_config_set_default (ESourceConfig *config, - ESource *source) -{ - ESourceRegistry *registry; - - registry = e_source_config_get_registry (config); - - e_source_registry_set_default_address_book (registry, source); -} - -static void -book_source_config_dispose (GObject *object) -{ - EBookSourceConfigPrivate *priv; - - priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (object); - - if (priv->default_button != NULL) { - g_object_unref (priv->default_button); - priv->default_button = NULL; - } - - if (priv->autocomplete_button != NULL) { - g_object_unref (priv->autocomplete_button); - priv->autocomplete_button = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_book_source_config_parent_class)->dispose (object); -} - -static void -book_source_config_constructed (GObject *object) -{ - EBookSourceConfigPrivate *priv; - ESource *default_source; - ESource *original_source; - ESourceConfig *config; - GObjectClass *class; - GtkWidget *widget; - const gchar *label; - - /* Chain up to parent's constructed() method. */ - class = G_OBJECT_CLASS (e_book_source_config_parent_class); - class->constructed (object); - - config = E_SOURCE_CONFIG (object); - priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (object); - - label = _("Mark as default address book"); - widget = gtk_check_button_new_with_label (label); - priv->default_button = g_object_ref_sink (widget); - gtk_widget_show (widget); - - label = _("Autocomplete with this address book"); - widget = gtk_check_button_new_with_label (label); - priv->autocomplete_button = g_object_ref_sink (widget); - gtk_widget_show (widget); - - default_source = book_source_config_ref_default (config); - original_source = e_source_config_get_original_source (config); - - if (original_source != NULL) { - gboolean active; - - active = e_source_equal (original_source, default_source); - g_object_set (priv->default_button, "active", active, NULL); - } - - g_object_unref (default_source); - - e_source_config_insert_widget ( - config, NULL, NULL, priv->default_button); - - e_source_config_insert_widget ( - config, NULL, NULL, priv->autocomplete_button); -} - -static const gchar * -book_source_config_get_backend_extension_name (ESourceConfig *config) -{ - return E_SOURCE_EXTENSION_ADDRESS_BOOK; -} - -static GList * -book_source_config_list_eligible_collections (ESourceConfig *config) -{ - GQueue trash = G_QUEUE_INIT; - GList *list, *link; - - /* Chain up to parent's list_eligible_collections() method. */ - list = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class)-> - list_eligible_collections (config); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - ESourceCollection *extension; - const gchar *extension_name; - - extension_name = E_SOURCE_EXTENSION_COLLECTION; - extension = e_source_get_extension (source, extension_name); - - if (!e_source_collection_get_contacts_enabled (extension)) - g_queue_push_tail (&trash, link); - } - - /* Remove ineligible collections from the list. */ - while ((link = g_queue_pop_head (&trash)) != NULL) { - g_object_unref (link->data); - list = g_list_delete_link (list, link); - } - - return list; -} - -static void -book_source_config_init_candidate (ESourceConfig *config, - ESource *scratch_source) -{ - EBookSourceConfigPrivate *priv; - ESourceConfigClass *class; - ESourceExtension *extension; - const gchar *extension_name; - - /* Chain up to parent's init_candidate() method. */ - class = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class); - class->init_candidate (config, scratch_source); - - priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config); - - extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE; - extension = e_source_get_extension (scratch_source, extension_name); - - g_object_bind_property ( - extension, "include-me", - priv->autocomplete_button, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} - -static void -book_source_config_commit_changes (ESourceConfig *config, - ESource *scratch_source) -{ - EBookSourceConfigPrivate *priv; - ESourceConfigClass *class; - ESource *default_source; - GtkToggleButton *toggle_button; - - priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config); - toggle_button = GTK_TOGGLE_BUTTON (priv->default_button); - - /* Chain up to parent's commit_changes() method. */ - class = E_SOURCE_CONFIG_CLASS (e_book_source_config_parent_class); - class->commit_changes (config, scratch_source); - - default_source = book_source_config_ref_default (config); - - /* The default setting is a little tricky to get right. If - * the toggle button is active, this ESource is now the default. - * That much is simple. But if the toggle button is NOT active, - * then we have to inspect the old default. If this ESource WAS - * the default, reset the default to 'system'. If this ESource - * WAS NOT the old default, leave it alone. */ - if (gtk_toggle_button_get_active (toggle_button)) - book_source_config_set_default (config, scratch_source); - else if (e_source_equal (scratch_source, default_source)) - book_source_config_set_default (config, NULL); - - g_object_unref (default_source); -} - -static void -e_book_source_config_class_init (EBookSourceConfigClass *class) -{ - GObjectClass *object_class; - ESourceConfigClass *source_config_class; - - g_type_class_add_private (class, sizeof (EBookSourceConfigPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = book_source_config_dispose; - object_class->constructed = book_source_config_constructed; - - source_config_class = E_SOURCE_CONFIG_CLASS (class); - source_config_class->get_backend_extension_name = - book_source_config_get_backend_extension_name; - source_config_class->list_eligible_collections = - book_source_config_list_eligible_collections; - source_config_class->init_candidate = book_source_config_init_candidate; - source_config_class->commit_changes = book_source_config_commit_changes; -} - -static void -e_book_source_config_init (EBookSourceConfig *config) -{ - config->priv = E_BOOK_SOURCE_CONFIG_GET_PRIVATE (config); -} - -GtkWidget * -e_book_source_config_new (ESourceRegistry *registry, - ESource *original_source) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - if (original_source != NULL) - g_return_val_if_fail (E_IS_SOURCE (original_source), NULL); - - return g_object_new ( - E_TYPE_BOOK_SOURCE_CONFIG, "registry", registry, - "original-source", original_source, NULL); -} - -void -e_book_source_config_add_offline_toggle (EBookSourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget; - ESourceExtension *extension; - const gchar *extension_name; - - g_return_if_fail (E_IS_BOOK_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_OFFLINE; - extension = e_source_get_extension (scratch_source, extension_name); - - widget = gtk_check_button_new_with_label ( - _("Copy book content locally for offline operation")); - e_source_config_insert_widget ( - E_SOURCE_CONFIG (config), scratch_source, NULL, widget); - gtk_widget_show (widget); - - g_object_bind_property ( - extension, "stay-synchronized", - widget, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} diff --git a/widgets/misc/e-book-source-config.h b/widgets/misc/e-book-source-config.h deleted file mode 100644 index 18e075511e..0000000000 --- a/widgets/misc/e-book-source-config.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * e-book-source-config.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_BOOK_SOURCE_CONFIG_H -#define E_BOOK_SOURCE_CONFIG_H - -#include <misc/e-source-config.h> - -/* Standard GObject macros */ -#define E_TYPE_BOOK_SOURCE_CONFIG \ - (e_book_source_config_get_type ()) -#define E_BOOK_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_BOOK_SOURCE_CONFIG, EBookSourceConfig)) -#define E_BOOK_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_BOOK_SOURCE_CONFIG, EBookSourceConfigClass)) -#define E_IS_BOOK_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_BOOK_SOURCE_CONFIG)) -#define E_IS_BOOK_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_BOOK_SOURCE_CONFIG)) -#define E_BOOK_SOURCE_CONFIG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_BOOK_SOURCE_CONFIG, EBookSourceConfigClass)) - -G_BEGIN_DECLS - -typedef struct _EBookSourceConfig EBookSourceConfig; -typedef struct _EBookSourceConfigClass EBookSourceConfigClass; -typedef struct _EBookSourceConfigPrivate EBookSourceConfigPrivate; - -struct _EBookSourceConfig { - ESourceConfig parent; - EBookSourceConfigPrivate *priv; -}; - -struct _EBookSourceConfigClass { - ESourceConfigClass parent_class; -}; - -GType e_book_source_config_get_type (void) G_GNUC_CONST; -GtkWidget * e_book_source_config_new (ESourceRegistry *registry, - ESource *original_source); -void e_book_source_config_add_offline_toggle - (EBookSourceConfig *config, - ESource *scratch_source); - -G_END_DECLS - -#endif /* E_BOOK_SOURCE_CONFIG_H */ diff --git a/widgets/misc/e-buffer-tagger.c b/widgets/misc/e-buffer-tagger.c deleted file mode 100644 index b68d414868..0000000000 --- a/widgets/misc/e-buffer-tagger.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * e-buffer-tagger.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <glib/gi18n.h> -#include <regex.h> -#include <string.h> -#include <ctype.h> - -#include "e-util/e-util.h" -#include "e-buffer-tagger.h" - -enum EBufferTaggerState -{ - E_BUFFER_TAGGER_STATE_NONE = 0, - E_BUFFER_TAGGER_STATE_INSDEL = 1 << 0, /* set when was called insert or delete of a text */ - E_BUFFER_TAGGER_STATE_CHANGED = 1 << 1, /* remark of the buffer is scheduled */ - E_BUFFER_TAGGER_STATE_IS_HOVERING = 1 << 2, /* mouse is over the link */ - E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP = 1 << 3, /* mouse is over the link and the tooltip can be shown */ - E_BUFFER_TAGGER_STATE_CTRL_DOWN = 1 << 4 /* Ctrl key is down */ -}; - -#define E_BUFFER_TAGGER_DATA_STATE "EBufferTagger::state" -#define E_BUFFER_TAGGER_LINK_TAG "EBufferTagger::link" - -struct _MagicInsertMatch -{ - const gchar *regex; - regex_t *preg; - const gchar *prefix; -}; - -typedef struct _MagicInsertMatch MagicInsertMatch; - -static MagicInsertMatch mim[] = { - /* prefixed expressions */ - { "(news|telnet|nntp|file|http|ftp|sftp|https|webcal)://([-a-z0-9]+(:[-a-z0-9]+)?@)?[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(([.])?/[-a-z0-9_$.+!*(),;:@%&=?/~#']*[^]'.}>\\) \n\r\t,?!;:\"]?)?", NULL, NULL }, - { "(sip|h323|callto):([-_a-z0-9.'\\+]+(:[0-9]{1,5})?(/[-_a-z0-9.']+)?)(@([-_a-z0-9.%=?]+|([0-9]{1,3}.){3}[0-9]{1,3})?)?(:[0-9]{1,5})?", NULL, NULL }, - { "mailto:[-_a-z0-9.'\\+]+@[-_a-z0-9.%=?]+", NULL, NULL }, - /* not prefixed expression */ - { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(([.])?/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]'.}>\\) \n\r\t,?!;:\"]?)?", NULL, "http://" }, - { "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(([.])?/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]'.}>\\) \n\r\t,?!;:\"]?)?", NULL, "ftp://" }, - { "[-_a-z0-9.'\\+]+@[-_a-z0-9.%=?]+", NULL, "mailto:" } -}; - -static void -init_magic_links (void) -{ - static gboolean done = FALSE; - gint i; - - if (done) - return; - - done = TRUE; - - for (i = 0; i < G_N_ELEMENTS (mim); i++) { - mim[i].preg = g_new0 (regex_t, 1); - if (regcomp (mim[i].preg, mim[i].regex, REG_EXTENDED | REG_ICASE)) { - /* error */ - g_free (mim[i].preg); - mim[i].preg = 0; - } - } -} - -static void -markup_text (GtkTextBuffer *buffer) -{ - GtkTextIter start, end; - gchar *text; - gint i; - regmatch_t pmatch[2]; - gboolean any; - const gchar *str; - gint offset = 0; - - g_return_if_fail (buffer != NULL); - - gtk_text_buffer_get_start_iter (buffer, &start); - gtk_text_buffer_get_end_iter (buffer, &end); - gtk_text_buffer_remove_tag_by_name (buffer, E_BUFFER_TAGGER_LINK_TAG, &start, &end); - text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); - - str = text; - any = TRUE; - while (any) { - any = FALSE; - for (i = 0; i < G_N_ELEMENTS (mim); i++) { - if (mim[i].preg && !regexec (mim[i].preg, str, 2, pmatch, 0)) { - gtk_text_buffer_get_iter_at_offset (buffer, &start, offset + pmatch[0].rm_so); - gtk_text_buffer_get_iter_at_offset (buffer, &end, offset + pmatch[0].rm_eo); - gtk_text_buffer_apply_tag_by_name (buffer, E_BUFFER_TAGGER_LINK_TAG, &start, &end); - - any = TRUE; - str += pmatch[0].rm_eo; - offset += pmatch[0].rm_eo; - break; - } - } - } - - g_free (text); -} - -static void -get_pointer_position (GtkTextView *text_view, - gint *x, - gint *y) -{ - GdkWindow *window; - GdkDisplay *display; - GdkDeviceManager *device_manager; - GdkDevice *device; - - window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_WIDGET); - display = gdk_window_get_display (window); - device_manager = gdk_display_get_device_manager (display); - device = gdk_device_manager_get_client_pointer (device_manager); - - gdk_window_get_device_position (window, device, x, y, NULL); -} - -static guint32 -get_state (GtkTextBuffer *buffer) -{ - g_return_val_if_fail (buffer != NULL, E_BUFFER_TAGGER_STATE_NONE); - g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), E_BUFFER_TAGGER_STATE_NONE); - - return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (buffer), E_BUFFER_TAGGER_DATA_STATE)); -} - -static void -set_state (GtkTextBuffer *buffer, - guint32 state) -{ - g_object_set_data (G_OBJECT (buffer), E_BUFFER_TAGGER_DATA_STATE, GINT_TO_POINTER (state)); -} - -static void -update_state (GtkTextBuffer *buffer, - guint32 value, - gboolean do_set) -{ - guint32 state; - - g_return_if_fail (buffer != NULL); - g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer)); - - state = get_state (buffer); - - if (do_set) - state = state | value; - else - state = state & (~value); - - set_state (buffer, state); -} - -static gboolean -get_tag_bounds (GtkTextIter *iter, - GtkTextTag *tag, - GtkTextIter *start, - GtkTextIter *end) -{ - gboolean res = FALSE; - - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (start != NULL, FALSE); - g_return_val_if_fail (end != NULL, FALSE); - - if (gtk_text_iter_has_tag (iter, tag)) { - *start = *iter; - *end = *iter; - - if (!gtk_text_iter_begins_tag (start, tag)) - gtk_text_iter_backward_to_tag_toggle (start, tag); - - if (!gtk_text_iter_ends_tag (end, tag)) - gtk_text_iter_forward_to_tag_toggle (end, tag); - - res = TRUE; - } - - return res; -} - -static gchar * -get_url_at_iter (GtkTextBuffer *buffer, - GtkTextIter *iter) -{ - GtkTextTagTable *tag_table; - GtkTextTag *tag; - GtkTextIter start, end; - gchar *url = NULL; - - g_return_val_if_fail (buffer != NULL, NULL); - - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - g_return_val_if_fail (tag != NULL, FALSE); - - if (get_tag_bounds (iter, tag, &start, &end)) - url = gtk_text_iter_get_text (&start, &end); - - return url; -} - -static gboolean -invoke_link_if_present (GtkTextBuffer *buffer, - GtkTextIter *iter) -{ - gboolean res; - gchar *url; - - g_return_val_if_fail (buffer != NULL, FALSE); - - url = get_url_at_iter (buffer, iter); - - res = url && *url; - if (res) - e_show_uri (NULL, url); - - g_free (url); - - return res; -} - -static void -remove_tag_if_present (GtkTextBuffer *buffer, - GtkTextIter *where) -{ - GtkTextTagTable *tag_table; - GtkTextTag *tag; - GtkTextIter start, end; - - g_return_if_fail (buffer != NULL); - g_return_if_fail (where != NULL); - - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - g_return_if_fail (tag != NULL); - - if (get_tag_bounds (where, tag, &start, &end)) - gtk_text_buffer_remove_tag (buffer, tag, &start, &end); -} - -static void -buffer_insert_text (GtkTextBuffer *buffer, - GtkTextIter *location, - gchar *text, - gint len, - gpointer user_data) -{ - update_state (buffer, E_BUFFER_TAGGER_STATE_INSDEL, TRUE); - remove_tag_if_present (buffer, location); -} - -static void -buffer_delete_range (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, - gpointer user_data) -{ - update_state (buffer, E_BUFFER_TAGGER_STATE_INSDEL, TRUE); - remove_tag_if_present (buffer, start); - remove_tag_if_present (buffer, end); -} - -static void -buffer_cursor_position (GtkTextBuffer *buffer, - gpointer user_data) -{ - guint32 state; - - state = get_state (buffer); - if (state & E_BUFFER_TAGGER_STATE_INSDEL) { - state = (state & (~E_BUFFER_TAGGER_STATE_INSDEL)) | E_BUFFER_TAGGER_STATE_CHANGED; - } else { - if (state & E_BUFFER_TAGGER_STATE_CHANGED) { - markup_text (buffer); - } - - state = state & (~ (E_BUFFER_TAGGER_STATE_CHANGED | E_BUFFER_TAGGER_STATE_INSDEL)); - } - - set_state (buffer, state); -} - -static void -update_mouse_cursor (GtkTextView *text_view, - gint x, - gint y) -{ - static GdkCursor *hand_cursor = NULL; - static GdkCursor *regular_cursor = NULL; - gboolean hovering = FALSE, hovering_over_link = FALSE, hovering_real; - guint32 state; - GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view); - GtkTextTagTable *tag_table; - GtkTextTag *tag; - GtkTextIter iter; - - if (!hand_cursor) { - hand_cursor = gdk_cursor_new (GDK_HAND2); - regular_cursor = gdk_cursor_new (GDK_XTERM); - } - - g_return_if_fail (buffer != NULL); - - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - g_return_if_fail (tag != NULL); - - state = get_state (buffer); - - gtk_text_view_get_iter_at_location (text_view, &iter, x, y); - hovering_real = gtk_text_iter_has_tag (&iter, tag); - - hovering_over_link = (state & E_BUFFER_TAGGER_STATE_IS_HOVERING) != 0; - if ((state & E_BUFFER_TAGGER_STATE_CTRL_DOWN) == 0) { - hovering = FALSE; - } else { - hovering = hovering_real; - } - - if (hovering != hovering_over_link) { - update_state (buffer, E_BUFFER_TAGGER_STATE_IS_HOVERING, hovering); - - if (hovering && gtk_widget_has_focus (GTK_WIDGET (text_view))) - gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor); - else - gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor); - - /* XXX Is this necessary? Appears to be a no-op. */ - get_pointer_position (text_view, NULL, NULL); - } - - hovering_over_link = (state & E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP) != 0; - - if (hovering_real != hovering_over_link) { - update_state (buffer, E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP, hovering_real); - - gtk_widget_trigger_tooltip_query (GTK_WIDGET (text_view)); - } -} - -static gboolean -textview_query_tooltip (GtkTextView *text_view, - gint x, - gint y, - gboolean keyboard_mode, - GtkTooltip *tooltip, - gpointer user_data) -{ - GtkTextBuffer *buffer; - guint32 state; - gboolean res = FALSE; - - if (keyboard_mode) - return FALSE; - - buffer = gtk_text_view_get_buffer (text_view); - g_return_val_if_fail (buffer != NULL, FALSE); - - state = get_state (buffer); - - if ((state & E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP) != 0) { - gchar *url; - GtkTextIter iter; - - gtk_text_view_window_to_buffer_coords ( - text_view, - GTK_TEXT_WINDOW_WIDGET, - x, y, &x, &y); - gtk_text_view_get_iter_at_location (text_view, &iter, x, y); - - url = get_url_at_iter (buffer, &iter); - res = url && *url; - - if (res) { - gchar *str; - - /* To Translators: The text is concatenated to a form: "Ctrl-click to open a link http://www.example.com" */ - str = g_strconcat (_("Ctrl-click to open a link"), " ", url, NULL); - gtk_tooltip_set_text (tooltip, str); - g_free (str); - } - - g_free (url); - } - - return res; -} - -/* Links can be activated by pressing Enter. */ -static gboolean -textview_key_press_event (GtkWidget *text_view, - GdkEventKey *event) -{ - GtkTextIter iter; - GtkTextBuffer *buffer; - - if ((event->state & GDK_CONTROL_MASK) == 0) - return FALSE; - - switch (event->keyval) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); - gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer)); - if (invoke_link_if_present (buffer, &iter)) - return TRUE; - break; - - default: - break; - } - - return FALSE; -} - -static void -update_ctrl_state (GtkTextView *textview, - gboolean ctrl_is_down) -{ - GtkTextBuffer *buffer; - gint x, y; - - buffer = gtk_text_view_get_buffer (textview); - if (buffer) { - if (((get_state (buffer) & E_BUFFER_TAGGER_STATE_CTRL_DOWN) != 0) != (ctrl_is_down != FALSE)) { - update_state (buffer, E_BUFFER_TAGGER_STATE_CTRL_DOWN, ctrl_is_down != FALSE); - } - - get_pointer_position (textview, &x, &y); - gtk_text_view_window_to_buffer_coords (textview, GTK_TEXT_WINDOW_WIDGET, x, y, &x, &y); - update_mouse_cursor (textview, x, y); - } -} - -/* Links can also be activated by clicking. */ -static gboolean -textview_event_after (GtkTextView *textview, - GdkEvent *event) -{ - GtkTextIter start, end, iter; - GtkTextBuffer *buffer; - gint x, y; - GdkModifierType mt = 0; - guint event_button = 0; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - - g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); - - if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) { - guint event_keyval = 0; - - gdk_event_get_keyval (event, &event_keyval); - - switch (event_keyval) { - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - update_ctrl_state ( - textview, - event->type == GDK_KEY_PRESS); - break; - } - - return FALSE; - } - - if (!gdk_event_get_state (event, &mt)) { - GdkWindow *window; - GdkDisplay *display; - GdkDeviceManager *device_manager; - GdkDevice *device; - - window = gtk_widget_get_parent_window (GTK_WIDGET (textview)); - display = gdk_window_get_display (window); - device_manager = gdk_display_get_device_manager (display); - device = gdk_device_manager_get_client_pointer (device_manager); - - gdk_window_get_device_position (window, device, NULL, NULL, &mt); - } - - update_ctrl_state (textview, (mt & GDK_CONTROL_MASK) != 0); - - if (event->type != GDK_BUTTON_RELEASE) - return FALSE; - - gdk_event_get_button (event, &event_button); - gdk_event_get_coords (event, &event_x_win, &event_y_win); - - if (event_button != 1 || (mt & GDK_CONTROL_MASK) == 0) - return FALSE; - - buffer = gtk_text_view_get_buffer (textview); - - /* we shouldn't follow a link if the user has selected something */ - gtk_text_buffer_get_selection_bounds (buffer, &start, &end); - if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) - return FALSE; - - gtk_text_view_window_to_buffer_coords ( - textview, - GTK_TEXT_WINDOW_WIDGET, - event_x_win, event_y_win, &x, &y); - - gtk_text_view_get_iter_at_location (textview, &iter, x, y); - - invoke_link_if_present (buffer, &iter); - update_mouse_cursor (textview, x, y); - - return FALSE; -} - -static gboolean -textview_motion_notify_event (GtkTextView *textview, - GdkEventMotion *event) -{ - gint x, y; - - g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); - - gtk_text_view_window_to_buffer_coords ( - textview, - GTK_TEXT_WINDOW_WIDGET, - event->x, event->y, &x, &y); - - update_mouse_cursor (textview, x, y); - - return FALSE; -} - -static gboolean -textview_visibility_notify_event (GtkTextView *textview, - GdkEventVisibility *event) -{ - gint wx, wy, bx, by; - - g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); - - get_pointer_position (textview, &wx, &wy); - - gtk_text_view_window_to_buffer_coords ( - textview, - GTK_TEXT_WINDOW_WIDGET, - wx, wy, &bx, &by); - - update_mouse_cursor (textview, bx, by); - - return FALSE; -} - -void -e_buffer_tagger_connect (GtkTextView *textview) -{ - GtkTextBuffer *buffer; - GtkTextTagTable *tag_table; - GtkTextTag *tag; - - init_magic_links (); - - g_return_if_fail (textview != NULL); - g_return_if_fail (GTK_IS_TEXT_VIEW (textview)); - - buffer = gtk_text_view_get_buffer (textview); - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - - /* if tag is there already, then it is connected, thus claim */ - g_return_if_fail (tag == NULL); - - gtk_text_buffer_create_tag ( - buffer, E_BUFFER_TAGGER_LINK_TAG, - "foreground", "blue", - "underline", PANGO_UNDERLINE_SINGLE, - NULL); - - set_state (buffer, E_BUFFER_TAGGER_STATE_NONE); - - g_signal_connect ( - buffer, "insert-text", - G_CALLBACK (buffer_insert_text), NULL); - g_signal_connect ( - buffer, "delete-range", - G_CALLBACK (buffer_delete_range), NULL); - g_signal_connect ( - buffer, "notify::cursor-position", - G_CALLBACK (buffer_cursor_position), NULL); - - gtk_widget_set_has_tooltip (GTK_WIDGET (textview), TRUE); - - g_signal_connect ( - textview, "query-tooltip", - G_CALLBACK (textview_query_tooltip), NULL); - g_signal_connect ( - textview, "key-press-event", - G_CALLBACK (textview_key_press_event), NULL); - g_signal_connect ( - textview, "event-after", - G_CALLBACK (textview_event_after), NULL); - g_signal_connect ( - textview, "motion-notify-event", - G_CALLBACK (textview_motion_notify_event), NULL); - g_signal_connect ( - textview, "visibility-notify-event", - G_CALLBACK (textview_visibility_notify_event), NULL); -} - -void -e_buffer_tagger_disconnect (GtkTextView *textview) -{ - GtkTextBuffer *buffer; - GtkTextTagTable *tag_table; - GtkTextTag *tag; - - g_return_if_fail (textview != NULL); - g_return_if_fail (GTK_IS_TEXT_VIEW (textview)); - - buffer = gtk_text_view_get_buffer (textview); - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - - /* if tag is not there, then it is not connected, thus claim */ - g_return_if_fail (tag != NULL); - - gtk_text_tag_table_remove (tag_table, tag); - - set_state (buffer, E_BUFFER_TAGGER_STATE_NONE); - - g_signal_handlers_disconnect_by_func (buffer, G_CALLBACK (buffer_insert_text), NULL); - g_signal_handlers_disconnect_by_func (buffer, G_CALLBACK (buffer_delete_range), NULL); - g_signal_handlers_disconnect_by_func (buffer, G_CALLBACK (buffer_cursor_position), NULL); - - gtk_widget_set_has_tooltip (GTK_WIDGET (textview), FALSE); - - g_signal_handlers_disconnect_by_func (textview, G_CALLBACK (textview_query_tooltip), NULL); - g_signal_handlers_disconnect_by_func (textview, G_CALLBACK (textview_key_press_event), NULL); - g_signal_handlers_disconnect_by_func (textview, G_CALLBACK (textview_event_after), NULL); - g_signal_handlers_disconnect_by_func (textview, G_CALLBACK (textview_motion_notify_event), NULL); - g_signal_handlers_disconnect_by_func (textview, G_CALLBACK (textview_visibility_notify_event), NULL); -} - -void -e_buffer_tagger_update_tags (GtkTextView *textview) -{ - GtkTextBuffer *buffer; - GtkTextTagTable *tag_table; - GtkTextTag *tag; - - g_return_if_fail (textview != NULL); - g_return_if_fail (GTK_IS_TEXT_VIEW (textview)); - - buffer = gtk_text_view_get_buffer (textview); - tag_table = gtk_text_buffer_get_tag_table (buffer); - tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); - - /* if tag is not there, then it is not connected, thus claim */ - g_return_if_fail (tag != NULL); - - update_state (buffer, E_BUFFER_TAGGER_STATE_INSDEL | E_BUFFER_TAGGER_STATE_CHANGED, FALSE); - - markup_text (buffer); -} diff --git a/widgets/misc/e-buffer-tagger.h b/widgets/misc/e-buffer-tagger.h deleted file mode 100644 index 86e6710d01..0000000000 --- a/widgets/misc/e-buffer-tagger.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * e-buffer-tagger.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_BUFFER_TAGGER_H -#define E_BUFFER_TAGGER_H - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -void e_buffer_tagger_connect (GtkTextView *textview); -void e_buffer_tagger_disconnect (GtkTextView *textview); -void e_buffer_tagger_update_tags (GtkTextView *textview); - -G_END_DECLS - -#endif /* E_BUFFER_TAGGER_H */ diff --git a/widgets/misc/e-cal-source-config.c b/widgets/misc/e-cal-source-config.c deleted file mode 100644 index e57d0c6745..0000000000 --- a/widgets/misc/e-cal-source-config.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * e-cal-source-config.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-cal-source-config.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#include <e-util/e-util.h> - -#define E_CAL_SOURCE_CONFIG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CAL_SOURCE_CONFIG, ECalSourceConfigPrivate)) - -struct _ECalSourceConfigPrivate { - ECalClientSourceType source_type; - GtkWidget *color_button; - GtkWidget *default_button; -}; - -enum { - PROP_0, - PROP_SOURCE_TYPE -}; - -G_DEFINE_TYPE ( - ECalSourceConfig, - e_cal_source_config, - E_TYPE_SOURCE_CONFIG) - -static ESource * -cal_source_config_ref_default (ESourceConfig *config) -{ - ECalSourceConfigPrivate *priv; - ESourceRegistry *registry; - - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config); - registry = e_source_config_get_registry (config); - - if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) - return e_source_registry_ref_default_calendar (registry); - else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - return e_source_registry_ref_default_memo_list (registry); - else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS) - return e_source_registry_ref_default_task_list (registry); - - g_return_val_if_reached (NULL); -} - -static void -cal_source_config_set_default (ESourceConfig *config, - ESource *source) -{ - ECalSourceConfigPrivate *priv; - ESourceRegistry *registry; - - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config); - registry = e_source_config_get_registry (config); - - if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) - e_source_registry_set_default_calendar (registry, source); - else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - e_source_registry_set_default_memo_list (registry, source); - else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS) - e_source_registry_set_default_task_list (registry, source); -} - -static void -cal_source_config_set_source_type (ECalSourceConfig *config, - ECalClientSourceType source_type) -{ - config->priv->source_type = source_type; -} - -static void -cal_source_config_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SOURCE_TYPE: - cal_source_config_set_source_type ( - E_CAL_SOURCE_CONFIG (object), - g_value_get_enum (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cal_source_config_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SOURCE_TYPE: - g_value_set_enum ( - value, - e_cal_source_config_get_source_type ( - E_CAL_SOURCE_CONFIG (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cal_source_config_dispose (GObject *object) -{ - ECalSourceConfigPrivate *priv; - - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (object); - - if (priv->color_button != NULL) { - g_object_unref (priv->color_button); - priv->color_button = NULL; - } - - if (priv->default_button != NULL) { - g_object_unref (priv->default_button); - priv->default_button = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_cal_source_config_parent_class)->dispose (object); -} - -static void -cal_source_config_constructed (GObject *object) -{ - ECalSourceConfigPrivate *priv; - ESource *default_source; - ESource *original_source; - ESourceConfig *config; - GObjectClass *class; - GtkWidget *widget; - const gchar *label; - - /* Chain up to parent's constructed() method. */ - class = G_OBJECT_CLASS (e_cal_source_config_parent_class); - class->constructed (object); - - config = E_SOURCE_CONFIG (object); - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (object); - - widget = gtk_color_button_new (); - priv->color_button = g_object_ref_sink (widget); - gtk_widget_show (widget); - - switch (priv->source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - label = _("Mark as default calendar"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - label = _("Mark as default task list"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - label = _("Mark as default memo list"); - break; - default: - /* No need to translate this string. */ - label = "Invalid ECalSourceType value"; - g_warn_if_reached (); - } - - widget = gtk_check_button_new_with_label (label); - priv->default_button = g_object_ref_sink (widget); - gtk_widget_show (widget); - - default_source = cal_source_config_ref_default (config); - original_source = e_source_config_get_original_source (config); - - if (original_source != NULL) { - gboolean active; - - active = e_source_equal (original_source, default_source); - g_object_set (priv->default_button, "active", active, NULL); - } - - g_object_unref (default_source); - - e_source_config_insert_widget ( - config, NULL, _("Color:"), priv->color_button); - - e_source_config_insert_widget ( - config, NULL, NULL, priv->default_button); -} - -static const gchar * -cal_source_config_get_backend_extension_name (ESourceConfig *config) -{ - ECalSourceConfig *cal_config; - const gchar *extension_name; - - cal_config = E_CAL_SOURCE_CONFIG (config); - - switch (e_cal_source_config_get_source_type (cal_config)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - default: - g_return_val_if_reached (NULL); - } - - return extension_name; -} - -static GList * -cal_source_config_list_eligible_collections (ESourceConfig *config) -{ - GQueue trash = G_QUEUE_INIT; - GList *list, *link; - - /* Chain up to parent's list_eligible_collections() method. */ - list = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class)-> - list_eligible_collections (config); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - ESourceCollection *extension; - const gchar *extension_name; - - extension_name = E_SOURCE_EXTENSION_COLLECTION; - extension = e_source_get_extension (source, extension_name); - - if (!e_source_collection_get_calendar_enabled (extension)) - g_queue_push_tail (&trash, link); - } - - /* Remove ineligible collections from the list. */ - while ((link = g_queue_pop_head (&trash)) != NULL) { - g_object_unref (link->data); - list = g_list_delete_link (list, link); - } - - return list; -} - -static void -cal_source_config_init_candidate (ESourceConfig *config, - ESource *scratch_source) -{ - ECalSourceConfigPrivate *priv; - ESourceConfigClass *class; - ESourceExtension *extension; - const gchar *extension_name; - - /* Chain up to parent's init_candidate() method. */ - class = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class); - class->init_candidate (config, scratch_source); - - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config); - - extension_name = e_source_config_get_backend_extension_name (config); - extension = e_source_get_extension (scratch_source, extension_name); - - g_object_bind_property_full ( - extension, "color", - priv->color_button, "color", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE, - e_binding_transform_string_to_color, - e_binding_transform_color_to_string, - NULL, (GDestroyNotify) NULL); -} - -static void -cal_source_config_commit_changes (ESourceConfig *config, - ESource *scratch_source) -{ - ECalSourceConfigPrivate *priv; - GtkToggleButton *toggle_button; - ESourceConfigClass *class; - ESource *default_source; - - priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config); - toggle_button = GTK_TOGGLE_BUTTON (priv->default_button); - - /* Chain up to parent's commit_changes() method. */ - class = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class); - class->commit_changes (config, scratch_source); - - default_source = cal_source_config_ref_default (config); - - /* The default setting is a little tricky to get right. If - * the toggle button is active, this ESource is now the default. - * That much is simple. But if the toggle button is NOT active, - * then we have to inspect the old default. If this ESource WAS - * the default, reset the default to 'system'. If this ESource - * WAS NOT the old default, leave it alone. */ - if (gtk_toggle_button_get_active (toggle_button)) - cal_source_config_set_default (config, scratch_source); - else if (e_source_equal (scratch_source, default_source)) - cal_source_config_set_default (config, NULL); - - g_object_unref (default_source); -} - -static void -e_cal_source_config_class_init (ECalSourceConfigClass *class) -{ - GObjectClass *object_class; - ESourceConfigClass *source_config_class; - - g_type_class_add_private (class, sizeof (ECalSourceConfigPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = cal_source_config_set_property; - object_class->get_property = cal_source_config_get_property; - object_class->dispose = cal_source_config_dispose; - object_class->constructed = cal_source_config_constructed; - - source_config_class = E_SOURCE_CONFIG_CLASS (class); - source_config_class->get_backend_extension_name = - cal_source_config_get_backend_extension_name; - source_config_class->list_eligible_collections = - cal_source_config_list_eligible_collections; - source_config_class->init_candidate = cal_source_config_init_candidate; - source_config_class->commit_changes = cal_source_config_commit_changes; - - g_object_class_install_property ( - object_class, - PROP_SOURCE_TYPE, - g_param_spec_enum ( - "source-type", - "Source Type", - "The iCalendar object type", - E_TYPE_CAL_CLIENT_SOURCE_TYPE, - E_CAL_CLIENT_SOURCE_TYPE_EVENTS, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_cal_source_config_init (ECalSourceConfig *config) -{ - config->priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config); -} - -GtkWidget * -e_cal_source_config_new (ESourceRegistry *registry, - ESource *original_source, - ECalClientSourceType source_type) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - if (original_source != NULL) - g_return_val_if_fail (E_IS_SOURCE (original_source), NULL); - - return g_object_new ( - E_TYPE_CAL_SOURCE_CONFIG, "registry", registry, - "original-source", original_source, "source-type", - source_type, NULL); -} - -ECalClientSourceType -e_cal_source_config_get_source_type (ECalSourceConfig *config) -{ - g_return_val_if_fail (E_IS_CAL_SOURCE_CONFIG (config), 0); - - return config->priv->source_type; -} - -void -e_cal_source_config_add_offline_toggle (ECalSourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget; - ESourceExtension *extension; - const gchar *extension_name; - const gchar *label; - - g_return_if_fail (E_IS_CAL_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_OFFLINE; - extension = e_source_get_extension (scratch_source, extension_name); - - switch (e_cal_source_config_get_source_type (config)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - label = _("Copy calendar contents locally " - "for offline operation"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - label = _("Copy task list contents locally " - "for offline operation"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - label = _("Copy memo list contents locally " - "for offline operation"); - break; - default: - g_return_if_reached (); - } - - widget = gtk_check_button_new_with_label (label); - e_source_config_insert_widget ( - E_SOURCE_CONFIG (config), scratch_source, NULL, widget); - gtk_widget_show (widget); - - g_object_bind_property ( - extension, "stay-synchronized", - widget, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} diff --git a/widgets/misc/e-cal-source-config.h b/widgets/misc/e-cal-source-config.h deleted file mode 100644 index 4db861069e..0000000000 --- a/widgets/misc/e-cal-source-config.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * e-cal-source-config.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_CAL_SOURCE_CONFIG_H -#define E_CAL_SOURCE_CONFIG_H - -#include <libecal/libecal.h> -#include <misc/e-source-config.h> - -/* Standard GObject macros */ -#define E_TYPE_CAL_SOURCE_CONFIG \ - (e_cal_source_config_get_type ()) -#define E_CAL_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CAL_SOURCE_CONFIG, ECalSourceConfig)) -#define E_CAL_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CAL_SOURCE_CONFIG, ECalSourceConfigClass)) -#define E_IS_CAL_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CAL_SOURCE_CONFIG)) -#define E_IS_CAL_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CAL_SOURCE_CONFIG)) -#define E_CAL_SOURCE_CONFIG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CAL_SOURCE_CONFIG, ECalSourceConfigClass)) - -G_BEGIN_DECLS - -typedef struct _ECalSourceConfig ECalSourceConfig; -typedef struct _ECalSourceConfigClass ECalSourceConfigClass; -typedef struct _ECalSourceConfigPrivate ECalSourceConfigPrivate; - -struct _ECalSourceConfig { - ESourceConfig parent; - ECalSourceConfigPrivate *priv; -}; - -struct _ECalSourceConfigClass { - ESourceConfigClass parent_class; -}; - -GType e_cal_source_config_get_type (void) G_GNUC_CONST; -GtkWidget * e_cal_source_config_new (ESourceRegistry *registry, - ESource *original_source, - ECalClientSourceType source_type); -ECalClientSourceType - e_cal_source_config_get_source_type - (ECalSourceConfig *config); -void e_cal_source_config_add_offline_toggle - (ECalSourceConfig *config, - ESource *scratch_source); - -G_END_DECLS - -#endif /* E_CAL_SOURCE_CONFIG_H */ diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c deleted file mode 100644 index 96b39529b1..0000000000 --- a/widgets/misc/e-calendar-item.c +++ /dev/null @@ -1,3772 +0,0 @@ -/* - * ECalendarItem - canvas item displaying a calendar. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <libebackend/libebackend.h> - -#include "e-calendar-item.h" -#include "ea-widgets.h" - -#include <time.h> -#include <stdlib.h> -#include <string.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <glib/gi18n.h> -#include <e-util/e-util.h> - -static const gint e_calendar_item_days_in_month[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -#define DAYS_IN_MONTH(year, month) \ - e_calendar_item_days_in_month[month] + (((month) == 1 \ - && ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))) ? 1 : 0) - -static void e_calendar_item_dispose (GObject *object); -static void e_calendar_item_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void e_calendar_item_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void e_calendar_item_realize (GnomeCanvasItem *item); -static void e_calendar_item_unmap (GnomeCanvasItem *item); -static void e_calendar_item_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags); -static void e_calendar_item_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height); -static void e_calendar_item_draw_month (ECalendarItem *calitem, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height, - gint row, - gint col); -static void e_calendar_item_draw_day_numbers - (ECalendarItem *calitem, - cairo_t *cr, - gint width, - gint height, - gint row, - gint col, - gint year, - gint month, - gint start_weekday, - gint cells_x, - gint cells_y); -static GnomeCanvasItem *e_calendar_item_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy); -static void e_calendar_item_stop_selecting (ECalendarItem *calitem, - guint32 time); -static void e_calendar_item_selection_add_days - (ECalendarItem *calitem, - gint n_days, - gboolean multi_selection); -static gint e_calendar_item_key_press_event (ECalendarItem *item, - GdkEvent *event); -static gint e_calendar_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static void e_calendar_item_bounds (GnomeCanvasItem *item, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2); - -static gboolean e_calendar_item_button_press (ECalendarItem *calitem, - GdkEvent *event); -static gboolean e_calendar_item_button_release (ECalendarItem *calitem, - GdkEvent *event); -static gboolean e_calendar_item_motion (ECalendarItem *calitem, - GdkEvent *event); - -static gboolean e_calendar_item_convert_position_to_day - (ECalendarItem *calitem, - gint x, - gint y, - gboolean round_empty_positions, - gint *month_offset, - gint *day, - gboolean *entire_week); -static void e_calendar_item_get_month_info (ECalendarItem *calitem, - gint row, - gint col, - gint *first_day_offset, - gint *days_in_month, - gint *days_in_prev_month); -static void e_calendar_item_recalc_sizes (ECalendarItem *calitem); - -static void e_calendar_item_get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gboolean *italic); -static void e_calendar_item_check_selection_end - (ECalendarItem *calitem, - gint start_month, - gint start_day, - gint *end_month, - gint *end_day); -static void e_calendar_item_check_selection_start - (ECalendarItem *calitem, - gint *start_month, - gint *start_day, - gint end_month, - gint end_day); -static void e_calendar_item_add_days_to_selection - (ECalendarItem *calitem, - gint days); -static void e_calendar_item_round_up_selection - (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static void e_calendar_item_round_down_selection - (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static gint e_calendar_item_get_inclusive_days - (ECalendarItem *calitem, - gint start_month_offset, - gint start_day, - gint end_month_offset, - gint end_day); -static void e_calendar_item_ensure_valid_day - (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static gboolean e_calendar_item_ensure_days_visible - (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - gboolean emission); -static void e_calendar_item_show_popup_menu (ECalendarItem *calitem, - GdkEvent *button_event, - gint month_offset); -static void e_calendar_item_on_menu_item_activate - (GtkWidget *menuitem, - ECalendarItem *calitem); -static void e_calendar_item_position_menu (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data); -static void e_calendar_item_date_range_changed - (ECalendarItem *calitem); -static void e_calendar_item_queue_signal_emission - (ECalendarItem *calitem); -static gboolean e_calendar_item_signal_emission_idle_cb - (gpointer data); -static void e_calendar_item_set_selection_if_emission - (ECalendarItem *calitem, - const GDate *start_date, - const GDate *end_date, - gboolean emission); - -/* Our arguments. */ -enum { - PROP_0, - PROP_YEAR, - PROP_MONTH, - PROP_X1, - PROP_Y1, - PROP_X2, - PROP_Y2, - PROP_FONT_DESC, - PROP_WEEK_NUMBER_FONT, - PROP_WEEK_NUMBER_FONT_DESC, - PROP_ROW_HEIGHT, - PROP_COLUMN_WIDTH, - PROP_MINIMUM_ROWS, - PROP_MINIMUM_COLUMNS, - PROP_MAXIMUM_ROWS, - PROP_MAXIMUM_COLUMNS, - PROP_WEEK_START_DAY, - PROP_SHOW_WEEK_NUMBERS, - PROP_KEEP_WDAYS_ON_WEEKNUM_CLICK, - PROP_MAXIMUM_DAYS_SELECTED, - PROP_DAYS_TO_START_WEEK_SELECTION, - PROP_MOVE_SELECTION_WHEN_MOVING, - PROP_PRESERVE_DAY_WHEN_MOVING, - PROP_DISPLAY_POPUP -}; - -enum { - DATE_RANGE_CHANGED, - SELECTION_CHANGED, - SELECTION_PREVIEW_CHANGED, - LAST_SIGNAL -}; - -static guint e_calendar_item_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE_WITH_CODE ( - ECalendarItem, - e_calendar_item, - GNOME_TYPE_CANVAS_ITEM, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -static void -e_calendar_item_class_init (ECalendarItemClass *class) -{ - GObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = e_calendar_item_dispose; - object_class->get_property = e_calendar_item_get_property; - object_class->set_property = e_calendar_item_set_property; - - item_class = GNOME_CANVAS_ITEM_CLASS (class); - item_class->realize = e_calendar_item_realize; - item_class->unmap = e_calendar_item_unmap; - item_class->update = e_calendar_item_update; - item_class->draw = e_calendar_item_draw; - item_class->point = e_calendar_item_point; - item_class->event = e_calendar_item_event; - item_class->bounds = e_calendar_item_bounds; - - class->date_range_changed = NULL; - class->selection_changed = NULL; - class->selection_preview_changed = NULL; - - g_object_class_install_property ( - object_class, - PROP_YEAR, - g_param_spec_int ( - "year", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MONTH, - g_param_spec_int ( - "month", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_X1, - g_param_spec_double ( - "x1", - NULL, - NULL, - -G_MAXDOUBLE, - G_MAXDOUBLE, - 0., - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_Y1, - g_param_spec_double ( - "y1", - NULL, - NULL, - -G_MAXDOUBLE, - G_MAXDOUBLE, - 0., - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_X2, - g_param_spec_double ( - "x2", - NULL, - NULL, - -G_MAXDOUBLE, - G_MAXDOUBLE, - 0., - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_Y2, - g_param_spec_double ( - "y2", - NULL, - NULL, - -G_MAXDOUBLE, - G_MAXDOUBLE, - 0., - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FONT_DESC, - g_param_spec_boxed ( - "font_desc", - NULL, - NULL, - PANGO_TYPE_FONT_DESCRIPTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WEEK_NUMBER_FONT_DESC, - g_param_spec_boxed ( - "week_number_font_desc", - NULL, - NULL, - PANGO_TYPE_FONT_DESCRIPTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ROW_HEIGHT, - g_param_spec_int ( - "row_height", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_COLUMN_WIDTH, - g_param_spec_int ( - "column_width", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_ROWS, - g_param_spec_int ( - "minimum_rows", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_COLUMNS, - g_param_spec_int ( - "minimum_columns", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAXIMUM_ROWS, - g_param_spec_int ( - "maximum_rows", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAXIMUM_COLUMNS, - g_param_spec_int ( - "maximum_columns", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WEEK_START_DAY, - g_param_spec_int ( - "week_start_day", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_WEEK_NUMBERS, - g_param_spec_boolean ( - "show_week_numbers", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_KEEP_WDAYS_ON_WEEKNUM_CLICK, - g_param_spec_boolean ( - "keep_wdays_on_weeknum_click", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAXIMUM_DAYS_SELECTED, - g_param_spec_int ( - "maximum_days_selected", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_DAYS_TO_START_WEEK_SELECTION, - g_param_spec_int ( - "days_to_start_week_selection", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MOVE_SELECTION_WHEN_MOVING, - g_param_spec_boolean ( - "move_selection_when_moving", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_PRESERVE_DAY_WHEN_MOVING, - g_param_spec_boolean ( - "preserve_day_when_moving", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_DISPLAY_POPUP, - g_param_spec_boolean ( - "display_popup", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - e_calendar_item_signals[DATE_RANGE_CHANGED] = g_signal_new ( - "date_range_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ECalendarItemClass, date_range_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_calendar_item_signals[SELECTION_CHANGED] = g_signal_new ( - "selection_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ECalendarItemClass, selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_calendar_item_signals[SELECTION_PREVIEW_CHANGED] = g_signal_new ( - "selection_preview_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarItemClass, selection_preview_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_calendar_item_a11y_init (); -} - -static void -e_calendar_item_init (ECalendarItem *calitem) -{ - struct tm *tmp_tm; - time_t t; - - /* Set the default time to the current month. */ - t = time (NULL); - tmp_tm = localtime (&t); - calitem->year = tmp_tm->tm_year + 1900; - calitem->month = tmp_tm->tm_mon; - - calitem->styles = NULL; - - calitem->min_cols = 1; - calitem->min_rows = 1; - calitem->max_cols = -1; - calitem->max_rows = -1; - - calitem->rows = 0; - calitem->cols = 0; - - calitem->show_week_numbers = FALSE; - calitem->keep_wdays_on_weeknum_click = FALSE; - calitem->week_start_day = 0; - calitem->expand = TRUE; - calitem->max_days_selected = 1; - calitem->days_to_start_week_selection = -1; - calitem->move_selection_when_moving = TRUE; - calitem->preserve_day_when_moving = FALSE; - calitem->display_popup = TRUE; - - calitem->x1 = 0.0; - calitem->y1 = 0.0; - calitem->x2 = 0.0; - calitem->y2 = 0.0; - - calitem->selecting = FALSE; - calitem->selecting_axis = NULL; - - calitem->selection_set = FALSE; - - calitem->selection_changed = FALSE; - calitem->date_range_changed = FALSE; - - calitem->style_callback = NULL; - calitem->style_callback_data = NULL; - calitem->style_callback_destroy = NULL; - - calitem->time_callback = NULL; - calitem->time_callback_data = NULL; - calitem->time_callback_destroy = NULL; - - calitem->signal_emission_idle_id = 0; -} - -static void -e_calendar_item_dispose (GObject *object) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (object); - - e_calendar_item_set_style_callback (calitem, NULL, NULL, NULL); - e_calendar_item_set_get_time_callback (calitem, NULL, NULL, NULL); - - if (calitem->styles) { - g_free (calitem->styles); - calitem->styles = NULL; - } - - if (calitem->signal_emission_idle_id > 0) { - g_source_remove (calitem->signal_emission_idle_id); - calitem->signal_emission_idle_id = -1; - } - - if (calitem->font_desc) { - pango_font_description_free (calitem->font_desc); - calitem->font_desc = NULL; - } - - if (calitem->week_number_font_desc) { - pango_font_description_free (calitem->week_number_font_desc); - calitem->week_number_font_desc = NULL; - } - - if (calitem->selecting_axis) - g_free (calitem->selecting_axis); - - G_OBJECT_CLASS (e_calendar_item_parent_class)->dispose (object); -} - -static void -e_calendar_item_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (object); - - switch (property_id) { - case PROP_YEAR: - g_value_set_int (value, calitem->year); - return; - case PROP_MONTH: - g_value_set_int (value, calitem->month); - return; - case PROP_X1: - g_value_set_double (value, calitem->x1); - return; - case PROP_Y1: - g_value_set_double (value, calitem->y1); - return; - case PROP_X2: - g_value_set_double (value, calitem->x2); - return; - case PROP_Y2: - g_value_set_double (value, calitem->y2); - return; - case PROP_FONT_DESC: - g_value_set_boxed (value, calitem->font_desc); - return; - case PROP_WEEK_NUMBER_FONT_DESC: - g_value_set_boxed (value, calitem->week_number_font_desc); - return; - case PROP_ROW_HEIGHT: - e_calendar_item_recalc_sizes (calitem); - g_value_set_int (value, calitem->min_month_height); - return; - case PROP_COLUMN_WIDTH: - e_calendar_item_recalc_sizes (calitem); - g_value_set_int (value, calitem->min_month_width); - return; - case PROP_MINIMUM_ROWS: - g_value_set_int (value, calitem->min_rows); - return; - case PROP_MINIMUM_COLUMNS: - g_value_set_int (value, calitem->min_cols); - return; - case PROP_MAXIMUM_ROWS: - g_value_set_int (value, calitem->max_rows); - return; - case PROP_MAXIMUM_COLUMNS: - g_value_set_int (value, calitem->max_cols); - return; - case PROP_WEEK_START_DAY: - g_value_set_int (value, calitem->week_start_day); - return; - case PROP_SHOW_WEEK_NUMBERS: - g_value_set_boolean (value, calitem->show_week_numbers); - return; - case PROP_KEEP_WDAYS_ON_WEEKNUM_CLICK: - g_value_set_boolean (value, calitem->keep_wdays_on_weeknum_click); - return; - case PROP_MAXIMUM_DAYS_SELECTED: - g_value_set_int (value, e_calendar_item_get_max_days_sel (calitem)); - return; - case PROP_DAYS_TO_START_WEEK_SELECTION: - g_value_set_int (value, e_calendar_item_get_days_start_week_sel (calitem)); - return; - case PROP_MOVE_SELECTION_WHEN_MOVING: - g_value_set_boolean (value, calitem->move_selection_when_moving); - return; - case PROP_PRESERVE_DAY_WHEN_MOVING: - g_value_set_boolean (value, calitem->preserve_day_when_moving); - return; - case PROP_DISPLAY_POPUP: - g_value_set_boolean (value, e_calendar_item_get_display_popup (calitem)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_calendar_item_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - ECalendarItem *calitem; - PangoFontDescription *font_desc; - gdouble dvalue; - gint ivalue; - gboolean bvalue; - - item = GNOME_CANVAS_ITEM (object); - calitem = E_CALENDAR_ITEM (object); - - switch (property_id) { - case PROP_YEAR: - ivalue = g_value_get_int (value); - e_calendar_item_set_first_month ( - calitem, ivalue, calitem->month); - return; - case PROP_MONTH: - ivalue = g_value_get_int (value); - e_calendar_item_set_first_month ( - calitem, calitem->year, ivalue); - return; - case PROP_X1: - dvalue = g_value_get_double (value); - if (calitem->x1 != dvalue) { - calitem->x1 = dvalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_Y1: - dvalue = g_value_get_double (value); - if (calitem->y1 != dvalue) { - calitem->y1 = dvalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_X2: - dvalue = g_value_get_double (value); - if (calitem->x2 != dvalue) { - calitem->x2 = dvalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_Y2: - dvalue = g_value_get_double (value); - if (calitem->y2 != dvalue) { - calitem->y2 = dvalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_FONT_DESC: - font_desc = g_value_get_boxed (value); - if (calitem->font_desc) - pango_font_description_free (calitem->font_desc); - calitem->font_desc = pango_font_description_copy (font_desc); - gnome_canvas_item_request_update (item); - return; - case PROP_WEEK_NUMBER_FONT_DESC: - font_desc = g_value_get_boxed (value); - if (calitem->week_number_font_desc) - pango_font_description_free (calitem->week_number_font_desc); - calitem->week_number_font_desc = pango_font_description_copy (font_desc); - gnome_canvas_item_request_update (item); - return; - case PROP_MINIMUM_ROWS: - ivalue = g_value_get_int (value); - ivalue = MAX (1, ivalue); - if (calitem->min_rows != ivalue) { - calitem->min_rows = ivalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_MINIMUM_COLUMNS: - ivalue = g_value_get_int (value); - ivalue = MAX (1, ivalue); - if (calitem->min_cols != ivalue) { - calitem->min_cols = ivalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_MAXIMUM_ROWS: - ivalue = g_value_get_int (value); - if (calitem->max_rows != ivalue) { - calitem->max_rows = ivalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_MAXIMUM_COLUMNS: - ivalue = g_value_get_int (value); - if (calitem->max_cols != ivalue) { - calitem->max_cols = ivalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_WEEK_START_DAY: - ivalue = g_value_get_int (value); - if (calitem->week_start_day != ivalue) { - calitem->week_start_day = ivalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_SHOW_WEEK_NUMBERS: - bvalue = g_value_get_boolean (value); - if (calitem->show_week_numbers != bvalue) { - calitem->show_week_numbers = bvalue; - gnome_canvas_item_request_update (item); - } - return; - case PROP_KEEP_WDAYS_ON_WEEKNUM_CLICK: - calitem->keep_wdays_on_weeknum_click = g_value_get_boolean (value); - return; - case PROP_MAXIMUM_DAYS_SELECTED: - ivalue = g_value_get_int (value); - e_calendar_item_set_max_days_sel (calitem, ivalue); - return; - case PROP_DAYS_TO_START_WEEK_SELECTION: - ivalue = g_value_get_int (value); - e_calendar_item_set_days_start_week_sel (calitem, ivalue); - return; - case PROP_MOVE_SELECTION_WHEN_MOVING: - bvalue = g_value_get_boolean (value); - calitem->move_selection_when_moving = bvalue; - return; - case PROP_PRESERVE_DAY_WHEN_MOVING: - bvalue = g_value_get_boolean (value); - calitem->preserve_day_when_moving = bvalue; - return; - case PROP_DISPLAY_POPUP: - bvalue = g_value_get_boolean (value); - e_calendar_item_set_display_popup (calitem, bvalue); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_calendar_item_realize (GnomeCanvasItem *item) -{ - ECalendarItem *calitem; - - if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize) (item); - - calitem = E_CALENDAR_ITEM (item); - - e_calendar_item_style_set (GTK_WIDGET (item->canvas), calitem); - - e_extensible_load_extensions (E_EXTENSIBLE (calitem)); -} - -static void -e_calendar_item_unmap (GnomeCanvasItem *item) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (item); - - if (calitem->selecting) { - gnome_canvas_item_ungrab (item, GDK_CURRENT_TIME); - calitem->selecting = FALSE; - } - - if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap) - (* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap) (item); -} - -static void -e_calendar_item_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - GnomeCanvasItemClass *item_class; - ECalendarItem *calitem; - GtkStyle *style; - gint char_height, width, height, space, space_per_cal, space_per_cell; - gint rows, cols, xthickness, ythickness; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - - item_class = GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class); - if (item_class->update != NULL) - item_class->update (item, i2c, flags); - - calitem = E_CALENDAR_ITEM (item); - style = gtk_widget_get_style (GTK_WIDGET (item->canvas)); - xthickness = style->xthickness; - ythickness = style->ythickness; - - item->x1 = calitem->x1; - item->y1 = calitem->y1; - item->x2 = calitem->x2 >= calitem->x1 ? calitem->x2 : calitem->x1; - item->y2 = calitem->y2 >= calitem->y1 ? calitem->y2 : calitem->y1; - - /* Set up Pango prerequisites */ - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (item->canvas)); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - /* - * Calculate the new layout of the calendar. - */ - - /* Make sure the minimum row width & cell height and the widths of - * all the digits and characters are up to date. */ - e_calendar_item_recalc_sizes (calitem); - - /* Calculate how many rows & cols we can fit in. */ - width = item->x2 - item->x1; - height = item->y2 - item->y1; - - width -= xthickness * 2; - height -= ythickness * 2; - - if (calitem->min_month_height == 0) - rows = 1; - else - rows = height / calitem->min_month_height; - rows = MAX (rows, calitem->min_rows); - if (calitem->max_rows > 0) - rows = MIN (rows, calitem->max_rows); - - if (calitem->min_month_width == 0) - cols = 1; - else - cols = width / calitem->min_month_width; - cols = MAX (cols, calitem->min_cols); - if (calitem->max_cols > 0) - cols = MIN (cols, calitem->max_cols); - - if (rows != calitem->rows || cols != calitem->cols) - e_calendar_item_date_range_changed (calitem); - - calitem->rows = rows; - calitem->cols = cols; - - /* Split up the empty space according to the configuration. - * If the calendar is set to expand, we divide the space between the - * cells and the spaces around the calendar, otherwise we place the - * calendars in the center of the available area. */ - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - calitem->month_width = calitem->min_month_width; - calitem->month_height = calitem->min_month_height; - calitem->cell_width = MAX (calitem->max_day_width, (calitem->max_digit_width * 2)) - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - calitem->cell_height = char_height - + E_CALENDAR_ITEM_MIN_CELL_YPAD; - calitem->month_tpad = 0; - calitem->month_bpad = 0; - calitem->month_lpad = 0; - calitem->month_rpad = 0; - - space = height - calitem->rows * calitem->month_height; - if (space > 0) { - space_per_cal = space / calitem->rows; - calitem->month_height += space_per_cal; - - if (calitem->expand) { - space_per_cell = space_per_cal / E_CALENDAR_ROWS_PER_MONTH; - calitem->cell_height += space_per_cell; - space_per_cal -= space_per_cell * E_CALENDAR_ROWS_PER_MONTH; - } - - calitem->month_tpad = space_per_cal / 2; - calitem->month_bpad = space_per_cal - calitem->month_tpad; - } - - space = width - calitem->cols * calitem->month_width; - if (space > 0) { - space_per_cal = space / calitem->cols; - calitem->month_width += space_per_cal; - space -= space_per_cal * calitem->cols; - - if (calitem->expand) { - space_per_cell = space_per_cal / E_CALENDAR_COLS_PER_MONTH; - calitem->cell_width += space_per_cell; - space_per_cal -= space_per_cell * E_CALENDAR_COLS_PER_MONTH; - } - - calitem->month_lpad = space_per_cal / 2; - calitem->month_rpad = space_per_cal - calitem->month_lpad; - } - - space = MAX (0, space); - calitem->x_offset = space / 2; - - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, - item->x2, item->y2); - - pango_font_metrics_unref (font_metrics); -} - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ -static void -e_calendar_item_draw (GnomeCanvasItem *canvas_item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - ECalendarItem *calitem; - GtkWidget *widget; - GtkStyleContext *style_context; - gint char_height, row, col, row_y, bar_height, col_x; - const PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - GdkRGBA bg_color; - GtkBorder border; - -#if 0 - g_print ( - "In e_calendar_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - calitem = E_CALENDAR_ITEM (canvas_item); - - widget = GTK_WIDGET (canvas_item->canvas); - style_context = gtk_widget_get_style_context (widget); - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = gtk_style_context_get_font ( - style_context, GTK_STATE_FLAG_NORMAL); - pango_context = gtk_widget_get_pango_context ( - GTK_WIDGET (canvas_item->canvas)); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - gtk_style_context_get_background_color ( - style_context, GTK_STATE_NORMAL, &bg_color); - - gtk_style_context_get_border ( - style_context, GTK_STATE_NORMAL, &border); - - /* Clear the entire background. */ - cairo_save (cr); - gdk_cairo_set_source_rgba (cr, &bg_color); - cairo_rectangle ( - cr, calitem->x1 - x, calitem->y1 - y, - calitem->x2 - calitem->x1 + 1, - calitem->y2 - calitem->y1 + 1); - cairo_fill (cr); - cairo_restore (cr); - - /* Draw the shadow around the entire item. */ - gtk_style_context_save (style_context); - gtk_style_context_add_class ( - style_context, GTK_STYLE_CLASS_ENTRY); - cairo_save (cr); - gtk_render_frame ( - style_context, cr, - (gdouble) calitem->x1 - x, - (gdouble) calitem->y1 - y, - (gdouble) calitem->x2 - calitem->x1 + 1, - (gdouble) calitem->y2 - calitem->y1 + 1); - cairo_restore (cr); - gtk_style_context_restore (style_context); - - row_y = canvas_item->y1 + border.top; - bar_height = - border.top + border.bottom + - E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + char_height + - E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME; - - for (row = 0; row < calitem->rows; row++) { - /* Draw the background for the title bars and the shadow around - * it, and the vertical lines between columns. */ - - cairo_save (cr); - gdk_cairo_set_source_rgba (cr, &bg_color); - cairo_rectangle ( - cr, calitem->x1 + border.left - x, - row_y - y, - calitem->x2 - calitem->x1 + 1 - - (border.left + border.right), - bar_height); - cairo_fill (cr); - cairo_restore (cr); - - gtk_style_context_save (style_context); - gtk_style_context_add_class ( - style_context, GTK_STYLE_CLASS_HEADER); - cairo_save (cr); - gtk_render_frame ( - style_context, cr, - (gdouble) calitem->x1 + border.left - x, - (gdouble) row_y - y, - (gdouble) calitem->x2 - calitem->x1 + 1 - - (border.left + border.right), - (gdouble) bar_height); - cairo_restore (cr); - gtk_style_context_restore (style_context); - - for (col = 0; col < calitem->cols; col++) { - if (col != 0) { - col_x = calitem->x1 + calitem->x_offset - + calitem->month_width * col; - - gtk_style_context_save (style_context); - gtk_style_context_add_class ( - style_context, - GTK_STYLE_CLASS_SEPARATOR); - cairo_save (cr); - gtk_render_line ( - style_context, cr, - (gdouble) col_x - 1 - x, - (gdouble) row_y + border.top + 1 - y, - (gdouble) row_y + bar_height - - border.bottom - 2 - y, - (gdouble) col_x - x); - cairo_restore (cr); - gtk_style_context_restore (style_context); - } - - e_calendar_item_draw_month ( - calitem, cr, x, y, - width, height, row, col); - } - - row_y += calitem->month_height; - } - - pango_font_metrics_unref (font_metrics); -} - -static void -layout_set_day_text (ECalendarItem *calitem, - PangoLayout *layout, - gint day_index) -{ - const gchar *abbr_name; - - /* day_index: 0 = Monday ... 6 = Sunday */ - abbr_name = e_get_weekday_name (day_index + 1, TRUE); - pango_layout_set_text (layout, abbr_name, -1); -} - -static void -e_calendar_item_draw_month (ECalendarItem *calitem, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height, - gint row, - gint col) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - PangoFontDescription *font_desc; - struct tm tmp_tm; - GdkRectangle clip_rect; - gint char_height, xthickness, ythickness, start_weekday; - gint year, month; - gint month_x, month_y, month_w, month_h; - gint min_x, max_x, text_x, text_y; - gint day, day_index, cells_x, cells_y, min_cell_width, text_width, arrow_button_size; - gint clip_width, clip_height; - gchar buffer[64]; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - -#if 0 - g_print ( - "In e_calendar_item_draw_month: %i,%i %ix%i row:%i col:%i\n", - x, y, width, height, row, col); -#endif - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = gtk_widget_get_style (widget); - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - xthickness = style->xthickness; - ythickness = style->ythickness; - arrow_button_size = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) - + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + 2 * xthickness; - - pango_font_metrics_unref (font_metrics); - - /* Calculate the top-left position of the entire month display. */ - month_x = item->x1 + xthickness + calitem->x_offset - + ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - ? (calitem->cols - 1 - col) : col) * calitem->month_width - x; - month_w = item->x2 - item->x1 - xthickness * 2; - month_w = MIN (month_w, calitem->month_width); - month_y = item->y1 + ythickness + row * calitem->month_height - y; - month_h = item->y2 - item->y1 - ythickness * 2; - month_h = MIN (month_h, calitem->month_height); - - /* Just return if the month is outside the given area. */ - if (month_x >= width || month_x + calitem->month_width <= 0 - || month_y >= height || month_y + calitem->month_height <= 0) - return; - - month = calitem->month + row * calitem->cols + col; - year = calitem->year + month / 12; - month %= 12; - - /* Draw the month name & year, with clipping. Note that the top row - * needs extra space around it for the buttons. */ - - layout = gtk_widget_create_pango_layout (widget, NULL); - - if (row == 0 && col == 0) - min_x = E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME_WITH_BUTTON; - else - min_x = E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME; - - max_x = month_w; - if (row == 0 && col == 0) - max_x -= E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME_WITH_BUTTON; - else - max_x -= E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME; - - text_y = month_y + style->ythickness - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME; - clip_rect.x = month_x + min_x; - clip_rect.x = MAX (0, clip_rect.x); - clip_rect.y = MAX (0, text_y); - - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - start_weekday = (tmp_tm.tm_wday + 6) % 7; - - if (month_x + max_x - clip_rect.x > 0) { - cairo_save (cr); - - clip_rect.width = month_x + max_x - clip_rect.x; - clip_rect.height = text_y + char_height - clip_rect.y; - gdk_cairo_rectangle (cr, &clip_rect); - cairo_clip (cr); - - gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]); - - if (row == 0 && col == 0) { - PangoLayout *layout_yr; - gchar buffer_yr[64]; - gdouble max_width; - - layout_yr = gtk_widget_create_pango_layout (widget, NULL); - - /* This is a strftime() format. %B = Month name. */ - e_utf8_strftime (buffer, sizeof (buffer), C_("CalItem", "%B"), &tmp_tm); - /* This is a strftime() format. %Y = Year. */ - e_utf8_strftime (buffer_yr, sizeof (buffer_yr), C_("CalItem", "%Y"), &tmp_tm); - - pango_layout_set_font_description (layout, font_desc); - pango_layout_set_text (layout, buffer, -1); - - pango_layout_set_font_description (layout_yr, font_desc); - pango_layout_set_text (layout_yr, buffer_yr, -1); - - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { - max_width = calitem->max_month_name_width; - pango_layout_get_pixel_size (layout, &text_width, NULL); - - cairo_move_to (cr, month_x + min_x + arrow_button_size + (max_width - text_width) / 2, text_y); - pango_cairo_show_layout (cr, layout); - - max_width = calitem->max_digit_width * 5; - pango_layout_get_pixel_size (layout_yr, &text_width, NULL); - - cairo_move_to (cr, month_x + month_w - arrow_button_size - (max_width - text_width) / 2 - text_width - min_x, text_y); - pango_cairo_show_layout (cr, layout_yr); - } else { - max_width = calitem->max_digit_width * 5; - pango_layout_get_pixel_size (layout_yr, &text_width, NULL); - - cairo_move_to (cr, month_x + min_x + arrow_button_size + (max_width - text_width) / 2, text_y); - pango_cairo_show_layout (cr, layout_yr); - - max_width = calitem->max_month_name_width; - pango_layout_get_pixel_size (layout, &text_width, NULL); - - cairo_move_to (cr, month_x + month_w - arrow_button_size - (max_width - text_width) / 2 - text_width - min_x, text_y); - pango_cairo_show_layout (cr, layout); - } - - g_object_unref (layout_yr); - } else { - /* This is a strftime() format. %B = Month name, %Y = Year. */ - e_utf8_strftime (buffer, sizeof (buffer), C_("CalItem", "%B %Y"), &tmp_tm); - - pango_layout_set_font_description (layout, font_desc); - pango_layout_set_text (layout, buffer, -1); - - /* Ideally we place the text centered in the month, but we - * won't go to the left of the minimum x position. */ - pango_layout_get_pixel_size (layout, &text_width, NULL); - text_x = (calitem->month_width - text_width) / 2; - text_x = MAX (min_x, text_x); - - cairo_move_to (cr, month_x + text_x, text_y); - pango_cairo_show_layout (cr, layout); - } - - cairo_restore (cr); - } - - /* Set the clip rectangle for the main month display. */ - clip_rect.x = MAX (0, month_x); - clip_rect.y = MAX (0, month_y); - clip_width = month_x + month_w - clip_rect.x; - clip_height = month_y + month_h - clip_rect.y; - - if (clip_width <= 0 || clip_height <= 0) { - g_object_unref (layout); - return; - } - - clip_rect.width = clip_width; - clip_rect.height = clip_height; - - cairo_save (cr); - - gdk_cairo_rectangle (cr, &clip_rect); - cairo_clip (cr); - - /* Draw the day initials across the top of the month. */ - min_cell_width = MAX (calitem->max_day_width, (calitem->max_digit_width * 2)) - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - - cells_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + calitem->month_lpad - + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - if (calitem->show_week_numbers) - cells_x += calitem->max_week_number_digit_width * 2 - + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - text_x = cells_x + calitem->cell_width - - (calitem->cell_width - min_cell_width) / 2; - text_x -= E_CALENDAR_ITEM_MIN_CELL_XPAD / 2; - text_y = month_y + ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; - - cells_y = text_y + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - - cairo_save (cr); - gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]); - cairo_rectangle ( - cr, cells_x , - text_y - E_CALENDAR_ITEM_YPAD_ABOVE_CELLS - 1, - calitem->cell_width * 7 , cells_y - text_y); - cairo_fill (cr); - cairo_restore (cr); - - day_index = calitem->week_start_day; - pango_layout_set_font_description (layout, font_desc); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - text_x += (7 - 1) * calitem->cell_width; - gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_ACTIVE]); - for (day = 0; day < 7; day++) { - cairo_save (cr); - layout_set_day_text (calitem, layout, day_index); - cairo_move_to ( - cr, - text_x - calitem->day_widths[day_index], - text_y); - pango_cairo_show_layout (cr, layout); - text_x += (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - ? -calitem->cell_width : calitem->cell_width; - day_index++; - if (day_index == 7) - day_index = 0; - cairo_restore (cr); - } - - /* Draw the rectangle around the week number. */ - if (calitem->show_week_numbers) { - cairo_save (cr); - gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]); - cairo_rectangle ( - cr, cells_x, cells_y - (cells_y - text_y + 2) , - -20, E_CALENDAR_ROWS_PER_MONTH * calitem->cell_height + 18); - cairo_fill (cr); - cairo_restore (cr); - } - - e_calendar_item_draw_day_numbers ( - calitem, cr, width, height, row, col, - year, month, start_weekday, cells_x, cells_y); - - g_object_unref (layout); - cairo_restore (cr); -} - -static const gchar * -get_digit_fomat (void) -{ - -#ifdef HAVE_GNU_GET_LIBC_VERSION -#include <gnu/libc-version.h> - - const gchar *libc_version = gnu_get_libc_version (); - gchar **split = g_strsplit (libc_version, ".", -1); - gint major = 0; - gint minor = 0; - gint revision = 0; - - major = atoi (split[0]); - minor = atoi (split[1]); - - if (g_strv_length (split) > 2) - revision = atoi (split[2]); - g_strfreev (split); - - if (major > 2 || minor > 2 || (minor == 2 && revision > 2)) { - return "%Id"; - } -#endif - - return "%d"; -} - -static void -e_calendar_item_draw_day_numbers (ECalendarItem *calitem, - cairo_t *cr, - gint width, - gint height, - gint row, - gint col, - gint year, - gint month, - gint start_weekday, - gint cells_x, - gint cells_y) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - PangoFontDescription *font_desc; - GdkColor *bg_color, *fg_color, *box_color; - struct tm today_tm; - time_t t; - gint char_height, min_cell_width, min_cell_height; - gint day_num, drow, dcol, day_x, day_y; - gint text_x, text_y; - gint num_chars, digit; - gint week_num, mon, days_from_week_start; - gint years[3], months[3], days_in_month[3]; - gboolean today, selected, has_focus, drop_target = FALSE; - gboolean bold, italic, draw_day, finished = FALSE; - gint today_year, today_month, today_mday, month_offset; - gchar buffer[9]; - gint day_style = 0; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = gtk_widget_get_style (widget); - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = style->font_desc; - - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - min_cell_width = MAX (calitem->max_day_width, (calitem->max_digit_width * 2)) - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - min_cell_height = char_height + E_CALENDAR_ITEM_MIN_CELL_YPAD; - - layout = pango_cairo_create_layout (cr); - - /* Calculate the number of days in the previous, current, and next - * months. */ - years[0] = years[1] = years[2] = year; - months[0] = month - 1; - months[1] = month; - months[2] = month + 1; - if (months[0] == -1) { - months[0] = 11; - years[0]--; - } - if (months[2] == 12) { - months[2] = 0; - years[2]++; - } - - days_in_month[0] = DAYS_IN_MONTH (years[0], months[0]); - days_in_month[1] = DAYS_IN_MONTH (years[1], months[1]); - days_in_month[2] = DAYS_IN_MONTH (years[2], months[2]); - - /* Mon 0 is the previous month, which we may show the end of. Mon 1 is - * the current month, and mon 2 is the next month. */ - mon = 0; - - month_offset = row * calitem->cols + col - 1; - day_num = days_in_month[0]; - days_from_week_start = (start_weekday + 7 - calitem->week_start_day) - % 7; - /* For the top-left month we show the end of the previous month, and - * if the new month starts on the first day of the week we show a - * complete week from the previous month. */ - if (days_from_week_start == 0) { - if (row == 0 && col == 0) { - day_num -= 6; - } else { - mon++; - month_offset++; - day_num = 1; - } - } else { - day_num -= days_from_week_start - 1; - } - - /* Get today's date, so we can highlight it. */ - if (calitem->time_callback) { - today_tm = calitem->time_callback ( - calitem, calitem->time_callback_data); - } else { - t = time (NULL); - today_tm = *localtime (&t); - } - today_year = today_tm.tm_year + 1900; - today_month = today_tm.tm_mon; - today_mday = today_tm.tm_mday; - - /* We usually skip the last days of the previous month (mon = 0), - * except for the top-left month displayed. */ - draw_day = (mon == 1 || (row == 0 && col == 0)); - - for (drow = 0; drow < 6; drow++) { - /* Draw the week number. */ - if (calitem->show_week_numbers) { - week_num = e_calendar_item_get_week_number ( - calitem, day_num, months[mon], years[mon]); - - text_x = cells_x - E_CALENDAR_ITEM_XPAD_BEFORE_CELLS - 1 - - E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS; - text_y = cells_y + drow * calitem->cell_height + - + (calitem->cell_height - min_cell_height + 1) / 2; - - num_chars = 0; - if (week_num >= 10) { - digit = week_num / 10; - text_x -= calitem->week_number_digit_widths[digit]; - num_chars += sprintf ( - &buffer[num_chars], - get_digit_fomat (), digit); - } - - digit = week_num % 10; - text_x -= calitem->week_number_digit_widths[digit] + 6; - num_chars += sprintf ( - &buffer[num_chars], - get_digit_fomat (), digit); - - cairo_save (cr); - gdk_cairo_set_source_color ( - cr, &style->text[GTK_STATE_ACTIVE]); - pango_layout_set_font_description (layout, font_desc); - pango_layout_set_text (layout, buffer, num_chars); - cairo_move_to (cr, text_x, text_y); - pango_cairo_update_layout (cr, layout); - pango_cairo_show_layout (cr, layout); - cairo_restore (cr); - } - - for (dcol = 0; dcol < 7; dcol++) { - if (draw_day) { - day_x = cells_x + - ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - ? 7 - 1 - dcol : dcol) * calitem->cell_width; - - day_y = cells_y + drow * calitem->cell_height; - - today = years[mon] == today_year - && months[mon] == today_month - && day_num == today_mday; - - selected = calitem->selection_set - && (calitem->selection_start_month_offset < month_offset - || (calitem->selection_start_month_offset == month_offset - && calitem->selection_start_day <= day_num)) - && (calitem->selection_end_month_offset > month_offset - || (calitem->selection_end_month_offset == month_offset - && calitem->selection_end_day >= day_num)); - - if (calitem->styles) - day_style = calitem->styles[(month_offset + 1) * 32 + day_num]; - - /* Get the colors & style to use for the day.*/ - if ((gtk_widget_has_focus (GTK_WIDGET (item->canvas))) && - item->canvas->focused_item == item) - has_focus = TRUE; - else - has_focus = FALSE; - - bold = FALSE; - italic = FALSE; - - if (calitem->style_callback) - calitem->style_callback ( - calitem, - years[mon], - months[mon], - day_num, - day_style, - today, - mon != 1, - selected, - has_focus, - drop_target, - &bg_color, - &fg_color, - &box_color, - &bold, - &italic, - calitem->style_callback_data); - else - e_calendar_item_get_day_style ( - calitem, - years[mon], - months[mon], - day_num, - day_style, - today, - mon != 1, - selected, - has_focus, - drop_target, - &bg_color, - &fg_color, - &box_color, - &bold, - &italic); - - /* Draw the background, if set. */ - if (bg_color) { - cairo_save (cr); - gdk_cairo_set_source_color (cr, bg_color); - cairo_rectangle ( - cr, day_x , day_y, - calitem->cell_width, - calitem->cell_height); - cairo_fill (cr); - cairo_restore (cr); - } - - /* Draw the box, if set. */ - if (box_color) { - cairo_save (cr); - gdk_cairo_set_source_color (cr, box_color); - cairo_rectangle ( - cr, day_x , day_y, - calitem->cell_width - 1, - calitem->cell_height - 1); - cairo_stroke (cr); - cairo_restore (cr); - } - - /* Draw the 1- or 2-digit day number. */ - day_x += calitem->cell_width - - (calitem->cell_width - - min_cell_width) / 2; - day_x -= E_CALENDAR_ITEM_MIN_CELL_XPAD / 2; - day_y += (calitem->cell_height - min_cell_height + 1) / 2; - day_y += E_CALENDAR_ITEM_MIN_CELL_YPAD / 2; - - num_chars = 0; - if (day_num >= 10) { - digit = day_num / 10; - day_x -= calitem->digit_widths[digit]; - num_chars += sprintf ( - &buffer[num_chars], - get_digit_fomat (), digit); - } - - digit = day_num % 10; - day_x -= calitem->digit_widths[digit]; - num_chars += sprintf ( - &buffer[num_chars], - get_digit_fomat (), digit); - - cairo_save (cr); - if (fg_color) { - gdk_cairo_set_source_color ( - cr, fg_color); - } else { - gdk_cairo_set_source_color ( - cr, &style->fg[GTK_STATE_NORMAL]); - } - - if (bold) { - pango_font_description_set_weight ( - font_desc, PANGO_WEIGHT_BOLD); - } else { - pango_font_description_set_weight ( - font_desc, PANGO_WEIGHT_NORMAL); - } - - if (italic) { - pango_font_description_set_style ( - font_desc, PANGO_STYLE_ITALIC); - } else { - pango_font_description_set_style ( - font_desc, PANGO_STYLE_NORMAL); - } - - pango_layout_set_font_description (layout, font_desc); - pango_layout_set_text (layout, buffer, num_chars); - cairo_move_to (cr, day_x, day_y); - pango_cairo_update_layout (cr, layout); - pango_cairo_show_layout (cr, layout); - cairo_restore (cr); - } - - /* See if we've reached the end of a month. */ - if (day_num == days_in_month[mon]) { - month_offset++; - mon++; - /* We only draw the start of the next month - * for the bottom-right month displayed. */ - if (mon == 2 && (row != calitem->rows - 1 - || col != calitem->cols - 1)) { - /* Set a flag so we exit the loop. */ - finished = TRUE; - break; - } - day_num = 1; - draw_day = TRUE; - } else { - day_num++; - } - } - - /* Exit the loop if the flag is set. */ - if (finished) - break; - } - - /* Reset pango weight and style */ - pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL); - pango_font_description_set_style (font_desc, PANGO_STYLE_NORMAL); - - g_object_unref (layout); - - pango_font_metrics_unref (font_metrics); -} - -gint -e_calendar_item_get_week_number (ECalendarItem *calitem, - gint day, - gint month, - gint year) -{ - GDate date; - guint weekday, yearday; - gint week_num; - - g_date_clear (&date, 1); - g_date_set_dmy (&date, day, month + 1, year); - - /* This results in a value of 0 (Monday) - 6 (Sunday). - * (or -1 on error - oops!!) */ - weekday = g_date_get_weekday (&date) - 1; - - if (weekday > 0) { - /* we want always point to nearest Monday, as the first day of the week, - * regardless of the calendar's week_start_day */ - if (weekday >= 3) - g_date_add_days (&date, 7 - weekday); - else - g_date_subtract_days (&date, weekday); - } - - /* Calculate the day of the year, from 0 to 365. */ - yearday = g_date_get_day_of_year (&date) - 1; - - /* If the week starts on or after 29th December, it is week 1 of the - * next year, since there are 4 days in the next year. */ - if (g_date_get_month (&date) == 12 && g_date_get_day (&date) >= 29) - return 1; - - /* Calculate the week number, from 0. */ - week_num = yearday / 7; - - /* If the first week starts on or after Jan 5th, then we need to add - * 1 since the previous week will really be the first week. */ - if (yearday % 7 >= 4) - week_num++; - - /* Add 1 so week numbers are from 1 to 53. */ - return week_num + 1; -} - -/* This is supposed to return the nearest item the the point and the distance. - * Since we are the only item we just return ourself and 0 for the distance. - * This is needed so that we get button/motion events. */ -static GnomeCanvasItem * -e_calendar_item_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - return item; -} - -static void -e_calendar_item_stop_selecting (ECalendarItem *calitem, - guint32 time) -{ - if (!calitem->selecting) - return; - - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem), time); - - calitem->selecting = FALSE; - - /* If the user selects the grayed dates before the first month or - * after the last month, we move backwards or forwards one month. - * The set_month () call should take care of updating the selection. */ - if (calitem->selection_end_month_offset == -1) - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month - 1); - else if (calitem->selection_start_month_offset == calitem->rows * calitem->cols) - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month + 1); - - calitem->selection_changed = TRUE; - if (calitem->selecting_axis) { - g_free (calitem->selecting_axis); - calitem->selecting_axis = NULL; - } - - e_calendar_item_queue_signal_emission (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -static void -e_calendar_item_selection_add_days (ECalendarItem *calitem, - gint n_days, - gboolean multi_selection) -{ - GDate gdate_start, gdate_end; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - if (!e_calendar_item_get_selection (calitem, &gdate_start, &gdate_end)) { - /* We set the date to the first day of the month */ - g_date_set_dmy (&gdate_start, 1, calitem->month + 1, calitem->year); - gdate_end = gdate_start; - } - - if (multi_selection && calitem->max_days_selected > 1) { - gint days_between; - - days_between = g_date_days_between (&gdate_start, &gdate_end); - if (!calitem->selecting_axis) { - calitem->selecting_axis = g_new (GDate, 1); - *(calitem->selecting_axis) = gdate_start; - } - if ((days_between != 0 && - g_date_compare (calitem->selecting_axis, &gdate_end) == 0) || - (days_between == 0 && n_days < 0)) { - if (days_between - n_days > calitem->max_days_selected - 1) - n_days = days_between + 1 - calitem->max_days_selected; - g_date_add_days (&gdate_start, n_days); - } - else { - if (days_between + n_days > calitem->max_days_selected - 1) - n_days = calitem->max_days_selected - 1 - days_between; - g_date_add_days (&gdate_end, n_days); - } - - if (g_date_compare (&gdate_end, &gdate_start) < 0) { - GDate tmp_date; - tmp_date = gdate_start; - gdate_start = gdate_end; - gdate_end = tmp_date; - } - } - else { - /* clear "selecting_axis", it is only for mulit-selecting */ - if (calitem->selecting_axis) { - g_free (calitem->selecting_axis); - calitem->selecting_axis = NULL; - } - g_date_add_days (&gdate_start, n_days); - gdate_end = gdate_start; - } - - calitem->selecting = TRUE; - - e_calendar_item_set_selection_if_emission ( - calitem, &gdate_start, &gdate_end, FALSE); - - g_signal_emit_by_name (calitem, "selection_preview_changed"); -} - -static gint -e_calendar_item_key_press_event (ECalendarItem *calitem, - GdkEvent *event) -{ - guint keyval = event->key.keyval; - gboolean multi_selection = FALSE; - - if (event->key.state & GDK_CONTROL_MASK || - event->key.state & GDK_MOD1_MASK) - return FALSE; - - multi_selection = event->key.state & GDK_SHIFT_MASK; - switch (keyval) { - case GDK_KEY_Up: - e_calendar_item_selection_add_days ( - calitem, -7, - multi_selection); - break; - case GDK_KEY_Down: - e_calendar_item_selection_add_days ( - calitem, 7, - multi_selection); - break; - case GDK_KEY_Left: - e_calendar_item_selection_add_days ( - calitem, -1, - multi_selection); - break; - case GDK_KEY_Right: - e_calendar_item_selection_add_days ( - calitem, 1, - multi_selection); - break; - case GDK_KEY_space: - case GDK_KEY_Return: - e_calendar_item_stop_selecting (calitem, event->key.time); - break; - default: - return FALSE; - } - return TRUE; -} - -static gint -e_calendar_item_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_calendar_item_button_press (calitem, event); - case GDK_BUTTON_RELEASE: - return e_calendar_item_button_release (calitem, event); - case GDK_MOTION_NOTIFY: - return e_calendar_item_motion (calitem, event); - case GDK_FOCUS_CHANGE: - gnome_canvas_item_request_update (item); - return FALSE; - case GDK_KEY_PRESS: - return e_calendar_item_key_press_event (calitem, event); - default: - break; - } - - return FALSE; -} - -static void -e_calendar_item_bounds (GnomeCanvasItem *item, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2) -{ - ECalendarItem *calitem; - - g_return_if_fail (E_IS_CALENDAR_ITEM (item)); - - calitem = E_CALENDAR_ITEM (item); - *x1 = calitem->x1; - *y1 = calitem->y1; - *x2 = calitem->x2; - *y2 = calitem->y2; -} - -/* This checks if any fonts have changed, and if so it recalculates the - * text sizes and the minimum month size. */ -static void -e_calendar_item_recalc_sizes (ECalendarItem *calitem) -{ - GnomeCanvasItem *canvas_item; - GtkStyle *style; - gint day, max_day_width, digit, max_digit_width, max_week_number_digit_width; - gint char_height, width, min_cell_width, min_cell_height; - gchar buffer[64]; - struct tm tmp_tm; - PangoFontDescription *font_desc, *wkfont_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - canvas_item = GNOME_CANVAS_ITEM (calitem); - style = gtk_widget_get_style (GTK_WIDGET (canvas_item->canvas)); - - if (!style) - return; - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - wkfont_desc = calitem->week_number_font_desc; - if (!font_desc) - font_desc = style->font_desc; - - pango_context = gtk_widget_create_pango_context ( - GTK_WIDGET (canvas_item->canvas)); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - max_day_width = 0; - for (day = 0; day < 7; day++) { - layout_set_day_text (calitem, layout, day); - pango_layout_get_pixel_size (layout, &width, NULL); - - calitem->day_widths[day] = width; - max_day_width = MAX (max_day_width, width); - } - calitem->max_day_width = max_day_width; - - max_digit_width = 0; - max_week_number_digit_width = 0; - for (digit = 0; digit < 10; digit++) { - gchar locale_digit[5]; - gint locale_digit_len; - - locale_digit_len = sprintf (locale_digit, get_digit_fomat (), digit); - - pango_layout_set_text (layout, locale_digit, locale_digit_len); - pango_layout_get_pixel_size (layout, &width, NULL); - - calitem->digit_widths[digit] = width; - max_digit_width = MAX (max_digit_width, width); - - if (wkfont_desc) { - pango_context_set_font_description (pango_context, wkfont_desc); - pango_layout_context_changed (layout); - - pango_layout_set_text (layout, locale_digit, locale_digit_len); - pango_layout_get_pixel_size (layout, &width, NULL); - - calitem->week_number_digit_widths[digit] = width; - max_week_number_digit_width = MAX (max_week_number_digit_width, width); - - pango_context_set_font_description (pango_context, font_desc); - pango_layout_context_changed (layout); - } else { - calitem->week_number_digit_widths[digit] = width; - max_week_number_digit_width = max_digit_width; - } - } - calitem->max_digit_width = max_digit_width; - calitem->max_week_number_digit_width = max_week_number_digit_width; - - min_cell_width = MAX (calitem->max_day_width, (calitem->max_digit_width * 2)) - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - min_cell_height = char_height + E_CALENDAR_ITEM_MIN_CELL_YPAD; - - calitem->min_month_width = E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS - + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS + min_cell_width * 7 - + E_CALENDAR_ITEM_XPAD_AFTER_CELLS; - if (calitem->show_week_numbers) { - calitem->min_month_width += calitem->max_week_number_digit_width * 2 - + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - } - - calitem->min_month_height = style->ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS + min_cell_height * 6 - + E_CALENDAR_ITEM_YPAD_BELOW_CELLS; - - calitem->max_month_name_width = 50; - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = 2000 - 100; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - for (tmp_tm.tm_mon = 0; tmp_tm.tm_mon < 12; tmp_tm.tm_mon++) { - mktime (&tmp_tm); - - e_utf8_strftime (buffer, sizeof (buffer), C_("CalItem", "%B"), &tmp_tm); - - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - - if (width > calitem->max_month_name_width) - calitem->max_month_name_width = width; - } - - g_object_unref (layout); - g_object_unref (pango_context); - pango_font_metrics_unref (font_metrics); -} - -static void -e_calendar_item_get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gboolean *italic) -{ - GtkWidget *widget; - GtkStyle *style; - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas); - style = gtk_widget_get_style (widget); - - *bg_color = NULL; - *fg_color = NULL; - *box_color = NULL; - - *bold = (day_style & E_CALENDAR_ITEM_MARK_BOLD) == - E_CALENDAR_ITEM_MARK_BOLD; - *italic = (day_style & E_CALENDAR_ITEM_MARK_ITALIC) == - E_CALENDAR_ITEM_MARK_ITALIC; - - if (today) - *box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX]; - - if (prev_or_next_month) - *fg_color = &style->mid[gtk_widget_get_state (widget)]; - - if (selected) { - if (has_focus) { - *fg_color = &style->text[GTK_STATE_SELECTED]; - *bg_color = &style->base[GTK_STATE_SELECTED]; - } else { - *fg_color = &style->text[GTK_STATE_ACTIVE]; - *bg_color = &style->base[GTK_STATE_ACTIVE]; - - if ((*bg_color)->red == style->base[GTK_STATE_NORMAL].red && - (*bg_color)->green == style->base[GTK_STATE_NORMAL].green && - (*bg_color)->blue == style->base[GTK_STATE_NORMAL].blue) { - *fg_color = &style->text[GTK_STATE_SELECTED]; - *bg_color = &style->base[GTK_STATE_SELECTED]; - } - } - } -} - -static gboolean -e_calendar_item_button_press (ECalendarItem *calitem, - GdkEvent *button_event) -{ - GdkGrabStatus grab_status; - GdkDevice *event_device; - guint event_button = 0; - guint32 event_time; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - gint month_offset, day, add_days = 0; - gboolean all_week, round_up_end = FALSE, round_down_start = FALSE; - - gdk_event_get_button (button_event, &event_button); - gdk_event_get_coords (button_event, &event_x_win, &event_y_win); - event_device = gdk_event_get_device (button_event); - event_time = gdk_event_get_time (button_event); - - if (event_button == 4) - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month - 1); - else if (event_button == 5) - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month + 1); - - if (!e_calendar_item_convert_position_to_day (calitem, - event_x_win, - event_y_win, - TRUE, - &month_offset, &day, - &all_week)) - return FALSE; - - if (event_button == 3 && day == -1 - && e_calendar_item_get_display_popup (calitem)) { - e_calendar_item_show_popup_menu ( - calitem, button_event, month_offset); - return TRUE; - } - - if (event_button != 1 || day == -1) - return FALSE; - - if (calitem->max_days_selected < 1) - return TRUE; - - grab_status = gnome_canvas_item_grab ( - GNOME_CANVAS_ITEM (calitem), - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, - event_device, - event_time); - - if (grab_status != GDK_GRAB_SUCCESS) - return FALSE; - - if (all_week && calitem->keep_wdays_on_weeknum_click) { - gint tmp_start_moff, tmp_start_day; - - tmp_start_moff = calitem->selection_start_month_offset; - tmp_start_day = calitem->selection_start_day; - e_calendar_item_round_down_selection ( - calitem, &tmp_start_moff, &tmp_start_day); - - e_calendar_item_round_down_selection (calitem, &month_offset, &day); - month_offset += calitem->selection_start_month_offset - tmp_start_moff; - day += calitem->selection_start_day - tmp_start_day; - - /* keep same count of days selected */ - add_days = e_calendar_item_get_inclusive_days ( - calitem, - calitem->selection_start_month_offset, - calitem->selection_start_day, - calitem->selection_end_month_offset, - calitem->selection_end_day) - 1; - } - - calitem->selection_set = TRUE; - calitem->selection_start_month_offset = month_offset; - calitem->selection_start_day = day; - calitem->selection_end_month_offset = month_offset; - calitem->selection_end_day = day; - - if (add_days > 0) - e_calendar_item_add_days_to_selection (calitem, add_days); - - calitem->selection_real_start_month_offset = month_offset; - calitem->selection_real_start_day = day; - - calitem->selection_from_full_week = FALSE; - calitem->selecting = TRUE; - calitem->selection_dragging_end = TRUE; - - if (all_week && !calitem->keep_wdays_on_weeknum_click) { - calitem->selection_from_full_week = TRUE; - round_up_end = TRUE; - } - - if (calitem->days_to_start_week_selection == 1) { - round_down_start = TRUE; - round_up_end = TRUE; - } - - /* Don't round up or down if we can't select a week or more, - * or when keeping week days. */ - if (calitem->max_days_selected < 7 || - (all_week && calitem->keep_wdays_on_weeknum_click)) { - round_down_start = FALSE; - round_up_end = FALSE; - } - - if (round_up_end) - e_calendar_item_round_up_selection ( - calitem, &calitem->selection_end_month_offset, - &calitem->selection_end_day); - - if (round_down_start) - e_calendar_item_round_down_selection ( - calitem, &calitem->selection_start_month_offset, - &calitem->selection_start_day); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - - return TRUE; -} - -static gboolean -e_calendar_item_button_release (ECalendarItem *calitem, - GdkEvent *button_event) -{ - guint32 event_time; - - event_time = gdk_event_get_time (button_event); - e_calendar_item_stop_selecting (calitem, event_time); - - return FALSE; -} - -static gboolean -e_calendar_item_motion (ECalendarItem *calitem, - GdkEvent *event) -{ - gint start_month, start_day, end_month, end_day, month_offset, day; - gint tmp_month, tmp_day, days_in_selection; - gboolean all_week, round_up_end = FALSE, round_down_start = FALSE; - - if (!calitem->selecting) - return FALSE; - - if (!e_calendar_item_convert_position_to_day (calitem, - event->button.x, - event->button.y, - TRUE, - &month_offset, &day, - &all_week)) - return FALSE; - - if (day == -1) - return FALSE; - - if (calitem->selection_dragging_end) { - start_month = calitem->selection_real_start_month_offset; - start_day = calitem->selection_real_start_day; - end_month = month_offset; - end_day = day; - } else { - start_month = month_offset; - start_day = day; - end_month = calitem->selection_real_start_month_offset; - end_day = calitem->selection_real_start_day; - } - - if (start_month > end_month || (start_month == end_month - && start_day > end_day)) { - tmp_month = start_month; - tmp_day = start_day; - start_month = end_month; - start_day = end_day; - end_month = tmp_month; - end_day = tmp_day; - - calitem->selection_dragging_end = - !calitem->selection_dragging_end; - } - - if (calitem->days_to_start_week_selection > 0) { - days_in_selection = e_calendar_item_get_inclusive_days ( - calitem, start_month, start_day, end_month, end_day); - if (days_in_selection >= calitem->days_to_start_week_selection) { - round_down_start = TRUE; - round_up_end = TRUE; - } - } - - /* If we are over a week number and we are dragging the end of the - * selection, we round up to the end of this week. */ - if (all_week && calitem->selection_dragging_end) - round_up_end = TRUE; - - /* If the selection was started from a week number and we are dragging - * the start of the selection, we need to round up the end to include - * all of the original week selected. */ - if (calitem->selection_from_full_week - && !calitem->selection_dragging_end) - round_up_end = TRUE; - - /* Don't round up or down if we can't select a week or more. */ - if (calitem->max_days_selected < 7) { - round_down_start = FALSE; - round_up_end = FALSE; - } - - if (round_up_end) - e_calendar_item_round_up_selection ( - calitem, &end_month, - &end_day); - if (round_down_start) - e_calendar_item_round_down_selection ( - calitem, &start_month, - &start_day); - - /* Check we don't go over the maximum number of days to select. */ - if (calitem->selection_dragging_end) { - e_calendar_item_check_selection_end ( - calitem, - start_month, - start_day, - &end_month, - &end_day); - } else { - e_calendar_item_check_selection_start ( - calitem, - &start_month, - &start_day, - end_month, - end_day); - } - - if (start_month == calitem->selection_start_month_offset - && start_day == calitem->selection_start_day - && end_month == calitem->selection_end_month_offset - && end_day == calitem->selection_end_day) - return FALSE; - - calitem->selection_start_month_offset = start_month; - calitem->selection_start_day = start_day; - calitem->selection_end_month_offset = end_month; - calitem->selection_end_day = end_day; - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - - return TRUE; -} - -static void -e_calendar_item_check_selection_end (ECalendarItem *calitem, - gint start_month, - gint start_day, - gint *end_month, - gint *end_day) -{ - gint year, month, max_month, max_day, days_in_month; - - if (calitem->max_days_selected <= 0) - return; - - year = calitem->year; - month = calitem->month + start_month; - e_calendar_item_normalize_date (calitem, &year, &month); - - max_month = start_month; - max_day = start_day + calitem->max_days_selected - 1; - - for (;;) { - days_in_month = DAYS_IN_MONTH (year, month); - if (max_day <= days_in_month) - break; - max_month++; - month++; - if (month == 12) { - year++; - month = 0; - } - max_day -= days_in_month; - } - - if (*end_month > max_month) { - *end_month = max_month; - *end_day = max_day; - } else if (*end_month == max_month && *end_day > max_day) { - *end_day = max_day; - } -} - -static void -e_calendar_item_check_selection_start (ECalendarItem *calitem, - gint *start_month, - gint *start_day, - gint end_month, - gint end_day) -{ - gint year, month, min_month, min_day, days_in_month; - - if (calitem->max_days_selected <= 0) - return; - - year = calitem->year; - month = calitem->month + end_month; - e_calendar_item_normalize_date (calitem, &year, &month); - - min_month = end_month; - min_day = end_day - calitem->max_days_selected + 1; - - while (min_day <= 0) { - min_month--; - month--; - if (month == -1) { - year--; - month = 11; - } - days_in_month = DAYS_IN_MONTH (year, month); - min_day += days_in_month; - } - - if (*start_month < min_month) { - *start_month = min_month; - *start_day = min_day; - } else if (*start_month == min_month && *start_day < min_day) { - *start_day = min_day; - } -} - -/* Converts a position within the item to a month & day. - * The month returned is 0 for the top-left month displayed. - * If the position is over the month heading -1 is returned for the day. - * If the position is over a week number the first day of the week is returned - * and entire_week is set to TRUE. - * It returns FALSE if the position is completely outside all months. */ -static gboolean -e_calendar_item_convert_position_to_day (ECalendarItem *calitem, - gint event_x, - gint event_y, - gboolean round_empty_positions, - gint *month_offset, - gint *day, - gboolean *entire_week) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - gint xthickness, ythickness, char_height; - gint x, y, row, col, cells_x, cells_y, day_row, day_col; - gint first_day_offset, days_in_month, days_in_prev_month; - gint week_num_x1, week_num_x2; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = gtk_widget_get_style (widget); - - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = style->font_desc; - pango_context = gtk_widget_create_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - xthickness = style->xthickness; - ythickness = style->ythickness; - - pango_font_metrics_unref (font_metrics); - - *entire_week = FALSE; - - x = event_x - xthickness - calitem->x_offset; - y = event_y - ythickness; - - if (x < 0 || y < 0) - return FALSE; - - row = y / calitem->month_height; - col = x / calitem->month_width; - - if (row >= calitem->rows || col >= calitem->cols) - return FALSE; - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - col = calitem->cols - 1 - col; - - *month_offset = row * calitem->cols + col; - - x = x % calitem->month_width; - y = y % calitem->month_height; - - if (y < ythickness * 2 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME) { - *day = -1; - return TRUE; - } - - cells_y = ythickness * 2 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - y -= cells_y; - if (y < 0) - return FALSE; - day_row = y / calitem->cell_height; - if (day_row >= E_CALENDAR_ROWS_PER_MONTH) - return FALSE; - - week_num_x1 = E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + calitem->month_lpad; - - if (calitem->show_week_numbers) { - week_num_x2 = week_num_x1 - + calitem->max_week_number_digit_width * 2; - if (x >= week_num_x1 && x < week_num_x2) - *entire_week = TRUE; - cells_x = week_num_x2 + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - } else { - cells_x = week_num_x1; - } - - if (*entire_week) { - day_col = 0; - } else { - cells_x += E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - x -= cells_x; - if (x < 0) - return FALSE; - day_col = x / calitem->cell_width; - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - day_col = E_CALENDAR_COLS_PER_MONTH - 1 - day_col; - if (day_col >= E_CALENDAR_COLS_PER_MONTH) - return FALSE; - } - - *day = day_row * E_CALENDAR_COLS_PER_MONTH + day_col; - - e_calendar_item_get_month_info ( - calitem, row, col, &first_day_offset, - &days_in_month, &days_in_prev_month); - if (*day < first_day_offset) { - if (*entire_week || (row == 0 && col == 0)) { - (*month_offset)--; - *day = days_in_prev_month + 1 - first_day_offset - + *day; - return TRUE; - } else if (round_empty_positions) { - *day = first_day_offset; - } else { - return FALSE; - } - } - - *day -= first_day_offset - 1; - - if (*day > days_in_month) { - if (row == calitem->rows - 1 && col == calitem->cols - 1) { - (*month_offset)++; - *day -= days_in_month; - return TRUE; - } else if (round_empty_positions) { - *day = days_in_month; - } else { - return FALSE; - } - } - - return TRUE; -} - -static void -e_calendar_item_get_month_info (ECalendarItem *calitem, - gint row, - gint col, - gint *first_day_offset, - gint *days_in_month, - gint *days_in_prev_month) -{ - gint year, month, start_weekday, first_day_of_month; - struct tm tmp_tm = { 0 }; - - month = calitem->month + row * calitem->cols + col; - year = calitem->year + month / 12; - month = month % 12; - - *days_in_month = DAYS_IN_MONTH (year, month); - if (month == 0) - *days_in_prev_month = DAYS_IN_MONTH (year - 1, 11); - else - *days_in_prev_month = DAYS_IN_MONTH (year, month - 1); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - start_weekday = (tmp_tm.tm_wday + 6) % 7; - - first_day_of_month = (start_weekday + 7 - calitem->week_start_day) % 7; - - if (row == 0 && col == 0 && first_day_of_month == 0) - *first_day_offset = 7; - else - *first_day_offset = first_day_of_month; -} - -void -e_calendar_item_get_first_month (ECalendarItem *calitem, - gint *year, - gint *month) -{ - *year = calitem->year; - *month = calitem->month; -} - -static void -e_calendar_item_preserve_day_selection (ECalendarItem *calitem, - gint selected_day, - gint *month_offset, - gint *day) -{ - gint year, month, weekday, days, days_in_month; - struct tm tmp_tm = { 0 }; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = *day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - weekday = (tmp_tm.tm_wday + 6) % 7; - - /* Calculate how many days to the start of the row. */ - days = (weekday + 7 - selected_day) % 7; - - *day -= days; - if (*day <= 0) { - month--; - if (month == -1) { - year--; - month = 11; - } - days_in_month = DAYS_IN_MONTH (year, month); - (*month_offset)--; - *day += days_in_month; - } -} - -/* This also handles values of month < 0 or > 11 by updating the year. */ -void -e_calendar_item_set_first_month (ECalendarItem *calitem, - gint year, - gint month) -{ - gint new_year, new_month, months_diff, num_months; - gint old_days_in_selection, new_days_in_selection; - - new_year = year; - new_month = month; - e_calendar_item_normalize_date (calitem, &new_year, &new_month); - - if (calitem->year == new_year && calitem->month == new_month) - return; - - /* Update the selection. */ - num_months = calitem->rows * calitem->cols; - months_diff = (new_year - calitem->year) * 12 - + new_month - calitem->month; - - if (calitem->selection_set) { - if (!calitem->move_selection_when_moving - || (calitem->selection_start_month_offset - months_diff >= 0 - && calitem->selection_end_month_offset - months_diff < num_months)) { - calitem->selection_start_month_offset -= months_diff; - calitem->selection_end_month_offset -= months_diff; - calitem->selection_real_start_month_offset -= months_diff; - - calitem->year = new_year; - calitem->month = new_month; - } else { - gint selected_day; - struct tm tmp_tm = { 0 }; - - old_days_in_selection = e_calendar_item_get_inclusive_days ( - calitem, - calitem->selection_start_month_offset, - calitem->selection_start_day, - calitem->selection_end_month_offset, - calitem->selection_end_day); - - /* Calculate the currently selected day */ - tmp_tm.tm_year = calitem->year - 1900; - tmp_tm.tm_mon = calitem->month + calitem->selection_start_month_offset; - tmp_tm.tm_mday = calitem->selection_start_day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - selected_day = (tmp_tm.tm_wday + 6) % 7; - - /* Make sure the selection will be displayed. */ - if (calitem->selection_start_month_offset < 0 - || calitem->selection_start_month_offset >= num_months) { - calitem->selection_end_month_offset -= - calitem->selection_start_month_offset; - calitem->selection_start_month_offset = 0; - } - - /* We want to ensure that the same number of days are - * selected after we have moved the selection. */ - calitem->year = new_year; - calitem->month = new_month; - - e_calendar_item_ensure_valid_day ( - calitem, &calitem->selection_start_month_offset, - &calitem->selection_start_day); - e_calendar_item_ensure_valid_day ( - calitem, &calitem->selection_end_month_offset, - &calitem->selection_end_day); - - if (calitem->preserve_day_when_moving) { - e_calendar_item_preserve_day_selection ( - calitem, selected_day, - &calitem->selection_start_month_offset, - &calitem->selection_start_day); - } - - new_days_in_selection = e_calendar_item_get_inclusive_days ( - calitem, - calitem->selection_start_month_offset, - calitem->selection_start_day, - calitem->selection_end_month_offset, - calitem->selection_end_day); - - if (old_days_in_selection != new_days_in_selection) - e_calendar_item_add_days_to_selection ( - calitem, old_days_in_selection - - new_days_in_selection); - - /* Flag that we need to emit the "selection_changed" - * signal. We don't want to emit it here since setting - * the "year" and "month" args would result in 2 - * signals emitted. */ - calitem->selection_changed = TRUE; - } - } else { - calitem->year = new_year; - calitem->month = new_month; - } - - e_calendar_item_date_range_changed (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -/* Get the maximum number of days selectable */ -gint -e_calendar_item_get_max_days_sel (ECalendarItem *calitem) -{ - return calitem->max_days_selected; -} - -/* Set the maximum number of days selectable */ -void -e_calendar_item_set_max_days_sel (ECalendarItem *calitem, - gint days) -{ - calitem->max_days_selected = MAX (0, days); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -/* Get the maximum number of days before whole weeks are selected */ -gint -e_calendar_item_get_days_start_week_sel (ECalendarItem *calitem) -{ - return calitem->days_to_start_week_selection; -} - -/* Set the maximum number of days before whole weeks are selected */ -void -e_calendar_item_set_days_start_week_sel (ECalendarItem *calitem, - gint days) -{ - calitem->days_to_start_week_selection = days; -} - -gboolean -e_calendar_item_get_display_popup (ECalendarItem *calitem) -{ - return calitem->display_popup; -} - -void -e_calendar_item_set_display_popup (ECalendarItem *calitem, - gboolean display) -{ - calitem->display_popup = display; -} - -/* This will make sure that the given year & month are valid, i.e. if month - * is < 0 or > 11 the year and month will be updated accordingly. */ -void -e_calendar_item_normalize_date (ECalendarItem *calitem, - gint *year, - gint *month) -{ - if (*month >= 0) { - *year += *month / 12; - *month = *month % 12; - } else { - *year += *month / 12 - 1; - *month = *month % 12; - if (*month != 0) - *month += 12; - } -} - -/* Adds or subtracts days from the selection. It is used when we switch months - * and the selection extends past the end of a month but we want to keep the - * number of days selected the same. days should not be more than 30. */ -static void -e_calendar_item_add_days_to_selection (ECalendarItem *calitem, - gint days) -{ - gint year, month, days_in_month; - - year = calitem->year; - month = calitem->month + calitem->selection_end_month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - calitem->selection_end_day += days; - if (calitem->selection_end_day <= 0) { - month--; - e_calendar_item_normalize_date (calitem, &year, &month); - calitem->selection_end_month_offset--; - calitem->selection_end_day += DAYS_IN_MONTH (year, month); - } else { - days_in_month = DAYS_IN_MONTH (year, month); - if (calitem->selection_end_day > days_in_month) { - calitem->selection_end_month_offset++; - calitem->selection_end_day -= days_in_month; - } - } -} - -/* Gets the range of dates actually shown. Months are 0 to 11. - * This also includes the last days of the previous month and the first days - * of the following month, which are normally shown in gray. - * It returns FALSE if no dates are currently shown. */ -gboolean -e_calendar_item_get_date_range (ECalendarItem *calitem, - gint *start_year, - gint *start_month, - gint *start_day, - gint *end_year, - gint *end_month, - gint *end_day) -{ - gint first_day_offset, days_in_month, days_in_prev_month; - - if (calitem->rows == 0 || calitem->cols == 0) - return FALSE; - - /* Calculate the first day shown. This will be one of the greyed-out - * days before the first full month begins. */ - e_calendar_item_get_month_info ( - calitem, 0, 0, &first_day_offset, - &days_in_month, &days_in_prev_month); - *start_year = calitem->year; - *start_month = calitem->month - 1; - if (*start_month == -1) { - (*start_year)--; - *start_month = 11; - } - *start_day = days_in_prev_month + 1 - first_day_offset; - - /* Calculate the last day shown. This will be one of the greyed-out - * days after the last full month ends. */ - e_calendar_item_get_month_info ( - calitem, calitem->rows - 1, - calitem->cols - 1, &first_day_offset, - &days_in_month, &days_in_prev_month); - *end_month = calitem->month + calitem->rows * calitem->cols; - *end_year = calitem->year + *end_month / 12; - *end_month %= 12; - *end_day = E_CALENDAR_ROWS_PER_MONTH * E_CALENDAR_COLS_PER_MONTH - - first_day_offset - days_in_month; - - return TRUE; -} - -/* Simple way to mark days so they appear bold. - * A more flexible interface may be added later. */ -void -e_calendar_item_clear_marks (ECalendarItem *calitem) -{ - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (calitem); - - g_free (calitem->styles); - calitem->styles = NULL; - - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, - item->x2, item->y2); -} - -/* add_day_style - whether bit-or with the actual style or change the style fully */ -void -e_calendar_item_mark_day (ECalendarItem *calitem, - gint year, - gint month, - gint day, - guint8 day_style, - gboolean add_day_style) -{ - gint month_offset; - gint index; - - month_offset = (year - calitem->year) * 12 + month - calitem->month; - if (month_offset < -1 || month_offset > calitem->rows * calitem->cols) - return; - - if (!calitem->styles) - calitem->styles = g_new0 (guint8, (calitem->rows * calitem->cols + 2) * 32); - - index = (month_offset + 1) * 32 + day; - calitem->styles[index] = day_style | - (add_day_style ? calitem->styles[index] : 0); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -void -e_calendar_item_mark_days (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - guint8 day_style, - gboolean add_day_style) -{ - gint month_offset, end_month_offset, day; - - month_offset = (start_year - calitem->year) * 12 + start_month - - calitem->month; - day = start_day; - if (month_offset > calitem->rows * calitem->cols) - return; - if (month_offset < -1) { - month_offset = -1; - day = 1; - } - - end_month_offset = (end_year - calitem->year) * 12 + end_month - - calitem->month; - if (end_month_offset < -1) - return; - if (end_month_offset > calitem->rows * calitem->cols) { - end_month_offset = calitem->rows * calitem->cols; - end_day = 31; - } - - if (month_offset > end_month_offset) - return; - - if (!calitem->styles) - calitem->styles = g_new0 (guint8, (calitem->rows * calitem->cols + 2) * 32); - - for (;;) { - gint index; - - if (month_offset == end_month_offset && day > end_day) - break; - - if (month_offset < -1 || month_offset > calitem->rows * calitem->cols) - g_warning ("Bad month offset: %i\n", month_offset); - if (day < 1 || day > 31) - g_warning ("Bad day: %i\n", day); - -#if 0 - g_print ("Marking Month:%i Day:%i\n", month_offset, day); -#endif - index = (month_offset + 1) * 32 + day; - calitem->styles[index] = day_style | - (add_day_style ? calitem->styles[index] : 0); - - day++; - if (day == 32) { - month_offset++; - day = 1; - if (month_offset > end_month_offset) - break; - } - } - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -/* Rounds up the given day to the end of the week. */ -static void -e_calendar_item_round_up_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, weekday, days, days_in_month; - struct tm tmp_tm = { 0 }; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = *day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - weekday = (tmp_tm.tm_wday + 6) % 7; - - /* Calculate how many days to the end of the row. */ - days = (calitem->week_start_day + 6 - weekday) % 7; - - *day += days; - days_in_month = DAYS_IN_MONTH (year, month); - if (*day > days_in_month) { - (*month_offset)++; - *day -= days_in_month; - } -} - -/* Rounds down the given day to the start of the week. */ -static void -e_calendar_item_round_down_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, weekday, days, days_in_month; - struct tm tmp_tm = { 0 }; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = *day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - weekday = (tmp_tm.tm_wday + 6) % 7; - - /* Calculate how many days to the start of the row. */ - days = (weekday + 7 - calitem->week_start_day) % 7; - - *day -= days; - if (*day <= 0) { - month--; - if (month == -1) { - year--; - month = 11; - } - days_in_month = DAYS_IN_MONTH (year, month); - (*month_offset)--; - *day += days_in_month; - } -} - -static gint -e_calendar_item_get_inclusive_days (ECalendarItem *calitem, - gint start_month_offset, - gint start_day, - gint end_month_offset, - gint end_day) -{ - gint start_year, start_month, end_year, end_month, days = 0; - - start_year = calitem->year; - start_month = calitem->month + start_month_offset; - e_calendar_item_normalize_date (calitem, &start_year, &start_month); - - end_year = calitem->year; - end_month = calitem->month + end_month_offset; - e_calendar_item_normalize_date (calitem, &end_year, &end_month); - - while (start_year < end_year || start_month < end_month) { - days += DAYS_IN_MONTH (start_year, start_month); - start_month++; - if (start_month == 12) { - start_year++; - start_month = 0; - } - } - - days += end_day - start_day + 1; - - return days; -} - -/* If the day is off the end of the month it is set to the last day of the - * month. */ -static void -e_calendar_item_ensure_valid_day (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, days_in_month; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - days_in_month = DAYS_IN_MONTH (year, month); - if (*day > days_in_month) - *day = days_in_month; -} - -gboolean -e_calendar_item_get_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - - g_date_clear (start_date, 1); - g_date_clear (end_date, 1); - - if (!calitem->selection_set) - return FALSE; - - start_year = calitem->year; - start_month = calitem->month + calitem->selection_start_month_offset; - e_calendar_item_normalize_date (calitem, &start_year, &start_month); - start_day = calitem->selection_start_day; - - end_year = calitem->year; - end_month = calitem->month + calitem->selection_end_month_offset; - e_calendar_item_normalize_date (calitem, &end_year, &end_month); - end_day = calitem->selection_end_day; - - g_date_set_dmy (start_date, start_day, start_month + 1, start_year); - g_date_set_dmy (end_date, end_day, end_month + 1, end_year); - - return TRUE; -} - -static void -e_calendar_item_set_selection_if_emission (ECalendarItem *calitem, - const GDate *start_date, - const GDate *end_date, - gboolean emission) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - gint new_start_month_offset, new_start_day; - gint new_end_month_offset, new_end_day; - gboolean need_update; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - /* If start_date is NULL, we clear the selection without changing the - * month shown. */ - if (start_date == NULL) { - calitem->selection_set = FALSE; - calitem->selection_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - return; - } - - if (end_date == NULL) - end_date = start_date; - - g_return_if_fail (g_date_compare (start_date, end_date) <= 0); - - start_year = g_date_get_year (start_date); - start_month = g_date_get_month (start_date) - 1; - start_day = g_date_get_day (start_date); - end_year = g_date_get_year (end_date); - end_month = g_date_get_month (end_date) - 1; - end_day = g_date_get_day (end_date); - - need_update = e_calendar_item_ensure_days_visible ( - calitem, - start_year, - start_month, - start_day, - end_year, - end_month, - end_day, - emission); - - new_start_month_offset = (start_year - calitem->year) * 12 - + start_month - calitem->month; - new_start_day = start_day; - - /* This may go outside the visible months, but we don't care. */ - new_end_month_offset = (end_year - calitem->year) * 12 - + end_month - calitem->month; - new_end_day = end_day; - - if (!calitem->selection_set - || calitem->selection_start_month_offset != new_start_month_offset - || calitem->selection_start_day != new_start_day - || calitem->selection_end_month_offset != new_end_month_offset - || calitem->selection_end_day != new_end_day) { - need_update = TRUE; - if (emission) { - calitem->selection_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); - } - calitem->selection_set = TRUE; - calitem->selection_start_month_offset = new_start_month_offset; - calitem->selection_start_day = new_start_day; - calitem->selection_end_month_offset = new_end_month_offset; - calitem->selection_end_day = new_end_day; - - calitem->selection_real_start_month_offset = new_start_month_offset; - calitem->selection_real_start_day = new_start_day; - calitem->selection_from_full_week = FALSE; - } - - if (need_update) { - g_signal_emit ( - calitem, - e_calendar_item_signals[DATE_RANGE_CHANGED], 0); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - } -} - -void -e_calendar_item_style_set (GtkWidget *widget, - ECalendarItem *calitem) -{ - GtkStyle *style; - GdkColor *color; - - style = gtk_widget_get_style (widget); - - color = &style->bg[GTK_STATE_SELECTED]; - calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX] = *color; - - color = &style->base[GTK_STATE_NORMAL]; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG] = *color; - - color = &style->bg[GTK_STATE_SELECTED]; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED] = *color; - - color = &style->fg[GTK_STATE_INSENSITIVE]; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG] = *color; - - color = &style->fg[GTK_STATE_INSENSITIVE]; - calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG] = *color; - - e_calendar_item_recalc_sizes (calitem); -} - -void -e_calendar_item_set_selection (ECalendarItem *calitem, - const GDate *start_date, - const GDate *end_date) -{ - /* If the user is in the middle of a selection, we must abort it. */ - if (calitem->selecting) { - gnome_canvas_item_ungrab ( - GNOME_CANVAS_ITEM (calitem), - GDK_CURRENT_TIME); - calitem->selecting = FALSE; - } - - e_calendar_item_set_selection_if_emission (calitem, - start_date, end_date, - TRUE); -} - -/* This tries to ensure that the given time range is visible. If the range - * given is longer than we can show, only the start of it will be visible. - * Note that this will not update the selection. That should be done somewhere - * else. It returns TRUE if the visible range has been changed. */ -static gboolean -e_calendar_item_ensure_days_visible (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - gboolean emission) -{ - gint current_end_year, current_end_month; - gint months_shown; - gint first_day_offset, days_in_month, days_in_prev_month; - gboolean need_update = FALSE; - - months_shown = calitem->rows * calitem->cols; - - /* Calculate the range of months currently displayed. */ - current_end_year = calitem->year; - current_end_month = calitem->month + months_shown - 1; - e_calendar_item_normalize_date ( - calitem, ¤t_end_year, - ¤t_end_month); - - /* Try to ensure that the end month is shown. */ - if ((end_year == current_end_year + 1 && - current_end_month == 11 && end_month == 0) || - (end_year == current_end_year && end_month == current_end_month + 1)) { - /* See if the end of the selection will fit in the - * leftover days of the month after the last one shown. */ - calitem->month += (months_shown - 1); - e_calendar_item_normalize_date ( - calitem, &calitem->year, - &calitem->month); - - e_calendar_item_get_month_info ( - calitem, 0, 0, - &first_day_offset, - &days_in_month, - &days_in_prev_month); - - if (end_day >= E_CALENDAR_ROWS_PER_MONTH * E_CALENDAR_COLS_PER_MONTH - - first_day_offset - days_in_month) { - need_update = TRUE; - - calitem->year = end_year; - calitem->month = end_month - months_shown + 1; - } else { - calitem->month -= (months_shown - 1); - } - - e_calendar_item_normalize_date ( - calitem, &calitem->year, - &calitem->month); - } - else if (end_year > current_end_year || - (end_year == current_end_year && end_month > current_end_month)) { - /* The selection will definitely not fit in the leftover days - * of the month after the last one shown. */ - need_update = TRUE; - - calitem->year = end_year; - calitem->month = end_month - months_shown + 1; - - e_calendar_item_normalize_date ( - calitem, &calitem->year, - &calitem->month); - } - - /* Now try to ensure that the start month is shown. We do this after - * the end month so that the start month will always be shown. */ - if (start_year < calitem->year - || (start_year == calitem->year - && start_month < calitem->month)) { - need_update = TRUE; - - /* First we see if the start of the selection will fit in the - * leftover days of the month before the first one shown. */ - calitem->year = start_year; - calitem->month = start_month + 1; - e_calendar_item_normalize_date ( - calitem, &calitem->year, - &calitem->month); - - e_calendar_item_get_month_info ( - calitem, 0, 0, - &first_day_offset, - &days_in_month, - &days_in_prev_month); - - if (start_day <= days_in_prev_month - first_day_offset) { - calitem->year = start_year; - calitem->month = start_month; - } - } - - if (need_update && emission) - e_calendar_item_date_range_changed (calitem); - - return need_update; -} - -static gboolean -destroy_menu_idle_cb (gpointer menu) -{ - gtk_widget_destroy (menu); - - return FALSE; -} - -static void -deactivate_menu_cb (GtkWidget *menu) -{ - g_signal_handlers_disconnect_by_func (menu, deactivate_menu_cb, NULL); - - g_idle_add (destroy_menu_idle_cb, menu); -} - -static void -e_calendar_item_show_popup_menu (ECalendarItem *calitem, - GdkEvent *button_event, - gint month_offset) -{ - GtkWidget *menu, *submenu, *menuitem, *label; - gint year, month; - const gchar *name; - gchar buffer[64]; - guint event_button = 0; - guint32 event_time; - - menu = gtk_menu_new (); - - for (year = calitem->year - 2; year <= calitem->year + 2; year++) { - g_snprintf (buffer, 64, "%i", year); - menuitem = gtk_menu_item_new_with_label (buffer); - gtk_widget_show (menuitem); - gtk_container_add (GTK_CONTAINER (menu), menuitem); - - submenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); - - g_object_set_data ( - G_OBJECT (submenu), "year", - GINT_TO_POINTER (year)); - g_object_set_data ( - G_OBJECT (submenu), "month_offset", - GINT_TO_POINTER (month_offset)); - - for (month = 0; month < 12; month++) { - name = e_get_month_name (month + 1, FALSE); - - menuitem = gtk_menu_item_new (); - gtk_widget_show (menuitem); - gtk_container_add (GTK_CONTAINER (submenu), menuitem); - - label = gtk_label_new (name); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER (menuitem), label); - - g_object_set_data ( - G_OBJECT (menuitem), "month", - GINT_TO_POINTER (month)); - - g_signal_connect ( - menuitem, "activate", - G_CALLBACK (e_calendar_item_on_menu_item_activate), - calitem); - } - } - - g_signal_connect ( - menu, "deactivate", - G_CALLBACK (deactivate_menu_cb), NULL); - - gdk_event_get_button (button_event, &event_button); - event_time = gdk_event_get_time (button_event); - - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, - e_calendar_item_position_menu, calitem, - event_button, event_time); -} - -static void -e_calendar_item_on_menu_item_activate (GtkWidget *menuitem, - ECalendarItem *calitem) -{ - GtkWidget *parent; - gint year, month_offset, month; - gpointer data; - - parent = gtk_widget_get_parent (menuitem); - data = g_object_get_data (G_OBJECT (parent), "year"); - year = GPOINTER_TO_INT (data); - - parent = gtk_widget_get_parent (menuitem); - data = g_object_get_data (G_OBJECT (parent), "month_offset"); - month_offset = GPOINTER_TO_INT (data); - - data = g_object_get_data (G_OBJECT (menuitem), "month"); - month = GPOINTER_TO_INT (data); - - month -= month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - e_calendar_item_set_first_month (calitem, year, month); -} - -static void -e_calendar_item_position_menu (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) -{ - GtkRequisition requisition; - gint screen_width, screen_height; - - gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL); - - *x -= (gtk_widget_get_direction(GTK_WIDGET(menu)) == GTK_TEXT_DIR_RTL) - ? requisition.width - 2 - : 2; - *y -= requisition.height / 2; - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - *x = CLAMP (*x, 0, screen_width - requisition.width); - *y = CLAMP (*y, 0, screen_height - requisition.height); -} - -/* Sets the function to call to get the colors to use for a particular day. */ -void -e_calendar_item_set_style_callback (ECalendarItem *calitem, - ECalendarItemStyleCallback cb, - gpointer data, - GDestroyNotify destroy) -{ - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - if (calitem->style_callback_data && calitem->style_callback_destroy) - (*calitem->style_callback_destroy) (calitem->style_callback_data); - - calitem->style_callback = cb; - calitem->style_callback_data = data; - calitem->style_callback_destroy = destroy; -} - -static void -e_calendar_item_date_range_changed (ECalendarItem *calitem) -{ - g_free (calitem->styles); - calitem->styles = NULL; - calitem->date_range_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); -} - -static void -e_calendar_item_queue_signal_emission (ECalendarItem *calitem) -{ - if (calitem->signal_emission_idle_id == 0) { - calitem->signal_emission_idle_id = g_idle_add_full ( - G_PRIORITY_HIGH, (GSourceFunc) - e_calendar_item_signal_emission_idle_cb, - calitem, NULL); - } -} - -static gboolean -e_calendar_item_signal_emission_idle_cb (gpointer data) -{ - ECalendarItem *calitem; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (data), FALSE); - - calitem = E_CALENDAR_ITEM (data); - - calitem->signal_emission_idle_id = 0; - - /* We ref the calitem & check in case it gets destroyed, since we - * were getting a free memory write here. */ - g_object_ref ((calitem)); - - if (calitem->date_range_changed) { - calitem->date_range_changed = FALSE; - g_signal_emit (calitem, e_calendar_item_signals[DATE_RANGE_CHANGED], 0); - } - - if (calitem->selection_changed) { - calitem->selection_changed = FALSE; - g_signal_emit (calitem, e_calendar_item_signals[SELECTION_CHANGED], 0); - } - - g_object_unref ((calitem)); - - return FALSE; -} - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void -e_calendar_item_set_get_time_callback (ECalendarItem *calitem, - ECalendarItemGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy) -{ - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - if (calitem->time_callback_data && calitem->time_callback_destroy) - (*calitem->time_callback_destroy) (calitem->time_callback_data); - - calitem->time_callback = cb; - calitem->time_callback_data = data; - calitem->time_callback_destroy = destroy; -} diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h deleted file mode 100644 index d8fc5f7277..0000000000 --- a/widgets/misc/e-calendar-item.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -#ifndef _E_CALENDAR_ITEM_H_ -#define _E_CALENDAR_ITEM_H_ - -#include <libgnomecanvas/gnome-canvas.h> - -G_BEGIN_DECLS - -/* - * ECalendarItem - canvas item displaying a calendar. - */ - -#define E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME 1 - -/* The number of rows & columns of days in each month. */ -#define E_CALENDAR_ROWS_PER_MONTH 6 -#define E_CALENDAR_COLS_PER_MONTH 7 - -/* Used to mark days as bold in e_calendar_item_mark_day(). */ -#define E_CALENDAR_ITEM_MARK_BOLD (1 << 0) -#define E_CALENDAR_ITEM_MARK_ITALIC (1 << 1) - -/* - * These are the padding sizes between various pieces of the calendar. - */ - -/* The minimum padding around the numbers in each cell/day. */ -#define E_CALENDAR_ITEM_MIN_CELL_XPAD 4 -#define E_CALENDAR_ITEM_MIN_CELL_YPAD 0 - -/* Vertical padding. */ -#define E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS 0 -#define E_CALENDAR_ITEM_YPAD_ABOVE_CELLS 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_CELLS 2 - -/* Horizontal padding in the heading bars. */ -#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME_WITH_BUTTON 10 -#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME 3 -#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME 3 -#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME_WITH_BUTTON 10 - -/* Horizontal padding in the month displays. */ -#define E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS 4 -#define E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS 2 -#define E_CALENDAR_ITEM_XPAD_BEFORE_CELLS 1 -#define E_CALENDAR_ITEM_XPAD_AFTER_CELLS 4 - -/* These index our colors array. */ -typedef enum -{ - E_CALENDAR_ITEM_COLOR_TODAY_BOX, - E_CALENDAR_ITEM_COLOR_SELECTION_FG, - E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED, - E_CALENDAR_ITEM_COLOR_SELECTION_BG, - E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG, - - E_CALENDAR_ITEM_COLOR_LAST -} ECalendarItemColors; - -typedef struct _ECalendarItem ECalendarItem; -typedef struct _ECalendarItemClass ECalendarItemClass; - -/* The type of the callback function optionally used to get the colors to - * use for each day. */ -typedef void (*ECalendarItemStyleCallback) (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gboolean *italic, - gpointer data); - -/* The type of the callback function optionally used to get the current time. - */ -typedef struct tm (*ECalendarItemGetTimeCallback) (ECalendarItem *calitem, - gpointer data); - -/* Standard GObject macros */ -#define E_TYPE_CALENDAR_ITEM \ - (e_calendar_item_get_type ()) -#define E_CALENDAR_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CALENDAR_ITEM, ECalendarItem)) -#define E_CALENDAR_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CALENDAR_ITEM, ECalendarItemClass)) -#define E_IS_CALENDAR_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CALENDAR_ITEM)) -#define E_IS_CALENDAR_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CALENDAR_ITEM)) -#define E_CALENDAR_ITEM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CALENDAR_ITEM, ECalendarItemClass)) - -struct _ECalendarItem -{ - GnomeCanvasItem canvas_item; - - /* The year & month of the first calendar being displayed. */ - gint year; - gint month; /* 0 to 11 */ - - /* Points to an array of styles, one gchar for each day. We use 32 - * chars for each month, with n + 2 months, where n is the number of - * complete months shown (since we show some days before the first - * month and after the last month grayes out). - * A value of 0 is the default, and 1 is bold. */ - guint8 *styles; - - /* - * Options. - */ - - /* The minimum & maximum number of rows & columns of months. - * If the maximum values are -1 then there is no maximum. - * The minimum valies default to 1. The maximum values to -1. */ - gint min_rows; - gint min_cols; - gint max_rows; - gint max_cols; - - /* The actual number of rows & columns of months. */ - gint rows; - gint cols; - - /* Whether we show week nubers. */ - gboolean show_week_numbers; - /* whether to keep same week days selected on week number click */ - gboolean keep_wdays_on_weeknum_click; - - /* The first day of the week, 0 (Monday) to 6 (Sunday). */ - gint week_start_day; - - /* Whether the cells expand to fill extra space. */ - gboolean expand; - - /* The maximum number of days that can be selected. Defaults to 1. */ - gint max_days_selected; - - /* The number of days selected before we switch to selecting whole - * weeks, or -1 if we never switch. Defaults to -1. */ - gint days_to_start_week_selection; - - /* Whether the selection is moved when we move back/forward one month. - * Used for things like the EDateEdit which only want the selection to - * be changed when the user explicitly selects a day. */ - gboolean move_selection_when_moving; - - /* Whether the selection day is preserved when we move back/forward - * one month. Used for the work week and week view. */ - gboolean preserve_day_when_moving; - - /* Whether to display the pop-up, TRUE by default */ - gboolean display_popup; - - /* - * Internal stuff. - */ - - /* Bounds of item. */ - gdouble x1, y1, x2, y2; - - /* The minimum size of each month, based on the fonts used. */ - gint min_month_width; - gint min_month_height; - - /* The actual size of each month, after dividing extra space. */ - gint month_width; - gint month_height; - - /* The offset to the left edge of the first calendar. */ - gint x_offset; - - /* The padding around each calendar month. */ - gint month_lpad, month_rpad; - gint month_tpad, month_bpad; - - /* The size of each cell. */ - gint cell_width; - gint cell_height; - - /* The current selection. The month offsets are from 0, which is the - * top-left calendar month view. Note that -1 is used for the last days - * from the previous month. The days are real month days. */ - gboolean selecting; - GDate *selecting_axis; - gboolean selection_dragging_end; - gboolean selection_from_full_week; - gboolean selection_set; - gint selection_start_month_offset; - gint selection_start_day; - gint selection_end_month_offset; - gint selection_end_day; - gint selection_real_start_month_offset; - gint selection_real_start_day; - - /* Widths of the day characters. */ - gint day_widths[7]; - gint max_day_width; - - /* Widths of the digits, '0' .. '9'. */ - gint digit_widths[10]; - gint max_digit_width; - - gint week_number_digit_widths[10]; - gint max_week_number_digit_width; - - gint max_month_name_width; - - /* Fonts for drawing text. If font isn't set it uses the font from the - * canvas widget. If week_number_font isn't set it uses font. */ - PangoFontDescription *font_desc; - PangoFontDescription *week_number_font_desc; - - ECalendarItemStyleCallback style_callback; - gpointer style_callback_data; - GDestroyNotify style_callback_destroy; - - ECalendarItemGetTimeCallback time_callback; - gpointer time_callback_data; - GDestroyNotify time_callback_destroy; - - /* Colors for drawing. */ - GdkColor colors[E_CALENDAR_ITEM_COLOR_LAST]; - - /* Our idle handler for emitting signals. */ - gint signal_emission_idle_id; - - /* A flag to indicate that the selection or date range has changed. - * When set the idle function will emit the signal and reset it to - * FALSE. This is so we don't emit it several times when args are set - * etc. */ - gboolean selection_changed; - gboolean date_range_changed; -}; - -struct _ECalendarItemClass -{ - GnomeCanvasItemClass parent_class; - - void (* date_range_changed) (ECalendarItem *calitem); - void (* selection_changed) (ECalendarItem *calitem); - void (* selection_preview_changed) (ECalendarItem *calitem); -}; - -GType e_calendar_item_get_type (void); - -/* FIXME: months are 0-11 throughout, but 1-12 may be better. */ - -void e_calendar_item_get_first_month (ECalendarItem *calitem, - gint *year, - gint *month); -void e_calendar_item_set_first_month (ECalendarItem *calitem, - gint year, - gint month); - -/* Get the maximum number of days selectable */ -gint e_calendar_item_get_max_days_sel (ECalendarItem *calitem); - -/* Set the maximum number of days selectable */ -void e_calendar_item_set_max_days_sel (ECalendarItem *calitem, - gint days); - -/* Get the maximum number of days selectable */ -gint e_calendar_item_get_days_start_week_sel (ECalendarItem *calitem); - -/* Set the maximum number of days selectable */ -void e_calendar_item_set_days_start_week_sel (ECalendarItem *calitem, - gint days); - -/* Set the maximum number of days before whole weeks are selected */ -gboolean - e_calendar_item_get_display_popup (ECalendarItem *calitem); - -/* Get the maximum number of days before whole weeks are selected */ -void e_calendar_item_set_display_popup (ECalendarItem *calitem, - gboolean display); - -/* Gets the range of dates actually shown. Months are 0 to 11. - * This also includes the last days of the previous month and the first days - * of the following month, which are normally shown in gray. - * It returns FALSE if no dates are currently shown. */ -gboolean - e_calendar_item_get_date_range (ECalendarItem *calitem, - gint *start_year, - gint *start_month, - gint *start_day, - gint *end_year, - gint *end_month, - gint *end_day); - -/* Returns the selected date range. It returns FALSE if no days are currently - * selected. */ -gboolean - e_calendar_item_get_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date); -/* Sets the selected date range, and changes the date range shown so at least - * the start of the selection is shown. If start_date is NULL it clears the - * selection. */ -void e_calendar_item_set_selection (ECalendarItem *calitem, - const GDate *start_date, - const GDate *end_date); - -/* Marks a particular day. Passing E_CALENDAR_ITEM_MARK_BOLD as the day style - * will result in the day being shown as bold by default. The style callback - * could support more day_styles, or the style callback could determine the - * colors itself, without needing to mark days. */ -void e_calendar_item_clear_marks (ECalendarItem *calitem); -void e_calendar_item_mark_day (ECalendarItem *calitem, - gint year, - gint month, - gint day, - guint8 day_style, - gboolean add_day_style); - -/* Mark a range of days. Any days outside the currently shown range are - * ignored. */ -void e_calendar_item_mark_days (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - guint8 day_style, - gboolean add_day_style); - -/* Sets the function to call to get the colors to use for a particular day. */ -void e_calendar_item_set_style_callback (ECalendarItem *calitem, - ECalendarItemStyleCallback cb, - gpointer data, - GDestroyNotify destroy); - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void e_calendar_item_set_get_time_callback (ECalendarItem *calitem, - ECalendarItemGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy); -void e_calendar_item_normalize_date (ECalendarItem *calitem, - gint *year, - gint *month); -gint e_calendar_item_get_week_number (ECalendarItem *calitem, - gint day, - gint month, - gint year); -void e_calendar_item_style_set (GtkWidget *widget, - ECalendarItem *calitem); - -G_END_DECLS - -#endif /* _E_CALENDAR_ITEM_H_ */ diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c deleted file mode 100644 index 38336cb618..0000000000 --- a/widgets/misc/e-calendar.c +++ /dev/null @@ -1,848 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECalendar - displays a table of monthly calendars, allowing highlighting - * and selection of one or more days. Like GtkCalendar with more features. - * Most of the functionality is in the ECalendarItem canvas item, though - * we also add GnomeCanvasWidget buttons to go to the previous/next month and - * to got to the current day. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-calendar.h" - -#include <gtk/gtk.h> -#include <libgnomecanvas/gnome-canvas-widget.h> -#include <glib/gi18n.h> - -#define E_CALENDAR_SMALL_FONT_PTSIZE 6 - -#define E_CALENDAR_SMALL_FONT \ - "-adobe-utopia-regular-r-normal-*-*-100-*-*-p-*-iso8859-*" -#define E_CALENDAR_SMALL_FONT_FALLBACK \ - "-adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-*" - -/* The space between the arrow buttons and the edge of the widget. */ -#define E_CALENDAR_ARROW_BUTTON_X_PAD 2 -#define E_CALENDAR_ARROW_BUTTON_Y_PAD 0 - -/* Vertical padding. The padding above the button includes the space for the - * horizontal line. */ -#define E_CALENDAR_YPAD_ABOVE_LOWER_BUTTONS 4 -#define E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS 3 - -/* Horizontal padding inside & between buttons. */ -#define E_CALENDAR_IXPAD_BUTTONS 4 -#define E_CALENDAR_XPAD_BUTTONS 8 - -/* The time between steps when the prev/next buttons is pressed, in 1/1000ths - * of a second, and the number of timeouts we skip before we start - * automatically moving back/forward. */ -#define E_CALENDAR_AUTO_MOVE_TIMEOUT 150 -#define E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY 2 - -static void e_calendar_dispose (GObject *object); -static void e_calendar_realize (GtkWidget *widget); -static void e_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void e_calendar_get_preferred_width (GtkWidget *widget, - gint *minimal_width, - gint *natural_width); -static void e_calendar_get_preferred_height (GtkWidget *widget, - gint *minimal_height, - gint *natural_height); -static void e_calendar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint e_calendar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void e_calendar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean e_calendar_button_has_focus (ECalendar *cal); -static gboolean e_calendar_focus (GtkWidget *widget, - GtkDirectionType direction); - -static void e_calendar_on_prev_pressed (ECalendar *cal); -static void e_calendar_on_prev_released (ECalendar *cal); -static void e_calendar_on_prev_clicked (ECalendar *cal); -static void e_calendar_on_next_pressed (ECalendar *cal); -static void e_calendar_on_next_released (ECalendar *cal); -static void e_calendar_on_next_clicked (ECalendar *cal); -static void e_calendar_on_prev_year_pressed (ECalendar *cal); -static void e_calendar_on_prev_year_released (ECalendar *cal); -static void e_calendar_on_prev_year_clicked (ECalendar *cal); -static void e_calendar_on_next_year_pressed (ECalendar *cal); -static void e_calendar_on_next_year_released (ECalendar *cal); -static void e_calendar_on_next_year_clicked (ECalendar *cal); - -static void e_calendar_start_auto_move (ECalendar *cal, - gboolean moving_forward); -static gboolean e_calendar_auto_move_handler (gpointer data); -static void e_calendar_start_auto_move_year (ECalendar *cal, - gboolean moving_forward); -static gboolean e_calendar_auto_move_year_handler (gpointer data); -static void e_calendar_stop_auto_move (ECalendar *cal); - -G_DEFINE_TYPE ( - ECalendar, - e_calendar, - E_TYPE_CANVAS) - -static void -e_calendar_class_init (ECalendarClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - object_class->dispose = e_calendar_dispose; - - widget_class->realize = e_calendar_realize; - widget_class->style_set = e_calendar_style_set; - widget_class->get_preferred_width = e_calendar_get_preferred_width; - widget_class->get_preferred_height = e_calendar_get_preferred_height; - widget_class->size_allocate = e_calendar_size_allocate; - widget_class->drag_motion = e_calendar_drag_motion; - widget_class->drag_leave = e_calendar_drag_leave; - widget_class->focus = e_calendar_focus; -} - -static void -e_calendar_init (ECalendar *cal) -{ - GnomeCanvasGroup *canvas_group; - PangoFontDescription *small_font_desc; - GtkWidget *button, *pixmap; - AtkObject *a11y; - - /* Create the small font. */ - - small_font_desc = pango_font_description_copy ( - gtk_widget_get_style (GTK_WIDGET (cal))->font_desc); - pango_font_description_set_size ( - small_font_desc, - E_CALENDAR_SMALL_FONT_PTSIZE * PANGO_SCALE); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (cal)->root); - - cal->calitem = E_CALENDAR_ITEM ( - gnome_canvas_item_new ( - canvas_group, - e_calendar_item_get_type (), - "week_number_font_desc", small_font_desc, - NULL)); - - pango_font_description_free (small_font_desc); - - /* Create the arrow buttons to move to the previous/next month. */ - button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - g_signal_connect_swapped ( - button, "pressed", - G_CALLBACK (e_calendar_on_prev_pressed), cal); - g_signal_connect_swapped ( - button, "released", - G_CALLBACK (e_calendar_on_prev_released), cal); - g_signal_connect_swapped ( - button, "clicked", - G_CALLBACK (e_calendar_on_prev_clicked), cal); - - pixmap = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); - gtk_widget_show (pixmap); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->prev_item = gnome_canvas_item_new ( - canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - a11y = gtk_widget_get_accessible (button); - atk_object_set_name (a11y, _("Previous month")); - - button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - g_signal_connect_swapped ( - button, "pressed", - G_CALLBACK (e_calendar_on_next_pressed), cal); - g_signal_connect_swapped ( - button, "released", - G_CALLBACK (e_calendar_on_next_released), cal); - g_signal_connect_swapped ( - button, "clicked", - G_CALLBACK (e_calendar_on_next_clicked), cal); - - pixmap = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - gtk_widget_show (pixmap); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->next_item = gnome_canvas_item_new ( - canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - a11y = gtk_widget_get_accessible (button); - atk_object_set_name (a11y, _("Next month")); - - /* Create the arrow buttons to move to the previous/next year. */ - button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - g_signal_connect_swapped ( - button, "pressed", - G_CALLBACK (e_calendar_on_prev_year_pressed), cal); - g_signal_connect_swapped ( - button, "released", - G_CALLBACK (e_calendar_on_prev_year_released), cal); - g_signal_connect_swapped ( - button, "clicked", - G_CALLBACK (e_calendar_on_prev_year_clicked), cal); - - pixmap = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); - gtk_widget_show (pixmap); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->prev_item_year = gnome_canvas_item_new ( - canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - a11y = gtk_widget_get_accessible (button); - atk_object_set_name (a11y, _("Previous year")); - - button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - g_signal_connect_swapped ( - button, "pressed", - G_CALLBACK (e_calendar_on_next_year_pressed), cal); - g_signal_connect_swapped ( - button, "released", - G_CALLBACK (e_calendar_on_next_year_released), cal); - g_signal_connect_swapped ( - button, "clicked", - G_CALLBACK (e_calendar_on_next_year_clicked), cal); - - pixmap = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - gtk_widget_show (pixmap); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->next_item_year = gnome_canvas_item_new ( - canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - a11y = gtk_widget_get_accessible (button); - atk_object_set_name (a11y, _("Next year")); - - cal->min_rows = 1; - cal->min_cols = 1; - cal->max_rows = -1; - cal->max_cols = -1; - - cal->timeout_id = 0; -} - -/** - * e_calendar_new: - * @Returns: a new #ECalendar. - * - * Creates a new #ECalendar. - **/ -GtkWidget * -e_calendar_new (void) -{ - GtkWidget *cal; - AtkObject *a11y; - - cal = g_object_new (e_calendar_get_type (), NULL); - a11y = gtk_widget_get_accessible (cal); - atk_object_set_name (a11y, _("Month Calendar")); - - return cal; -} - -static void -e_calendar_dispose (GObject *object) -{ - ECalendar *cal; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_CALENDAR (object)); - - cal = E_CALENDAR (object); - - if (cal->timeout_id != 0) { - g_source_remove (cal->timeout_id); - cal->timeout_id = 0; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_calendar_parent_class)->dispose (object); -} - -static void -e_calendar_realize (GtkWidget *widget) -{ - GtkStyle *style; - GdkWindow *window; - - (*GTK_WIDGET_CLASS (e_calendar_parent_class)->realize) (widget); - - /* Set the background of the canvas window to the normal color, - * or the arrow buttons are not displayed properly. */ - style = gtk_widget_get_style (widget); - window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); - gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]); -} - -static void -e_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - ECalendar *e_calendar; - - e_calendar = E_CALENDAR (widget); - if (GTK_WIDGET_CLASS (e_calendar_parent_class)->style_set) - (*GTK_WIDGET_CLASS (e_calendar_parent_class)->style_set) (widget, - previous_style); - - /* Set the background of the canvas window to the normal color, - * or the arrow buttons are not displayed properly. */ - if (gtk_widget_get_realized (widget)) { - GtkStyle *style; - GdkWindow *window; - - style = gtk_widget_get_style (widget); - window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); - gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]); - } - e_calendar_item_style_set (widget, e_calendar->calitem); -} - -static void -e_calendar_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - ECalendar *cal; - GtkStyle *style; - gint col_width; - - cal = E_CALENDAR (widget); - style = gtk_widget_get_style (GTK_WIDGET (cal)); - - g_object_get ((cal->calitem), "column_width", &col_width, NULL); - - *minimum = *natural = col_width * cal->min_cols + style->xthickness * 2; -} - -static void -e_calendar_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - ECalendar *cal; - GtkStyle *style; - gint row_height; - - cal = E_CALENDAR (widget); - style = gtk_widget_get_style (GTK_WIDGET (cal)); - - g_object_get ((cal->calitem), "row_height", &row_height, NULL); - - *minimum = *natural = row_height * cal->min_rows + style->ythickness * 2; -} - -static void -e_calendar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - ECalendar *cal; - GtkStyle *style; - GtkAllocation old_allocation; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - gdouble old_x2, old_y2, new_x2, new_y2; - gdouble xthickness, ythickness, arrow_button_size, current_x, month_width; - gboolean is_rtl; - - cal = E_CALENDAR (widget); - style = gtk_widget_get_style (widget); - xthickness = style->xthickness; - ythickness = style->ythickness; - - (*GTK_WIDGET_CLASS (e_calendar_parent_class)->size_allocate) (widget, allocation); - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (widget)->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - /* Set the scroll region to its allocated size, if changed. */ - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (cal), - NULL, NULL, &old_x2, &old_y2); - gtk_widget_get_allocation (widget, &old_allocation); - new_x2 = old_allocation.width - 1; - new_y2 = old_allocation.height - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (cal), - 0, 0, new_x2, new_y2); - - /* Take off space for line & buttons if shown. */ - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (cal->calitem), - "x1", 0.0, - "y1", 0.0, - "x2", new_x2, - "y2", new_y2, - NULL); - - if (cal->calitem->month_width > 0) - month_width = cal->calitem->month_width; - else - month_width = new_x2; - month_width -= E_CALENDAR_ITEM_MIN_CELL_XPAD + E_CALENDAR_ARROW_BUTTON_X_PAD; - - /* Position the arrow buttons. */ - arrow_button_size = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) - + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - - E_CALENDAR_ARROW_BUTTON_Y_PAD * 2 - 2; - - is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL; - current_x = is_rtl ? - (month_width - 2 * xthickness - E_CALENDAR_ARROW_BUTTON_X_PAD - arrow_button_size) : - (xthickness); - - gnome_canvas_item_set ( - cal->prev_item, - "x", current_x, - "y", ythickness + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); - - current_x += (is_rtl ? -1.0 : +1.0) * (cal->calitem->max_month_name_width - xthickness + 2 * arrow_button_size); - - gnome_canvas_item_set ( - cal->next_item, - "x", current_x, - "y", ythickness + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); - - current_x = is_rtl ? - (xthickness) : - (month_width - 2 * xthickness - E_CALENDAR_ARROW_BUTTON_X_PAD - arrow_button_size); - - gnome_canvas_item_set ( - cal->next_item_year, - "x", current_x, - "y", ythickness + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); - - current_x += (is_rtl ? +1.0 : -1.0) * (cal->calitem->max_digit_width * 5 - xthickness + 2 * arrow_button_size); - - gnome_canvas_item_set ( - cal->prev_item_year, - "x", current_x, - "y", ythickness + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); - - pango_font_metrics_unref (font_metrics); -} - -void -e_calendar_set_minimum_size (ECalendar *cal, - gint rows, - gint cols) -{ - g_return_if_fail (E_IS_CALENDAR (cal)); - - cal->min_rows = rows; - cal->min_cols = cols; - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (cal->calitem), - "minimum_rows", rows, - "minimum_columns", cols, - NULL); - - gtk_widget_queue_resize (GTK_WIDGET (cal)); -} - -void -e_calendar_set_maximum_size (ECalendar *cal, - gint rows, - gint cols) -{ - g_return_if_fail (E_IS_CALENDAR (cal)); - - cal->max_rows = rows; - cal->max_cols = cols; - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (cal->calitem), - "maximum_rows", rows, - "maximum_columns", cols, - NULL); - - gtk_widget_queue_resize (GTK_WIDGET (cal)); -} - -/* Returns the border size on each side of the month displays. */ -void -e_calendar_get_border_size (ECalendar *cal, - gint *top, - gint *bottom, - gint *left, - gint *right) -{ - GtkStyle *style; - - g_return_if_fail (E_IS_CALENDAR (cal)); - - style = gtk_widget_get_style (GTK_WIDGET (cal)); - - if (style) { - *top = style->ythickness; - *bottom = style->ythickness; - *left = style->xthickness; - *right = style->xthickness; - } else { - *top = *bottom = *left = *right = 0; - } -} - -static void -e_calendar_on_prev_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move (cal, FALSE); -} - -static void -e_calendar_on_next_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move (cal, TRUE); -} - -static void -e_calendar_on_prev_year_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move_year (cal, FALSE); -} - -static void -e_calendar_on_next_year_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move_year (cal, TRUE); -} - -static void -e_calendar_start_auto_move (ECalendar *cal, - gboolean moving_forward) -{ - if (cal->timeout_id == 0) { - cal->timeout_id = g_timeout_add ( - E_CALENDAR_AUTO_MOVE_TIMEOUT, - e_calendar_auto_move_handler, - cal); - } - cal->timeout_delay = E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY; - cal->moving_forward = moving_forward; - -} - -static void -e_calendar_start_auto_move_year (ECalendar *cal, - gboolean moving_forward) -{ - if (cal->timeout_id == 0) { - cal->timeout_id = g_timeout_add ( - E_CALENDAR_AUTO_MOVE_TIMEOUT, - e_calendar_auto_move_year_handler, - cal); - } - cal->timeout_delay = E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY; - cal->moving_forward = moving_forward; -} - -static gboolean -e_calendar_auto_move_year_handler (gpointer data) -{ - ECalendar *cal; - ECalendarItem *calitem; - gint offset; - - g_return_val_if_fail (E_IS_CALENDAR (data), FALSE); - - cal = E_CALENDAR (data); - calitem = cal->calitem; - - if (cal->timeout_delay > 0) { - cal->timeout_delay--; - } else { - offset = cal->moving_forward ? 12 : -12; - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month + offset); - } - - return TRUE; -} - -static gboolean -e_calendar_auto_move_handler (gpointer data) -{ - ECalendar *cal; - ECalendarItem *calitem; - gint offset; - - g_return_val_if_fail (E_IS_CALENDAR (data), FALSE); - - cal = E_CALENDAR (data); - calitem = cal->calitem; - - if (cal->timeout_delay > 0) { - cal->timeout_delay--; - } else { - offset = cal->moving_forward ? 1 : -1; - e_calendar_item_set_first_month ( - calitem, calitem->year, - calitem->month + offset); - } - - return TRUE; -} - -static void -e_calendar_on_prev_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - -static void -e_calendar_on_next_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - -static void -e_calendar_on_prev_year_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - -static void -e_calendar_on_next_year_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - -static void -e_calendar_stop_auto_move (ECalendar *cal) -{ - if (cal->timeout_id != 0) { - g_source_remove (cal->timeout_id); - cal->timeout_id = 0; - } -} - -static void -e_calendar_on_prev_clicked (ECalendar *cal) -{ - e_calendar_item_set_first_month ( - cal->calitem, cal->calitem->year, - cal->calitem->month - 1); -} - -static void -e_calendar_on_next_clicked (ECalendar *cal) -{ - e_calendar_item_set_first_month ( - cal->calitem, cal->calitem->year, - cal->calitem->month + 1); -} - -static void -e_calendar_on_prev_year_clicked (ECalendar *cal) -{ - e_calendar_item_set_first_month ( - cal->calitem, cal->calitem->year, - cal->calitem->month - 12); -} - -static void -e_calendar_on_next_year_clicked (ECalendar *cal) -{ - e_calendar_item_set_first_month ( - cal->calitem, cal->calitem->year, - cal->calitem->month + 12); -} - -static gint -e_calendar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - return FALSE; -} - -static void -e_calendar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time) -{ -} - -static gboolean -e_calendar_button_has_focus (ECalendar *cal) -{ - GtkWidget *prev_widget, *next_widget; - gboolean ret_val; - - g_return_val_if_fail (E_IS_CALENDAR (cal), FALSE); - - prev_widget = GNOME_CANVAS_WIDGET (cal->prev_item)->widget; - next_widget = GNOME_CANVAS_WIDGET (cal->next_item)->widget; - ret_val = gtk_widget_has_focus (prev_widget) || - gtk_widget_has_focus (next_widget); - return ret_val; -} - -static gboolean -e_calendar_focus (GtkWidget *widget, - GtkDirectionType direction) -{ -#define E_CALENDAR_FOCUS_CHILDREN_NUM 5 - ECalendar *cal; - GnomeCanvas *canvas; - GnomeCanvasItem *children[E_CALENDAR_FOCUS_CHILDREN_NUM]; - gint focused_index = -1; - gint index; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE); - cal = E_CALENDAR (widget); - canvas = GNOME_CANVAS (widget); - - if (!gtk_widget_get_can_focus (widget)) - return FALSE; - - children[0] = GNOME_CANVAS_ITEM (cal->calitem); - children[1] = cal->prev_item; - children[2] = cal->next_item; - children[3] = cal->prev_item_year; - children[4] = cal->next_item_year; - - /* get current focused item, if e-calendar has had focus */ - if (gtk_widget_has_focus (widget) || e_calendar_button_has_focus (cal)) - for (index = 0; index < E_CALENDAR_FOCUS_CHILDREN_NUM; ++index) { - if (canvas->focused_item == NULL) - break; - - if (children[index] == canvas->focused_item) { - focused_index = index; - break; - } - } - - if (focused_index == -1) - if (direction == GTK_DIR_TAB_FORWARD) - focused_index = 0; - else - focused_index = E_CALENDAR_FOCUS_CHILDREN_NUM - 1; - else - if (direction == GTK_DIR_TAB_FORWARD) - ++focused_index; - else - --focused_index; - - if (focused_index < 0 || - focused_index >= E_CALENDAR_FOCUS_CHILDREN_NUM) - /* move out of e-calendar */ - return FALSE; - gnome_canvas_item_grab_focus (children[focused_index]); - if (GNOME_IS_CANVAS_WIDGET (children[focused_index])) { - widget = GNOME_CANVAS_WIDGET (children[focused_index])->widget; - gtk_widget_grab_focus (widget); - } - return TRUE; -} - -void -e_calendar_set_focusable (ECalendar *cal, - gboolean focusable) -{ - GtkWidget *widget; - GtkWidget *prev_widget, *next_widget; - GtkWidget *toplevel; - - g_return_if_fail (E_IS_CALENDAR (cal)); - - widget = GTK_WIDGET (cal); - prev_widget = GNOME_CANVAS_WIDGET (cal->prev_item)->widget; - next_widget = GNOME_CANVAS_WIDGET (cal->next_item)->widget; - - if (focusable) { - gtk_widget_set_can_focus (widget, TRUE); - gtk_widget_set_can_focus (prev_widget, TRUE); - gtk_widget_set_can_focus (next_widget, TRUE); - } - else { - if (gtk_widget_has_focus (GTK_WIDGET (cal)) || - e_calendar_button_has_focus (cal)) { - toplevel = gtk_widget_get_toplevel (widget); - if (toplevel) - gtk_widget_grab_focus (toplevel); - } - gtk_widget_set_can_focus (widget, FALSE); - gtk_widget_set_can_focus (prev_widget, FALSE); - gtk_widget_set_can_focus (next_widget, FALSE); - } -} diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h deleted file mode 100644 index bdf77786f2..0000000000 --- a/widgets/misc/e-calendar.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CALENDAR_H_ -#define _E_CALENDAR_H_ - -#include <gtk/gtk.h> -#include <misc/e-canvas.h> -#include "e-calendar-item.h" - -G_BEGIN_DECLS - -/* - * ECalendar - displays a table of monthly calendars, allowing highlighting - * and selection of one or more days. Like GtkCalendar with more features. - * Most of the functionality is in the ECalendarItem canvas item, though - * we also add GnomeCanvasWidget buttons to go to the previous/next month and - * to got to the current day. - */ - -/* Standard GObject macros */ -#define E_TYPE_CALENDAR \ - (e_calendar_get_type ()) -#define E_CALENDAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CALENDAR, ECalendar)) -#define E_CALENDAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CALENDAR, ECalendarClass)) -#define E_IS_CALENDAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CALENDAR)) -#define E_IS_CALENDAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CALENDAR)) -#define E_CALENDAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CALENDAR, ECalendarClass)) - -typedef struct _ECalendar ECalendar; -typedef struct _ECalendarClass ECalendarClass; - -struct _ECalendar { - ECanvas parent; - - ECalendarItem *calitem; - - GnomeCanvasItem *prev_item; - GnomeCanvasItem *next_item; - GnomeCanvasItem *prev_item_year; - GnomeCanvasItem *next_item_year; - - gint min_rows; - gint min_cols; - - gint max_rows; - gint max_cols; - - /* These are all used when the prev/next buttons are held down. - * moving_forward is TRUE if we are moving forward in time, i.e. the - * next button is pressed. */ - gint timeout_id; - gint timeout_delay; - gboolean moving_forward; -}; - -struct _ECalendarClass { - ECanvasClass parent_class; -}; - -GType e_calendar_get_type (void); -GtkWidget * e_calendar_new (void); -void e_calendar_set_minimum_size (ECalendar *cal, - gint rows, - gint cols); -void e_calendar_set_maximum_size (ECalendar *cal, - gint rows, - gint cols); -void e_calendar_get_border_size (ECalendar *cal, - gint *top, - gint *bottom, - gint *left, - gint *right); -void e_calendar_set_focusable (ECalendar *cal, - gboolean focusable); - -G_END_DECLS - -#endif /* _E_CALENDAR_H_ */ diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c deleted file mode 100644 index 0b1f05a6b8..0000000000 --- a/widgets/misc/e-canvas-background.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * e-canvas-background.c - background color for canvas. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <stdio.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas.h" -#include "misc/e-canvas-utils.h" - -#include "e-canvas-background.h" - -#define E_CANVAS_BACKGROUND_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_CANVAS_BACKGROUND_TYPE, ECanvasBackgroundPrivate)) - -/* workaround for avoiding API broken */ -#define ecb_get_type e_canvas_background_get_type -G_DEFINE_TYPE ( - ECanvasBackground, - ecb, - GNOME_TYPE_CANVAS_ITEM) - -#define d(x) - -struct _ECanvasBackgroundPrivate { - guint rgba; /* Fill color, RGBA */ -}; - -enum { - STYLE_SET, - LAST_SIGNAL -}; - -static guint ecb_signals[LAST_SIGNAL] = { 0, }; - -enum { - PROP_0, - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, -}; - -static void -ecb_bounds (GnomeCanvasItem *item, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2) -{ - *x1 = -G_MAXDOUBLE; - *y1 = -G_MAXDOUBLE; - *x2 = G_MAXDOUBLE; - *y2 = G_MAXDOUBLE; -} - -static void -ecb_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - gdouble x1, y1, x2, y2; - - x1 = item->x1; - y1 = item->y1; - x2 = item->x2; - y2 = item->y2; - - /* The bounds are all constants so we should only have to - * redraw once. */ - ecb_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2); - - if (item->x1 != x1 || item->y1 != y1 || - item->x2 != x2 || item->y2 != y2) - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, item->x2, item->y2); -} - -static void -ecb_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ECanvasBackground *ecb; - - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - - ecb = E_CANVAS_BACKGROUND (object); - - switch (property_id) { - case PROP_FILL_COLOR: - if (g_value_get_string (value)) - gdk_color_parse (g_value_get_string (value), &color); - - ecb->priv->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - if (pcolor) { - color = *pcolor; - } - - ecb->priv->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_RGBA: - ecb->priv->rgba = g_value_get_uint (value); - break; - - } - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ecb)); -} - -static void -ecb_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECanvasBackground *ecb; - - ecb = E_CANVAS_BACKGROUND (object); - - switch (property_id) { - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, ecb->priv->rgba); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -ecb_init (ECanvasBackground *ecb) -{ - ecb->priv = E_CANVAS_BACKGROUND_GET_PRIVATE (ecb); -} - -static void -ecb_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item); - - cairo_save (cr); - cairo_set_source_rgba ( - cr, - ((ecb->priv->rgba >> 24) & 0xff) / 255.0, - ((ecb->priv->rgba >> 16) & 0xff) / 255.0, - ((ecb->priv->rgba >> 8) & 0xff) / 255.0, - ( ecb->priv->rgba & 0xff) / 255.0); - cairo_paint (cr); - cairo_restore (cr); -} - -static GnomeCanvasItem * -ecb_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - return item; -} - -static void -ecb_style_set (ECanvasBackground *ecb, - GtkStyle *previous_style) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ecb); - - if (gtk_widget_get_realized (GTK_WIDGET (item->canvas))) - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ecb)); -} - -static void -ecb_class_init (ECanvasBackgroundClass *ecb_class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (ecb_class); - GObjectClass *object_class = G_OBJECT_CLASS (ecb_class); - - g_type_class_add_private (ecb_class, sizeof (ECanvasBackgroundPrivate)); - - object_class->set_property = ecb_set_property; - object_class->get_property = ecb_get_property; - - item_class->update = ecb_update; - item_class->draw = ecb_draw; - item_class->point = ecb_point; - item_class->bounds = ecb_bounds; - - ecb_class->style_set = ecb_style_set; - - g_object_class_install_property ( - object_class, - PROP_FILL_COLOR, - g_param_spec_string ( - "fill_color", - "Fill color", - "Fill color", - NULL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ( - "fill_color_gdk", - "GDK fill color", - "GDK fill color", - GDK_TYPE_COLOR, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ( - "fill_color_rgba", - "GDK fill color", - "GDK fill color", - 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); - - ecb_signals[STYLE_SET] = g_signal_new ( - "style_set", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECanvasBackgroundClass, style_set), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_STYLE); -} - diff --git a/widgets/misc/e-canvas-background.h b/widgets/misc/e-canvas-background.h deleted file mode 100644 index 3c07770701..0000000000 --- a/widgets/misc/e-canvas-background.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * e-canvas-background.h - background color for canvas. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CANVAS_BACKGROUND_H -#define E_CANVAS_BACKGROUND_H - -#include <libgnomecanvas/gnome-canvas.h> - -G_BEGIN_DECLS - -/* - * name type read/write description - * ------------------------------------------------------------------------------------------ - * fill_color string W X color specification for fill color, - * or NULL pointer for no color (transparent) - * fill_color_gdk GdkColor* RW Allocated GdkColor for fill - * x1 gdouble RW Coordinates for edges of background rectangle - * x2 gdouble RW Default is all of them = -1. - * y1 gdouble RW Which means that the entire space is shown. - * y2 gdouble RW If you need the rectangle to have negative coordinates, use an affine. - */ - -#define E_CANVAS_BACKGROUND_TYPE (e_canvas_background_get_type ()) -#define E_CANVAS_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_CANVAS_BACKGROUND_TYPE, ECanvasBackground)) -#define E_CANVAS_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_CANVAS_BACKGROUND_TYPE, ECanvasBackgroundClass)) -#define E_IS_CANVAS_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_CANVAS_BACKGROUND_TYPE)) -#define E_IS_CANVAS_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_CANVAS_BACKGROUND_TYPE)) - -typedef struct _ECanvasBackground ECanvasBackground; -typedef struct _ECanvasBackgroundClass ECanvasBackgroundClass; -typedef struct _ECanvasBackgroundPrivate ECanvasBackgroundPrivate; - -struct _ECanvasBackground { - GnomeCanvasItem item; - - ECanvasBackgroundPrivate *priv; -}; - -struct _ECanvasBackgroundClass { - GnomeCanvasItemClass parent_class; - void (*style_set) (ECanvasBackground *eti, GtkStyle *previous_style); -}; - -/* Standard Gtk function */ -GType e_canvas_background_get_type (void); - -G_END_DECLS - -#endif diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c deleted file mode 100644 index ec3aad3858..0000000000 --- a/widgets/misc/e-canvas-utils.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-canvas-utils.h" - -void -e_canvas_item_move_absolute (GnomeCanvasItem *item, - gdouble dx, - gdouble dy) -{ - cairo_matrix_t translate; - - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - cairo_matrix_init_translate (&translate, dx, dy); - - gnome_canvas_item_set_matrix (item, &translate); -} - -static double -compute_offset (gint top, - gint bottom, - gint page_top, - gint page_bottom) -{ - gint size = bottom - top; - gint offset = 0; - - if (top <= page_top && bottom >= page_bottom) - return 0; - - if (bottom > page_bottom) - offset = (bottom - page_bottom); - if (top < page_top + offset) - offset = (top - page_top); - - if (top <= page_top + offset && bottom >= page_bottom + offset) - return offset; - - if (top < page_top + size * 3 / 2 + offset) - offset = top - (page_top + size * 3 / 2); - if (bottom > page_bottom - size * 3 / 2 + offset) - offset = bottom - (page_bottom - size * 3 / 2); - if (top < page_top + size * 3 / 2 + offset) - offset = top - ((page_top + page_bottom - (bottom - top)) / 2); - - return offset; -} - -static void -e_canvas_show_area (GnomeCanvas *canvas, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - GtkAdjustment *h, *v; - gint dx = 0, dy = 0; - gdouble page_size; - gdouble lower; - gdouble upper; - gdouble value; - - g_return_if_fail (canvas != NULL); - g_return_if_fail (GNOME_IS_CANVAS (canvas)); - - h = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)); - page_size = gtk_adjustment_get_page_size (h); - lower = gtk_adjustment_get_lower (h); - upper = gtk_adjustment_get_upper (h); - value = gtk_adjustment_get_value (h); - dx = compute_offset (x1, x2, value, value + page_size); - if (dx) - gtk_adjustment_set_value (h, CLAMP (value + dx, lower, upper - page_size)); - - v = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)); - page_size = gtk_adjustment_get_page_size (v); - lower = gtk_adjustment_get_lower (v); - upper = gtk_adjustment_get_upper (v); - value = gtk_adjustment_get_value (v); - dy = compute_offset (y1, y2, value, value + page_size); - if (dy) - gtk_adjustment_set_value (v, CLAMP (value + dy, lower, upper - page_size)); -} - -void -e_canvas_item_show_area (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - g_return_if_fail (item != NULL); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - gnome_canvas_item_i2w (item, &x1, &y1); - gnome_canvas_item_i2w (item, &x2, &y2); - - e_canvas_show_area (item->canvas, x1, y1, x2, y2); -} - -static gboolean -e_canvas_area_shown (GnomeCanvas *canvas, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - GtkAdjustment *h, *v; - gint dx = 0, dy = 0; - gdouble page_size; - gdouble lower; - gdouble upper; - gdouble value; - - g_return_val_if_fail (canvas != NULL, FALSE); - g_return_val_if_fail (GNOME_IS_CANVAS (canvas), FALSE); - - h = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)); - page_size = gtk_adjustment_get_page_size (h); - lower = gtk_adjustment_get_lower (h); - upper = gtk_adjustment_get_upper (h); - value = gtk_adjustment_get_value (h); - dx = compute_offset (x1, x2, value, value + page_size); - if (CLAMP (value + dx, lower, upper - page_size) - value != 0) - return FALSE; - - v = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)); - page_size = gtk_adjustment_get_page_size (v); - lower = gtk_adjustment_get_lower (v); - upper = gtk_adjustment_get_upper (v); - value = gtk_adjustment_get_value (v); - dy = compute_offset (y1, y2, value, value + page_size); - if (CLAMP (value + dy, lower, upper - page_size) - value != 0) - return FALSE; - return TRUE; -} - -gboolean -e_canvas_item_area_shown (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - g_return_val_if_fail (item != NULL, FALSE); - g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (item), FALSE); - - gnome_canvas_item_i2w (item, &x1, &y1); - gnome_canvas_item_i2w (item, &x2, &y2); - - return e_canvas_area_shown (item->canvas, x1, y1, x2, y2); -} - -typedef struct { - gdouble x1; - gdouble y1; - gdouble x2; - gdouble y2; - GnomeCanvas *canvas; -} DoubsAndCanvas; - -static gboolean -show_area_timeout (gpointer data) -{ - DoubsAndCanvas *dac = data; - - e_canvas_show_area (dac->canvas, dac->x1, dac->y1, dac->x2, dac->y2); - g_object_unref (dac->canvas); - g_free (dac); - return FALSE; -} - -void -e_canvas_item_show_area_delayed (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2, - gint delay) -{ - DoubsAndCanvas *dac; - - g_return_if_fail (item != NULL); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - gnome_canvas_item_i2w (item, &x1, &y1); - gnome_canvas_item_i2w (item, &x2, &y2); - - dac = g_new (DoubsAndCanvas, 1); - dac->x1 = x1; - dac->y1 = y1; - dac->x2 = x2; - dac->y2 = y2; - dac->canvas = item->canvas; - g_object_ref (item->canvas); - g_timeout_add (delay, show_area_timeout, dac); -} diff --git a/widgets/misc/e-canvas-utils.h b/widgets/misc/e-canvas-utils.h deleted file mode 100644 index 0843ba8f17..0000000000 --- a/widgets/misc/e-canvas-utils.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_CANVAS_UTILS__ -#define __E_CANVAS_UTILS__ - -#include <libgnomecanvas/gnome-canvas.h> - -G_BEGIN_DECLS - -void e_canvas_item_move_absolute (GnomeCanvasItem *item, - gdouble dx, - gdouble dy); -void e_canvas_item_show_area (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2); -void e_canvas_item_show_area_delayed (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2, - gint delay); -/* Returns TRUE if the area is already shown on the screen (including - * spacing.) This is equivelent to returning FALSE iff show_area - * would do anything. */ -gboolean e_canvas_item_area_shown (GnomeCanvasItem *item, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2); - -G_END_DECLS - -#endif /* __E_CANVAS_UTILS__ */ diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c deleted file mode 100644 index 1767c1ac14..0000000000 --- a/widgets/misc/e-canvas-vbox.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-canvas.h" -#include "e-canvas-utils.h" -#include "e-canvas-vbox.h" - -static void e_canvas_vbox_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void e_canvas_vbox_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void e_canvas_vbox_dispose (GObject *object); - -static gint e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event); -static void e_canvas_vbox_realize (GnomeCanvasItem *item); - -static void e_canvas_vbox_reflow (GnomeCanvasItem *item, gint flags); - -static void e_canvas_vbox_real_add_item (ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); -static void e_canvas_vbox_real_add_item_start (ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); -static void e_canvas_vbox_resize_children (GnomeCanvasItem *item); - -enum { - PROP_0, - PROP_WIDTH, - PROP_MINIMUM_WIDTH, - PROP_HEIGHT, - PROP_SPACING -}; - -G_DEFINE_TYPE ( - ECanvasVbox, - e_canvas_vbox, - GNOME_TYPE_CANVAS_GROUP) - -static void -e_canvas_vbox_class_init (ECanvasVboxClass *class) -{ - GObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - class->add_item = e_canvas_vbox_real_add_item; - class->add_item_start = e_canvas_vbox_real_add_item_start; - - object_class->set_property = e_canvas_vbox_set_property; - object_class->get_property = e_canvas_vbox_get_property; - object_class->dispose = e_canvas_vbox_dispose; - - /* GnomeCanvasItem method overrides */ - item_class->event = e_canvas_vbox_event; - item_class->realize = e_canvas_vbox_realize; - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - g_object_class_install_property ( - object_class, - PROP_MINIMUM_WIDTH, - g_param_spec_double ( - "minimum_width", - "Minimum width", - "Minimum Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_SPACING, - g_param_spec_double ( - "spacing", - "Spacing", - "Spacing", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); -} - -static void -e_canvas_vbox_init (ECanvasVbox *vbox) -{ - vbox->items = NULL; - - vbox->width = 10; - vbox->minimum_width = 10; - vbox->height = 10; - vbox->spacing = 0; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (vbox), e_canvas_vbox_reflow); -} - -static void -e_canvas_vbox_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - ECanvasVbox *e_canvas_vbox; - - item = GNOME_CANVAS_ITEM (object); - e_canvas_vbox = E_CANVAS_VBOX (object); - - switch (property_id) { - case PROP_WIDTH: - case PROP_MINIMUM_WIDTH: - e_canvas_vbox->minimum_width = g_value_get_double (value); - e_canvas_vbox_resize_children (item); - e_canvas_item_request_reflow (item); - break; - case PROP_SPACING: - e_canvas_vbox->spacing = g_value_get_double (value); - e_canvas_item_request_reflow (item); - break; - } -} - -static void -e_canvas_vbox_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECanvasVbox *e_canvas_vbox; - - e_canvas_vbox = E_CANVAS_VBOX (object); - - switch (property_id) { - case PROP_WIDTH: - g_value_set_double (value, e_canvas_vbox->width); - break; - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, e_canvas_vbox->minimum_width); - break; - case PROP_HEIGHT: - g_value_set_double (value, e_canvas_vbox->height); - break; - case PROP_SPACING: - g_value_set_double (value, e_canvas_vbox->spacing); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -/* Used from g_list_foreach(); disconnects from an item's signals */ -static void -disconnect_item_cb (gpointer data, - gpointer user_data) -{ - ECanvasVbox *vbox; - GnomeCanvasItem *item; - - vbox = E_CANVAS_VBOX (user_data); - - item = GNOME_CANVAS_ITEM (data); - g_signal_handlers_disconnect_matched ( - item, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - vbox); -} - -static void -e_canvas_vbox_dispose (GObject *object) -{ - ECanvasVbox *vbox = E_CANVAS_VBOX (object); - - if (vbox->items) { - g_list_foreach (vbox->items, disconnect_item_cb, vbox); - g_list_free (vbox->items); - vbox->items = NULL; - } - - G_OBJECT_CLASS (e_canvas_vbox_parent_class)->dispose (object); -} - -static gint -e_canvas_vbox_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - gint return_val = TRUE; - - switch (event->type) { - case GDK_KEY_PRESS: - switch (event->key.keyval) { - case GDK_KEY_Left: - case GDK_KEY_KP_Left: - case GDK_KEY_Right: - case GDK_KEY_KP_Right: - case GDK_KEY_Down: - case GDK_KEY_KP_Down: - case GDK_KEY_Up: - case GDK_KEY_KP_Up: - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - return_val = TRUE; - break; - default: - return_val = FALSE; - break; - } - break; - default: - return_val = FALSE; - break; - } - if (!return_val) { - if (GNOME_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->event) - return GNOME_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->event (item, event); - } - return return_val; - -} - -static void -e_canvas_vbox_realize (GnomeCanvasItem *item) -{ - if (GNOME_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->realize) (item); - - e_canvas_vbox_resize_children (item); - e_canvas_item_request_reflow (item); -} - -static void -e_canvas_vbox_remove_item (gpointer data, - GObject *where_object_was) -{ - ECanvasVbox *vbox = data; - vbox->items = g_list_remove (vbox->items, where_object_was); -} - -static void -e_canvas_vbox_real_add_item (ECanvasVbox *e_canvas_vbox, - GnomeCanvasItem *item) -{ - e_canvas_vbox->items = g_list_append (e_canvas_vbox->items, item); - g_object_weak_ref ( - G_OBJECT (item), - e_canvas_vbox_remove_item, e_canvas_vbox); - if (GNOME_CANVAS_ITEM (e_canvas_vbox)->flags & GNOME_CANVAS_ITEM_REALIZED) { - gnome_canvas_item_set ( - item, - "width", (gdouble) e_canvas_vbox->minimum_width, - NULL); - e_canvas_item_request_reflow (item); - } -} - -static void -e_canvas_vbox_real_add_item_start (ECanvasVbox *e_canvas_vbox, - GnomeCanvasItem *item) -{ - e_canvas_vbox->items = g_list_prepend (e_canvas_vbox->items, item); - g_object_weak_ref ( - G_OBJECT (item), - e_canvas_vbox_remove_item, e_canvas_vbox); - if (GNOME_CANVAS_ITEM (e_canvas_vbox)->flags & GNOME_CANVAS_ITEM_REALIZED) { - gnome_canvas_item_set ( - item, - "width", (gdouble) e_canvas_vbox->minimum_width, - NULL); - e_canvas_item_request_reflow (item); - } -} - -static void -e_canvas_vbox_resize_children (GnomeCanvasItem *item) -{ - GList *list; - ECanvasVbox *e_canvas_vbox; - - e_canvas_vbox = E_CANVAS_VBOX (item); - for (list = e_canvas_vbox->items; list; list = list->next) { - GnomeCanvasItem *child = GNOME_CANVAS_ITEM (list->data); - gnome_canvas_item_set ( - child, - "width", (gdouble) e_canvas_vbox->minimum_width, - NULL); - } -} - -static void -e_canvas_vbox_reflow (GnomeCanvasItem *item, - gint flags) -{ - ECanvasVbox *e_canvas_vbox = E_CANVAS_VBOX (item); - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) { - - gdouble old_height; - gdouble running_height; - gdouble old_width; - gdouble max_width; - - old_width = e_canvas_vbox->width; - max_width = e_canvas_vbox->minimum_width; - - old_height = e_canvas_vbox->height; - running_height = 0; - - if (e_canvas_vbox->items == NULL) { - } else { - GList *list; - gdouble item_height; - gdouble item_width; - - list = e_canvas_vbox->items; - g_object_get ( - list->data, - "height", &item_height, - "width", &item_width, - NULL); - e_canvas_item_move_absolute ( - GNOME_CANVAS_ITEM (list->data), - (gdouble) 0, - (gdouble) running_height); - running_height += item_height; - if (max_width < item_width) - max_width = item_width; - list = g_list_next (list); - - for (; list; list = g_list_next (list)) { - running_height += e_canvas_vbox->spacing; - - g_object_get ( - list->data, - "height", &item_height, - "width", &item_width, - NULL); - - e_canvas_item_move_absolute ( - GNOME_CANVAS_ITEM (list->data), - (gdouble) 0, - (gdouble) running_height); - - running_height += item_height; - if (max_width < item_width) - max_width = item_width; - } - - } - e_canvas_vbox->height = running_height; - e_canvas_vbox->width = max_width; - if (old_height != e_canvas_vbox->height || - old_width != e_canvas_vbox->width) - e_canvas_item_request_parent_reflow (item); - } -} - -void -e_canvas_vbox_add_item (ECanvasVbox *e_canvas_vbox, - GnomeCanvasItem *item) -{ - if (E_CANVAS_VBOX_CLASS (G_OBJECT_GET_CLASS (e_canvas_vbox))->add_item) - (E_CANVAS_VBOX_CLASS (G_OBJECT_GET_CLASS (e_canvas_vbox))->add_item) (e_canvas_vbox, item); -} - -void -e_canvas_vbox_add_item_start (ECanvasVbox *e_canvas_vbox, - GnomeCanvasItem *item) -{ - if (E_CANVAS_VBOX_CLASS (G_OBJECT_GET_CLASS (e_canvas_vbox))->add_item_start) - (E_CANVAS_VBOX_CLASS (G_OBJECT_GET_CLASS (e_canvas_vbox))->add_item_start) (e_canvas_vbox, item); -} - diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h deleted file mode 100644 index 7f0110ce9e..0000000000 --- a/widgets/misc/e-canvas-vbox.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_CANVAS_VBOX_H__ -#define __E_CANVAS_VBOX_H__ - -#include <gtk/gtk.h> -#include <libgnomecanvas/gnome-canvas.h> - -G_BEGIN_DECLS - -/* ECanvasVbox - A canvas item container. - * - * The following arguments are available: - * - * name type read/write description - * -------------------------------------------------------------------------------- - * width gdouble RW width of the CanvasVbox - * height gdouble R height of the CanvasVbox - * spacing gdouble RW Spacing between items. - */ - -#define E_CANVAS_VBOX_TYPE (e_canvas_vbox_get_type ()) -#define E_CANVAS_VBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_CANVAS_VBOX_TYPE, ECanvasVbox)) -#define E_CANVAS_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_CANVAS_VBOX_TYPE, ECanvasVboxClass)) -#define E_IS_CANVAS_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_CANVAS_VBOX_TYPE)) -#define E_IS_CANVAS_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_CANVAS_VBOX_TYPE)) - -typedef struct _ECanvasVbox ECanvasVbox; -typedef struct _ECanvasVboxClass ECanvasVboxClass; - -struct _ECanvasVbox -{ - GnomeCanvasGroup parent; - - /* item specific fields */ - GList *items; /* Of type GnomeCanvasItem */ - - gdouble width; - gdouble minimum_width; - gdouble height; - gdouble spacing; -}; - -struct _ECanvasVboxClass -{ - GnomeCanvasGroupClass parent_class; - - /* Virtual methods. */ - void (* add_item) (ECanvasVbox *CanvasVbox, GnomeCanvasItem *item); - void (* add_item_start) (ECanvasVbox *CanvasVbox, GnomeCanvasItem *item); -}; - -/* - * To be added to a CanvasVbox, an item must have the argument "width" as - * a Read/Write argument and "height" as a Read Only argument. It - * should also do an ECanvas parent CanvasVbox request if its size - * changes. - */ -void e_canvas_vbox_add_item (ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); -void e_canvas_vbox_add_item_start (ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); -GType e_canvas_vbox_get_type (void); - -G_END_DECLS - -#endif /* __E_CANVAS_VBOX_H__ */ diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c deleted file mode 100644 index 3ffc105867..0000000000 --- a/widgets/misc/e-canvas.c +++ /dev/null @@ -1,882 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-canvas.h" - -#define d(x) - -enum { - REFLOW, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE ( - ECanvas, - e_canvas, - GNOME_TYPE_CANVAS) - -/* Emits an event for an item in the canvas, be it the current - * item, grabbed item, or focused item, as appropriate. */ -static gint -canvas_emit_event (GnomeCanvas *canvas, - GdkEvent *event) -{ - GdkEvent *ev; - gint finished; - GnomeCanvasItem *item; - GnomeCanvasItem *parent; - guint mask; - - /* Choose where we send the event */ - - item = canvas->current_item; - - if (canvas->focused_item && - ((event->type == GDK_KEY_PRESS) || - (event->type == GDK_KEY_RELEASE) || - (event->type == GDK_FOCUS_CHANGE))) - item = canvas->focused_item; - - if (canvas->grabbed_item) - item = canvas->grabbed_item; - - /* Perform checks for grabbed items */ - - if (canvas->grabbed_item) { - switch (event->type) { - case GDK_ENTER_NOTIFY: - mask = GDK_ENTER_NOTIFY_MASK; - break; - - case GDK_LEAVE_NOTIFY: - mask = GDK_LEAVE_NOTIFY_MASK; - break; - - case GDK_MOTION_NOTIFY: - mask = GDK_POINTER_MOTION_MASK; - break; - - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - mask = GDK_BUTTON_PRESS_MASK; - break; - - case GDK_BUTTON_RELEASE: - mask = GDK_BUTTON_RELEASE_MASK; - break; - - case GDK_KEY_PRESS: - mask = GDK_KEY_PRESS_MASK; - break; - - case GDK_KEY_RELEASE: - mask = GDK_KEY_RELEASE_MASK; - break; - - default: - mask = 0; - break; - } - - if (!(mask & canvas->grabbed_event_mask)) - return FALSE; - } - - /* Convert to world coordinates -- we have two cases because of - * different offsets of the fields in the event structures. */ - - ev = gdk_event_copy (event); - - switch (ev->type) { - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - gnome_canvas_window_to_world ( - canvas, - ev->crossing.x, ev->crossing.y, - &ev->crossing.x, &ev->crossing.y); - break; - - case GDK_MOTION_NOTIFY: - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - gnome_canvas_window_to_world ( - canvas, - ev->motion.x, ev->motion.y, - &ev->motion.x, &ev->motion.y); - break; - - default: - break; - } - - /* The event is propagated up the hierarchy (for if someone connected - * to a group instead of a leaf event), and emission is stopped if a - * handler returns TRUE, just like for GtkWidget events. */ - - finished = FALSE; - - while (item && !finished) { - g_object_ref (item); - - g_signal_emit_by_name (item, "event", ev, &finished); - - parent = item->parent; - g_object_unref (item); - - item = parent; - } - - gdk_event_free (ev); - - return finished; -} - -/* This routine invokes the point method of the item. The argument x, y - * should be in the parent's item-relative coordinate system. This routine - * applies the inverse of the item's transform, maintaining the affine - * invariant. */ -static GnomeCanvasItem * -gnome_canvas_item_invoke_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - cairo_matrix_t inverse; - - /* Calculate x & y in item local coordinates */ - inverse = item->matrix; - if (cairo_matrix_invert (&inverse) != CAIRO_STATUS_SUCCESS) - return NULL; - - cairo_matrix_transform_point (&inverse, &x, &y); - - if (GNOME_CANVAS_ITEM_GET_CLASS (item)->point) - return GNOME_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy); - - return NULL; -} - -/* Re-picks the current item in the canvas, based on the event's coordinates. - * Also emits enter/leave events for items as appropriate. - */ -#define DISPLAY_X1(canvas) (GNOME_CANVAS (canvas)->layout.xoffset) -#define DISPLAY_Y1(canvas) (GNOME_CANVAS (canvas)->layout.yoffset) -static gint -pick_current_item (GnomeCanvas *canvas, - GdkEvent *event) -{ - gint button_down; - gdouble x, y; - gint cx, cy; - gint retval; - - retval = FALSE; - - /* If a button is down, we'll perform enter and leave events on the - * current item, but not enter on any other item. This is more or less - * like X pointer grabbing for canvas items. - */ - button_down = canvas->state & (GDK_BUTTON1_MASK - | GDK_BUTTON2_MASK - | GDK_BUTTON3_MASK - | GDK_BUTTON4_MASK - | GDK_BUTTON5_MASK); - if (!button_down) - canvas->left_grabbed_item = FALSE; - - /* Save the event in the canvas. This is used to synthesize enter and - * leave events in case the current item changes. It is also used to - * re-pick the current item if the current one gets deleted. Also, - * synthesize an enter event. - */ - if (event != &canvas->pick_event) { - if ((event->type == GDK_MOTION_NOTIFY) || - (event->type == GDK_BUTTON_RELEASE)) { - /* these fields have the same offsets in both types of events */ - - canvas->pick_event.crossing.type = GDK_ENTER_NOTIFY; - canvas->pick_event.crossing.window = event->motion.window; - canvas->pick_event.crossing.send_event = event->motion.send_event; - canvas->pick_event.crossing.subwindow = NULL; - canvas->pick_event.crossing.x = event->motion.x; - canvas->pick_event.crossing.y = event->motion.y; - canvas->pick_event.crossing.mode = GDK_CROSSING_NORMAL; - canvas->pick_event.crossing.detail = GDK_NOTIFY_NONLINEAR; - canvas->pick_event.crossing.focus = FALSE; - canvas->pick_event.crossing.state = event->motion.state; - - /* these fields don't have the same offsets in both types of events */ - - if (event->type == GDK_MOTION_NOTIFY) { - canvas->pick_event.crossing.x_root = event->motion.x_root; - canvas->pick_event.crossing.y_root = event->motion.y_root; - } else { - canvas->pick_event.crossing.x_root = event->button.x_root; - canvas->pick_event.crossing.y_root = event->button.y_root; - } - } else - canvas->pick_event = *event; - } - - /* Don't do anything else if this is a recursive call */ - - if (canvas->in_repick) - return retval; - - /* LeaveNotify means that there is no current item, so we don't look for one */ - - if (canvas->pick_event.type != GDK_LEAVE_NOTIFY) { - /* these fields don't have the same offsets in both types of events */ - - if (canvas->pick_event.type == GDK_ENTER_NOTIFY) { - x = canvas->pick_event.crossing.x + - canvas->scroll_x1 - canvas->zoom_xofs; - y = canvas->pick_event.crossing.y + - canvas->scroll_y1 - canvas->zoom_yofs; - } else { - x = canvas->pick_event.motion.x + - canvas->scroll_x1 - canvas->zoom_xofs; - y = canvas->pick_event.motion.y + - canvas->scroll_y1 - canvas->zoom_yofs; - } - - /* canvas pixel coords */ - - cx = (gint) (x + 0.5); - cy = (gint) (y + 0.5); - - /* world coords */ - - x = canvas->scroll_x1 + x; - y = canvas->scroll_y1 + y; - - /* find the closest item */ - - if (canvas->root->flags & GNOME_CANVAS_ITEM_VISIBLE) - canvas->new_current_item = - gnome_canvas_item_invoke_point ( - canvas->root, x, y, cx, cy); - else - canvas->new_current_item = NULL; - } else - canvas->new_current_item = NULL; - - if ((canvas->new_current_item == canvas->current_item) && - !canvas->left_grabbed_item) - return retval; /* current item did not change */ - - /* Synthesize events for old and new current items */ - - if ((canvas->new_current_item != canvas->current_item) - && (canvas->current_item != NULL) - && !canvas->left_grabbed_item) { - GdkEvent new_event = { 0 }; - - new_event = canvas->pick_event; - new_event.type = GDK_LEAVE_NOTIFY; - - new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; - new_event.crossing.subwindow = NULL; - canvas->in_repick = TRUE; - retval = canvas_emit_event (canvas, &new_event); - canvas->in_repick = FALSE; - } - - /* new_current_item may have been set to NULL during - * the call to canvas_emit_event() above. */ - - if ((canvas->new_current_item != canvas->current_item) && button_down) { - canvas->left_grabbed_item = TRUE; - return retval; - } - - /* Handle the rest of cases */ - - canvas->left_grabbed_item = FALSE; - canvas->current_item = canvas->new_current_item; - - if (canvas->current_item != NULL) { - GdkEvent new_event = { 0 }; - - new_event = canvas->pick_event; - new_event.type = GDK_ENTER_NOTIFY; - new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; - new_event.crossing.subwindow = NULL; - retval = canvas_emit_event (canvas, &new_event); - } - - return retval; -} - -static void -canvas_style_set_recursive (GnomeCanvasItem *item, - GtkStyle *previous_style) -{ - guint signal_id = g_signal_lookup ("style_set", G_OBJECT_TYPE (item)); - if (signal_id >= 1) { - GSignalQuery query; - g_signal_query (signal_id, &query); - if (query.return_type == G_TYPE_NONE && - query.n_params == 1 && - query.param_types[0] == GTK_TYPE_STYLE) { - g_signal_emit (item, signal_id, 0, previous_style); - } - } - - if (GNOME_IS_CANVAS_GROUP (item)) { - GList *items = GNOME_CANVAS_GROUP (item)->item_list; - for (; items; items = items->next) - canvas_style_set_recursive ( - items->data, previous_style); - } -} - -static void -canvas_dispose (GObject *object) -{ - ECanvas *canvas = E_CANVAS (object); - - if (canvas->idle_id) - g_source_remove (canvas->idle_id); - canvas->idle_id = 0; - - if (canvas->grab_cancelled_check_id) - g_source_remove (canvas->grab_cancelled_check_id); - canvas->grab_cancelled_check_id = 0; - - if (canvas->toplevel) { - if (canvas->visibility_notify_id) - g_signal_handler_disconnect ( - canvas->toplevel, - canvas->visibility_notify_id); - canvas->visibility_notify_id = 0; - - g_object_unref (canvas->toplevel); - canvas->toplevel = NULL; - } - - if (canvas->im_context) { - g_object_unref (canvas->im_context); - canvas->im_context = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_canvas_parent_class)->dispose (object); -} - -static void -canvas_realize (GtkWidget *widget) -{ - ECanvas *ecanvas = E_CANVAS (widget); - GdkWindow *window; - - /* Chain up to parent's realize() method. */ - GTK_WIDGET_CLASS (e_canvas_parent_class)->realize (widget); - - window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); - gdk_window_set_background_pattern (window, NULL); - - window = gtk_widget_get_window (widget); - gtk_im_context_set_client_window (ecanvas->im_context, window); -} - -static void -canvas_unrealize (GtkWidget *widget) -{ - ECanvas * ecanvas = E_CANVAS (widget); - - if (ecanvas->idle_id) { - g_source_remove (ecanvas->idle_id); - ecanvas->idle_id = 0; - } - - gtk_im_context_set_client_window (ecanvas->im_context, NULL); - - /* Chain up to parent's unrealize() method. */ - GTK_WIDGET_CLASS (e_canvas_parent_class)->unrealize (widget); -} - -static void -canvas_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - canvas_style_set_recursive ( - GNOME_CANVAS_ITEM (gnome_canvas_root ( - GNOME_CANVAS (widget))), previous_style); -} - -static gint -canvas_button_event (GtkWidget *widget, - GdkEventButton *event) -{ - GnomeCanvas *canvas; - GdkWindow *bin_window; - gint mask; - gint retval; - - g_return_val_if_fail (GNOME_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - retval = FALSE; - - canvas = GNOME_CANVAS (widget); - bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (canvas)); - - d ( - g_print ("button %d, event type %d, grabbed=%p, current=%p\n", - event->button, - event->type, - canvas->grabbed_item, - canvas->current_item)); - - /* dispatch normally regardless of the event's window if an item has - has a pointer grab in effect */ - if (!canvas->grabbed_item && event->window != bin_window) - return retval; - - switch (event->button) { - case 1: - mask = GDK_BUTTON1_MASK; - break; - case 2: - mask = GDK_BUTTON2_MASK; - break; - case 3: - mask = GDK_BUTTON3_MASK; - break; - case 4: - mask = GDK_BUTTON4_MASK; - break; - case 5: - mask = GDK_BUTTON5_MASK; - break; - default: - mask = 0; - } - - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - /* Pick the current item as if the button were not - * pressed, and then process the event. */ - canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - canvas->state ^= mask; - retval = canvas_emit_event (canvas, (GdkEvent *) event); - break; - - case GDK_BUTTON_RELEASE: - /* Process the event as if the button were pressed, - * then repick after the button has been released. */ - canvas->state = event->state; - retval = canvas_emit_event (canvas, (GdkEvent *) event); - event->state ^= mask; - canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - event->state ^= mask; - break; - - default: - g_return_val_if_reached (0); - } - - return retval; -} - -static gint -canvas_key_event (GtkWidget *widget, - GdkEventKey *event) -{ - GnomeCanvas *canvas; - GdkEvent full_event = { 0 }; - - g_return_val_if_fail (GNOME_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - canvas = GNOME_CANVAS (widget); - - full_event.type = event->type; - full_event.key = *event; - - return canvas_emit_event (canvas, &full_event); -} - -static gint -canvas_focus_in_event (GtkWidget *widget, - GdkEventFocus *event) -{ - GnomeCanvas *canvas; - ECanvas *ecanvas; - GdkEvent full_event = { 0 }; - - canvas = GNOME_CANVAS (widget); - ecanvas = E_CANVAS (widget); - - /* XXX Can't access flags directly anymore, but is it really needed? - * If so, could we call gtk_widget_send_focus_change() instead? */ -#if 0 - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); -#endif - - gtk_im_context_focus_in (ecanvas->im_context); - - if (canvas->focused_item) { - full_event.type = event->type; - full_event.focus_change = *event; - return canvas_emit_event (canvas, &full_event); - } else { - return FALSE; - } -} - -static gint -canvas_focus_out_event (GtkWidget *widget, - GdkEventFocus *event) -{ - GnomeCanvas *canvas; - ECanvas *ecanvas; - GdkEvent full_event = { 0 }; - - canvas = GNOME_CANVAS (widget); - ecanvas = E_CANVAS (widget); - - /* XXX Can't access flags directly anymore, but is it really needed? - * If so, could we call gtk_widget_send_focus_change() instead? */ -#if 0 - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); -#endif - - gtk_im_context_focus_out (ecanvas->im_context); - - if (canvas->focused_item) { - full_event.type = event->type; - full_event.focus_change = *event; - return canvas_emit_event (canvas, &full_event); - } else { - return FALSE; - } -} - -static void -canvas_reflow (ECanvas *canvas) -{ - /* Placeholder so subclasses can safely chain up. */ -} - -static void -e_canvas_class_init (ECanvasClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = canvas_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = canvas_realize; - widget_class->unrealize = canvas_unrealize; - widget_class->style_set = canvas_style_set; - widget_class->button_press_event = canvas_button_event; - widget_class->button_release_event = canvas_button_event; - widget_class->key_press_event = canvas_key_event; - widget_class->key_release_event = canvas_key_event; - widget_class->focus_in_event = canvas_focus_in_event; - widget_class->focus_out_event = canvas_focus_out_event; - - class->reflow = canvas_reflow; - - signals[REFLOW] = g_signal_new ( - "reflow", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECanvasClass, reflow), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_canvas_init (ECanvas *canvas) -{ - canvas->im_context = gtk_im_multicontext_new (); -} - -GtkWidget * -e_canvas_new (void) -{ - return g_object_new (E_TYPE_CANVAS, NULL); -} - -/** - * e_canvas_item_grab_focus: - * @item: A canvas item. - * @widget_too: Whether or not to grab the widget-level focus too - * - * Makes the specified item take the keyboard focus, so all keyboard - * events will be sent to it. If the canvas widget itself did not have - * the focus and @widget_too is %TRUE, it grabs that focus as well. - **/ -void -e_canvas_item_grab_focus (GnomeCanvasItem *item, - gboolean widget_too) -{ - GnomeCanvasItem *focused_item; - GdkWindow *bin_window; - GdkEvent ev = { 0 }; - - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - g_return_if_fail (gtk_widget_get_can_focus (GTK_WIDGET (item->canvas))); - - bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (item->canvas)); - - focused_item = item->canvas->focused_item; - - if (focused_item) { - ev.type = GDK_FOCUS_CHANGE; - ev.focus_change.type = GDK_FOCUS_CHANGE; - ev.focus_change.window = bin_window; - ev.focus_change.send_event = FALSE; - ev.focus_change.in = FALSE; - - canvas_emit_event (item->canvas, &ev); - } - - item->canvas->focused_item = item; - - if (widget_too && !gtk_widget_has_focus (GTK_WIDGET (item->canvas))) { - gtk_widget_grab_focus (GTK_WIDGET (item->canvas)); - } - - if (item) { - ev.focus_change.type = GDK_FOCUS_CHANGE; - ev.focus_change.window = bin_window; - ev.focus_change.send_event = FALSE; - ev.focus_change.in = TRUE; - - canvas_emit_event (item->canvas, &ev); - } -} - -static void -e_canvas_item_invoke_reflow (GnomeCanvasItem *item, - gint flags) -{ - GnomeCanvasGroup *group; - GList *list; - GnomeCanvasItem *child; - - if (GNOME_IS_CANVAS_GROUP (item)) { - group = GNOME_CANVAS_GROUP (item); - for (list = group->item_list; list; list = list->next) { - child = GNOME_CANVAS_ITEM (list->data); - if (child->flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW) - e_canvas_item_invoke_reflow (child, flags); - } - } - - if (item->flags & E_CANVAS_ITEM_NEEDS_REFLOW) { - ECanvasItemReflowFunc func; - func = (ECanvasItemReflowFunc) - g_object_get_data ( - G_OBJECT (item), - "ECanvasItem::reflow_callback"); - if (func) - func (item, flags); - } - - item->flags &= ~E_CANVAS_ITEM_NEEDS_REFLOW; - item->flags &= ~E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW; -} - -static void -do_reflow (ECanvas *canvas) -{ - if (GNOME_CANVAS (canvas)->root->flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW) - e_canvas_item_invoke_reflow (GNOME_CANVAS (canvas)->root, 0); -} - -/* Idle handler for the e-canvas. It deals with pending reflows. */ -static gint -idle_handler (gpointer data) -{ - ECanvas *canvas; - - canvas = E_CANVAS (data); - do_reflow (canvas); - - /* Reset idle id */ - canvas->idle_id = 0; - - g_signal_emit (canvas, signals[REFLOW], 0); - - return FALSE; -} - -/* Convenience function to add an idle handler to a canvas */ -static void -add_idle (ECanvas *canvas) -{ - if (canvas->idle_id != 0) - return; - - canvas->idle_id = g_idle_add_full ( - G_PRIORITY_HIGH_IDLE, idle_handler, (gpointer) canvas, NULL); -} - -static void -e_canvas_item_descendent_needs_reflow (GnomeCanvasItem *item) -{ - if (item->flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW) - return; - - item->flags |= E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW; - if (item->parent) - e_canvas_item_descendent_needs_reflow (item->parent); -} - -void -e_canvas_item_request_reflow (GnomeCanvasItem *item) -{ - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) { - item->flags |= E_CANVAS_ITEM_NEEDS_REFLOW; - e_canvas_item_descendent_needs_reflow (item); - add_idle (E_CANVAS (item->canvas)); - } -} - -void -e_canvas_item_request_parent_reflow (GnomeCanvasItem *item) -{ - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - e_canvas_item_request_reflow (item->parent); -} - -void -e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, - ECanvasItemReflowFunc func) -{ - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - g_return_if_fail (func != NULL); - - g_object_set_data ( - G_OBJECT (item), "ECanvasItem::reflow_callback", - (gpointer) func); -} - -static gboolean -grab_cancelled_check (gpointer data) -{ - ECanvas *canvas = data; - - if (GNOME_CANVAS (canvas)->grabbed_item == NULL) { - canvas->grab_cancelled_cb = NULL; - canvas->grab_cancelled_check_id = 0; - canvas->grab_cancelled_time = 0; - canvas->grab_cancelled_data = NULL; - return FALSE; - } - - if (gtk_grab_get_current ()) { - gnome_canvas_item_ungrab ( - GNOME_CANVAS (canvas)->grabbed_item, - canvas->grab_cancelled_time); - if (canvas->grab_cancelled_cb) - canvas->grab_cancelled_cb ( - canvas, GNOME_CANVAS (canvas)->grabbed_item, - canvas->grab_cancelled_data); - canvas->grab_cancelled_cb = NULL; - canvas->grab_cancelled_check_id = 0; - canvas->grab_cancelled_time = 0; - canvas->grab_cancelled_data = NULL; - return FALSE; - } - return TRUE; -} - -gint -e_canvas_item_grab (ECanvas *canvas, - GnomeCanvasItem *item, - guint event_mask, - GdkCursor *cursor, - GdkDevice *device, - guint32 etime, - ECanvasItemGrabCancelled cancelled_cb, - gpointer cancelled_data) -{ - GdkGrabStatus grab_status; - - g_return_val_if_fail (E_IS_CANVAS (canvas), -1); - g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (item), -1); - g_return_val_if_fail (GDK_IS_DEVICE (device), -1); - - if (gtk_grab_get_current ()) - return GDK_GRAB_ALREADY_GRABBED; - - grab_status = gnome_canvas_item_grab ( - item, event_mask, cursor, device, etime); - if (grab_status == GDK_GRAB_SUCCESS) { - canvas->grab_cancelled_cb = cancelled_cb; - canvas->grab_cancelled_check_id = g_timeout_add_full ( - G_PRIORITY_LOW, 100, - grab_cancelled_check, canvas, NULL); - canvas->grab_cancelled_time = etime; - canvas->grab_cancelled_data = cancelled_data; - } - - return grab_status; -} - -void -e_canvas_item_ungrab (ECanvas *canvas, - GnomeCanvasItem *item, - guint32 etime) -{ - g_return_if_fail (E_IS_CANVAS (canvas)); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - if (canvas->grab_cancelled_check_id) { - g_source_remove (canvas->grab_cancelled_check_id); - canvas->grab_cancelled_cb = NULL; - canvas->grab_cancelled_check_id = 0; - canvas->grab_cancelled_time = 0; - canvas->grab_cancelled_data = NULL; - gnome_canvas_item_ungrab (item, etime); - } -} diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h deleted file mode 100644 index c5f2087cd0..0000000000 --- a/widgets/misc/e-canvas.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CANVAS_H -#define E_CANVAS_H - -#include <gtk/gtk.h> -#include <libgnomecanvas/gnome-canvas.h> - -/* ECanvas - A class derived from canvas for the purpose of adding - * evolution specific canvas hacks. */ - -/* Standard GObject macros */ -#define E_TYPE_CANVAS \ - (e_canvas_get_type ()) -#define E_CANVAS(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CANVAS, ECanvas)) -#define E_CANVAS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CANVAS, ECanvasClass)) -#define E_IS_CANVAS(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CANVAS)) -#define E_IS_CANVAS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CANVAS)) -#define E_CANVAS_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CANVAS, ECanvasClass)) - -G_BEGIN_DECLS - -typedef void (*ECanvasItemReflowFunc) (GnomeCanvasItem *item, - gint flags); - -typedef void (*ECanvasItemSelectionFunc) (GnomeCanvasItem *item, - gint flags, - gpointer user_data); -/* Returns the same as strcmp does. */ -typedef gint (*ECanvasItemSelectionCompareFunc) - (GnomeCanvasItem *item, - gpointer data1, - gpointer data2, - gint flags); - -typedef struct _ECanvas ECanvas; -typedef struct _ECanvasClass ECanvasClass; - -/* Object flags for items */ -enum { - E_CANVAS_ITEM_NEEDS_REFLOW = 1 << 13, - E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW = 1 << 14 -}; - -typedef struct { - GnomeCanvasItem *item; - gpointer id; -} ECanvasSelectionInfo; - -typedef void (*ECanvasItemGrabCancelled) (ECanvas *canvas, - GnomeCanvasItem *item, - gpointer data); - -struct _ECanvas { - GnomeCanvas parent; - - gint idle_id; - GList *selection; - ECanvasSelectionInfo *cursor; - - GtkWidget *tooltip_window; - gint visibility_notify_id; - GtkWidget *toplevel; - - /* Input context for dead key support */ - GtkIMContext *im_context; - - ECanvasItemGrabCancelled grab_cancelled_cb; - guint grab_cancelled_check_id; - guint32 grab_cancelled_time; - gpointer grab_cancelled_data; -}; - -struct _ECanvasClass { - GnomeCanvasClass parent_class; - - void (*reflow) (ECanvas *canvas); -}; - -GType e_canvas_get_type (void); -GtkWidget * e_canvas_new (void); - -/* Used to send all of the keystroke events to a specific item as well as - * GDK_FOCUS_CHANGE events. */ -void e_canvas_item_grab_focus (GnomeCanvasItem *item, - gboolean widget_too); -void e_canvas_item_request_reflow (GnomeCanvasItem *item); -void e_canvas_item_request_parent_reflow - (GnomeCanvasItem *item); -void e_canvas_item_set_reflow_callback - (GnomeCanvasItem *item, - ECanvasItemReflowFunc func); -gint e_canvas_item_grab (ECanvas *canvas, - GnomeCanvasItem *item, - guint event_mask, - GdkCursor *cursor, - GdkDevice *device, - guint32 etime, - ECanvasItemGrabCancelled cancelled, - gpointer cancelled_data); -void e_canvas_item_ungrab (ECanvas *canvas, - GnomeCanvasItem *item, - guint32 etime); - -G_END_DECLS - -#endif /* E_CANVAS_H */ diff --git a/widgets/misc/e-charset-combo-box.c b/widgets/misc/e-charset-combo-box.c deleted file mode 100644 index 01a814ad10..0000000000 --- a/widgets/misc/e-charset-combo-box.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * e-charset-combo-box.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-charset-combo-box.h" - -#include <glib/gi18n.h> - -#include "e-util/e-charset.h" -#include "e-util/e-util.h" - -#define E_CHARSET_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxPrivate)) - -#define DEFAULT_CHARSET "UTF-8" -#define OTHER_VALUE G_MAXINT - -struct _ECharsetComboBoxPrivate { - GtkActionGroup *action_group; - GtkRadioAction *other_action; - GHashTable *charset_index; - - /* Used when the user clicks Cancel in the character set - * dialog. Reverts to the previous combo box setting. */ - gint previous_index; - - /* When setting the character set programmatically, this - * prevents the custom character set dialog from running. */ - guint block_dialog : 1; -}; - -enum { - PROP_0, - PROP_CHARSET -}; - -G_DEFINE_TYPE ( - ECharsetComboBox, - e_charset_combo_box, - E_TYPE_ACTION_COMBO_BOX) - -static void -charset_combo_box_entry_changed_cb (GtkEntry *entry, - GtkDialog *dialog) -{ - const gchar *text; - gboolean sensitive; - - text = gtk_entry_get_text (entry); - sensitive = (text != NULL && *text != '\0'); - gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, sensitive); -} - -static void -charset_combo_box_run_dialog (ECharsetComboBox *combo_box) -{ - GtkDialog *dialog; - GtkEntry *entry; - GtkWidget *container; - GtkWidget *widget; - GObject *object; - gpointer parent; - const gchar *charset; - - /* FIXME Using a dialog for this is lame. Selecting "Other..." - * should unlock an entry directly in the Preferences tab. - * Unfortunately space in Preferences is at a premium right - * now, but we should revisit this when the space issue is - * finally resolved. */ - - parent = gtk_widget_get_toplevel (GTK_WIDGET (combo_box)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - object = G_OBJECT (combo_box->priv->other_action); - charset = g_object_get_data (object, "charset"); - - widget = gtk_dialog_new_with_buttons ( - _("Character Encoding"), parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - - /* Load the broken border width defaults so we can override them. */ - gtk_widget_ensure_style (widget); - - dialog = GTK_DIALOG (widget); - - gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK); - - gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); - - widget = gtk_dialog_get_action_area (dialog); - gtk_container_set_border_width (GTK_CONTAINER (widget), 0); - - widget = gtk_dialog_get_content_area (dialog); - gtk_box_set_spacing (GTK_BOX (widget), 12); - gtk_container_set_border_width (GTK_CONTAINER (widget), 0); - - container = widget; - - widget = gtk_label_new (_("Enter the character set to use")); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_entry_new (); - entry = GTK_ENTRY (widget); - gtk_entry_set_activates_default (entry, TRUE); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - g_signal_connect ( - entry, "changed", - G_CALLBACK (charset_combo_box_entry_changed_cb), dialog); - - /* Set the default text -after- connecting the signal handler. - * This will initialize the "OK" button to the proper state. */ - gtk_entry_set_text (entry, charset); - - if (gtk_dialog_run (dialog) != GTK_RESPONSE_OK) { - gint active; - - /* Revert to the previously selected character set. */ - combo_box->priv->block_dialog = TRUE; - active = combo_box->priv->previous_index; - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), active); - combo_box->priv->block_dialog = FALSE; - - goto exit; - } - - charset = gtk_entry_get_text (entry); - g_return_if_fail (charset != NULL && charset != '\0'); - - g_object_set_data_full ( - object, "charset", g_strdup (charset), - (GDestroyNotify) g_free); - -exit: - gtk_widget_destroy (GTK_WIDGET (dialog)); -} - -static void -charset_combo_box_notify_charset_cb (ECharsetComboBox *combo_box) -{ - GtkToggleAction *action; - - action = GTK_TOGGLE_ACTION (combo_box->priv->other_action); - if (!gtk_toggle_action_get_active (action)) - return; - - if (combo_box->priv->block_dialog) - return; - - /* "Other" action was selected by user. */ - charset_combo_box_run_dialog (combo_box); -} - -static void -charset_combo_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CHARSET: - e_charset_combo_box_set_charset ( - E_CHARSET_COMBO_BOX (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -charset_combo_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CHARSET: - g_value_set_string ( - value, e_charset_combo_box_get_charset ( - E_CHARSET_COMBO_BOX (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -charset_combo_box_dispose (GObject *object) -{ - ECharsetComboBoxPrivate *priv; - - priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object); - - if (priv->action_group != NULL) { - g_object_unref (priv->action_group); - priv->action_group = NULL; - } - - if (priv->other_action != NULL) { - g_object_unref (priv->other_action); - priv->other_action = NULL; - } - - g_hash_table_remove_all (priv->charset_index); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_charset_combo_box_parent_class)->dispose (object); -} - -static void -charset_combo_box_finalize (GObject *object) -{ - ECharsetComboBoxPrivate *priv; - - priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object); - - g_hash_table_destroy (priv->charset_index); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_charset_combo_box_parent_class)->finalize (object); -} - -static void -charset_combo_box_changed (GtkComboBox *combo_box) -{ - ECharsetComboBoxPrivate *priv; - - priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box); - - /* Chain up to parent's changed() method. */ - GTK_COMBO_BOX_CLASS (e_charset_combo_box_parent_class)-> - changed (combo_box); - - /* Notify -before- updating previous index. */ - g_object_notify (G_OBJECT (combo_box), "charset"); - priv->previous_index = gtk_combo_box_get_active (combo_box); -} - -static void -e_charset_combo_box_class_init (ECharsetComboBoxClass *class) -{ - GObjectClass *object_class; - GtkComboBoxClass *combo_box_class; - - g_type_class_add_private (class, sizeof (ECharsetComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = charset_combo_box_set_property; - object_class->get_property = charset_combo_box_get_property; - object_class->dispose = charset_combo_box_dispose; - object_class->finalize = charset_combo_box_finalize; - - combo_box_class = GTK_COMBO_BOX_CLASS (class); - combo_box_class->changed = charset_combo_box_changed; - - g_object_class_install_property ( - object_class, - PROP_CHARSET, - g_param_spec_string ( - "charset", - "Charset", - "The selected character set", - "UTF-8", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_charset_combo_box_init (ECharsetComboBox *combo_box) -{ - GtkActionGroup *action_group; - GtkRadioAction *radio_action; - GHashTable *charset_index; - GSList *group, *iter; - - action_group = gtk_action_group_new ("charset-combo-box-internal"); - - charset_index = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); - - combo_box->priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box); - combo_box->priv->action_group = action_group; - combo_box->priv->charset_index = charset_index; - - group = e_charset_add_radio_actions ( - action_group, "charset-", NULL, NULL, NULL); - - /* Populate the character set index. */ - for (iter = group; iter != NULL; iter = iter->next) { - GObject *object = iter->data; - const gchar *charset; - - charset = g_object_get_data (object, "charset"); - g_return_if_fail (charset != NULL); - - g_hash_table_insert ( - charset_index, g_strdup (charset), - g_object_ref (object)); - } - - /* Note the "other" action is not included in the index. */ - - radio_action = gtk_radio_action_new ( - "charset-other", _("Other..."), NULL, NULL, OTHER_VALUE); - - g_object_set_data (G_OBJECT (radio_action), "charset", (gpointer) ""); - - gtk_radio_action_set_group (radio_action, group); - group = gtk_radio_action_get_group (radio_action); - - e_action_combo_box_set_action ( - E_ACTION_COMBO_BOX (combo_box), radio_action); - - e_action_combo_box_add_separator_after ( - E_ACTION_COMBO_BOX (combo_box), g_slist_length (group)); - - g_signal_connect ( - combo_box, "notify::charset", - G_CALLBACK (charset_combo_box_notify_charset_cb), NULL); - - combo_box->priv->other_action = radio_action; -} - -GtkWidget * -e_charset_combo_box_new (void) -{ - return g_object_new (E_TYPE_CHARSET_COMBO_BOX, NULL); -} - -const gchar * -e_charset_combo_box_get_charset (ECharsetComboBox *combo_box) -{ - GtkRadioAction *radio_action; - - g_return_val_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box), NULL); - - radio_action = combo_box->priv->other_action; - radio_action = e_radio_action_get_current_action (radio_action); - - return g_object_get_data (G_OBJECT (radio_action), "charset"); -} - -void -e_charset_combo_box_set_charset (ECharsetComboBox *combo_box, - const gchar *charset) -{ - GHashTable *charset_index; - GtkRadioAction *radio_action; - - g_return_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box)); - - if (charset == NULL || *charset == '\0') - charset = "UTF-8"; - - charset_index = combo_box->priv->charset_index; - radio_action = g_hash_table_lookup (charset_index, charset); - - if (radio_action == NULL) { - radio_action = combo_box->priv->other_action; - g_object_set_data_full ( - G_OBJECT (radio_action), - "charset", g_strdup (charset), - (GDestroyNotify) g_free); - } - - combo_box->priv->block_dialog = TRUE; - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (radio_action), TRUE); - combo_box->priv->block_dialog = FALSE; -} diff --git a/widgets/misc/e-charset-combo-box.h b/widgets/misc/e-charset-combo-box.h deleted file mode 100644 index 471dfa6a54..0000000000 --- a/widgets/misc/e-charset-combo-box.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * e-charset-combo-box.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CHARSET_COMBO_BOX_H -#define E_CHARSET_COMBO_BOX_H - -#include <misc/e-action-combo-box.h> - -/* Standard GObject macros */ -#define E_TYPE_CHARSET_COMBO_BOX \ - (e_charset_combo_box_get_type ()) -#define E_CHARSET_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBox)) -#define E_CHARSET_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass)) -#define E_IS_CHARSET_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CHARSET_COMBO_BOX)) -#define E_IS_CHARSET_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CHARSET_COMBO_BOX)) -#define E_CHARSET_COMBO_BOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass)) - -G_BEGIN_DECLS - -typedef struct _ECharsetComboBox ECharsetComboBox; -typedef struct _ECharsetComboBoxClass ECharsetComboBoxClass; -typedef struct _ECharsetComboBoxPrivate ECharsetComboBoxPrivate; - -struct _ECharsetComboBox { - EActionComboBox parent; - ECharsetComboBoxPrivate *priv; -}; - -struct _ECharsetComboBoxClass { - EActionComboBoxClass parent_class; -}; - -GType e_charset_combo_box_get_type (void); -GtkWidget * e_charset_combo_box_new (void); -const gchar * e_charset_combo_box_get_charset (ECharsetComboBox *combo_box); -void e_charset_combo_box_set_charset (ECharsetComboBox *combo_box, - const gchar *charset); - -G_END_DECLS - -#endif /* E_CHARSET_COMBO_BOX_H */ diff --git a/widgets/misc/e-contact-map-window.c b/widgets/misc/e-contact-map-window.c deleted file mode 100644 index 2e3aec5bcb..0000000000 --- a/widgets/misc/e-contact-map-window.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * e-contact-map-window.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef WITH_CONTACT_MAPS - -#include "e-contact-map.h" -#include "e-contact-map-window.h" -#include "e-contact-marker.h" - -#include <champlain/champlain.h> - -#include <string.h> - -#include <glib/gi18n.h> -#include <glib-object.h> - -#define E_CONTACT_MAP_WINDOW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowPrivate)) - -G_DEFINE_TYPE (EContactMapWindow, e_contact_map_window, GTK_TYPE_WINDOW) - -struct _EContactMapWindowPrivate { - EContactMap *map; - - GtkWidget *zoom_in_btn; - GtkWidget *zoom_out_btn; - - GtkWidget *search_entry; - GtkListStore *completion_model; - - GHashTable *hash_table; /* Hash table contact-name -> marker */ - - GtkWidget *spinner; - gint tasks_cnt; -}; - -enum { - SHOW_CONTACT_EDITOR, - LAST_SIGNAL -}; - -static gint signals[LAST_SIGNAL] = {0}; - -static void -marker_doubleclick_cb (ClutterActor *actor, - gpointer user_data) -{ - EContactMapWindow *window = user_data; - EContactMarker *marker; - const gchar *contact_uid; - - marker = E_CONTACT_MARKER (actor); - contact_uid = e_contact_marker_get_contact_uid (marker); - - g_signal_emit (window, signals[SHOW_CONTACT_EDITOR], 0, contact_uid); -} - -static void -book_contacts_received_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - EContactMapWindow *window = user_data; - EBookClient *client = E_BOOK_CLIENT (source_object); - GSList *contacts = NULL, *p; - GError *error = NULL; - - if (!e_book_client_get_contacts_finish (client, result, &contacts, &error)) - contacts = NULL; - - if (error != NULL) { - g_warning ( - "%s: Failed to get contacts: %s", - G_STRFUNC, error->message); - g_error_free (error); - } - - for (p = contacts; p; p = p->next) - e_contact_map_add_contact ( - window->priv->map, (EContact *) p->data); - - e_client_util_free_object_slist (contacts); - g_object_unref (client); -} - -static void -contact_map_window_zoom_in_cb (GtkButton *button, - gpointer user_data) -{ - EContactMapWindow *window = user_data; - ChamplainView *view; - - view = e_contact_map_get_view (window->priv->map); - - champlain_view_zoom_in (view); -} - -static void -contact_map_window_zoom_out_cb (GtkButton *button, - gpointer user_data) -{ - EContactMapWindow *window = user_data; - ChamplainView *view; - - view = e_contact_map_get_view (window->priv->map); - - champlain_view_zoom_out (view); -} -static void -zoom_level_changed_cb (ChamplainView *view, - GParamSpec *pspec, - gpointer user_data) -{ - EContactMapWindow *window = user_data; - gint zoom_level = champlain_view_get_zoom_level (view); - - gtk_widget_set_sensitive ( - window->priv->zoom_in_btn, - (zoom_level < champlain_view_get_max_zoom_level (view))); - - gtk_widget_set_sensitive ( - window->priv->zoom_out_btn, - (zoom_level > champlain_view_get_min_zoom_level (view))); -} - -/** - * Add contact to hash_table only when EContactMap tells us - * that the contact has really been added to map. - */ -static void -map_contact_added_cb (EContactMap *map, - ClutterActor *marker, - gpointer user_data) -{ - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - const gchar *name; - GtkTreeIter iter; - - name = champlain_label_get_text (CHAMPLAIN_LABEL (marker)); - - g_hash_table_insert ( - priv->hash_table, - g_strdup (name), marker); - - gtk_list_store_append (priv->completion_model, &iter); - gtk_list_store_set ( - priv->completion_model, &iter, - 0, name, -1); - - g_signal_connect ( - marker, "double-clicked", - G_CALLBACK (marker_doubleclick_cb), user_data); - - priv->tasks_cnt--; - if (priv->tasks_cnt == 0) { - gtk_spinner_stop (GTK_SPINNER (priv->spinner)); - gtk_widget_hide (priv->spinner); - } -} - -static void -map_contact_removed_cb (EContactMap *map, - const gchar *name, - gpointer user_data) -{ - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - GtkTreeIter iter; - GtkTreeModel *model = GTK_TREE_MODEL (priv->completion_model); - - g_hash_table_remove (priv->hash_table, name); - - if (gtk_tree_model_get_iter_first (model, &iter)) { - do { - gchar *name_str; - gtk_tree_model_get (model, &iter, 0, &name_str, -1); - if (g_ascii_strcasecmp (name_str, name) == 0) { - g_free (name_str); - gtk_list_store_remove (priv->completion_model, &iter); - break; - } - g_free (name_str); - } while (gtk_tree_model_iter_next (model, &iter)); - } -} - -static void -map_contact_geocoding_started_cb (EContactMap *map, - ClutterActor *marker, - gpointer user_data) -{ - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - - gtk_spinner_start (GTK_SPINNER (priv->spinner)); - gtk_widget_show (priv->spinner); - - priv->tasks_cnt++; -} - -static void -map_contact_geocoding_failed_cb (EContactMap *map, - const gchar *name, - gpointer user_data) -{ - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - - priv->tasks_cnt--; - - if (priv->tasks_cnt == 0) { - gtk_spinner_stop (GTK_SPINNER (priv->spinner)); - gtk_widget_hide (priv->spinner); - } -} - -static void -contact_map_window_find_contact_cb (GtkButton *button, - gpointer user_data) -{ - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - ClutterActor *marker; - - marker = g_hash_table_lookup ( - priv->hash_table, - gtk_entry_get_text (GTK_ENTRY (priv->search_entry))); - - if (marker) - e_contact_map_zoom_on_marker (priv->map, marker); -} - -static gboolean -contact_map_window_entry_key_pressed_cb (GtkWidget *entry, - GdkEventKey *event, - gpointer user_data) -{ - if (event->keyval == GDK_KEY_Return) - contact_map_window_find_contact_cb (NULL, user_data); - - return FALSE; -} - -static gboolean -entry_completion_match_selected_cb (GtkEntryCompletion *widget, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - GValue name_val = {0}; - EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv; - const gchar *name; - - gtk_tree_model_get_value (model, iter, 0, &name_val); - g_return_val_if_fail (G_VALUE_HOLDS_STRING (&name_val), FALSE); - - name = g_value_get_string (&name_val); - gtk_entry_set_text (GTK_ENTRY (priv->search_entry), name); - - contact_map_window_find_contact_cb (NULL, user_data); - - return TRUE; -} - -static void -contact_map_window_finalize (GObject *object) -{ - EContactMapWindowPrivate *priv; - - priv = E_CONTACT_MAP_WINDOW (object)->priv; - - if (priv->hash_table) { - g_hash_table_destroy (priv->hash_table); - priv->hash_table = NULL; - } - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_contact_map_window_parent_class)->finalize (object); -} - -static void -contact_map_window_dispose (GObject *object) -{ - EContactMapWindowPrivate *priv; - - priv = E_CONTACT_MAP_WINDOW (object)->priv; - - if (priv->map) { - gtk_widget_destroy (GTK_WIDGET (priv->map)); - priv->map = NULL; - } - - if (priv->completion_model) { - g_object_unref (priv->completion_model); - priv->completion_model = NULL; - } - - G_OBJECT_CLASS (e_contact_map_window_parent_class)->dispose (object); -} - -static void -e_contact_map_window_class_init (EContactMapWindowClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EContactMapWindowPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = contact_map_window_finalize; - object_class->dispose = contact_map_window_dispose; - - signals[SHOW_CONTACT_EDITOR] = g_signal_new ( - "show-contact-editor", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMapWindowClass, show_contact_editor), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} - -static void -e_contact_map_window_init (EContactMapWindow *window) -{ - EContactMapWindowPrivate *priv; - GtkWidget *map; - GtkWidget *button, *entry; - GtkWidget *hbox, *vbox, *viewport; - GtkEntryCompletion *entry_completion; - GtkListStore *completion_model; - ChamplainView *view; - GHashTable *hash_table; - - priv = E_CONTACT_MAP_WINDOW_GET_PRIVATE (window); - window->priv = priv; - - priv->tasks_cnt = 0; - - hash_table = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) NULL); - priv->hash_table = hash_table; - - gtk_window_set_title (GTK_WINDOW (window), _("Contacts Map")); - gtk_container_set_border_width (GTK_CONTAINER (window), 12); - gtk_widget_set_size_request (GTK_WIDGET (window), 800, 600); - - /* The map view itself */ - map = e_contact_map_new (); - view = e_contact_map_get_view (E_CONTACT_MAP (map)); - champlain_view_set_zoom_level (view, 2); - priv->map = E_CONTACT_MAP (map); - g_signal_connect ( - view, "notify::zoom-level", - G_CALLBACK (zoom_level_changed_cb), window); - g_signal_connect ( - map, "contact-added", - G_CALLBACK (map_contact_added_cb), window); - g_signal_connect ( - map, "contact-removed", - G_CALLBACK (map_contact_removed_cb), window); - g_signal_connect ( - map, "geocoding-started", - G_CALLBACK (map_contact_geocoding_started_cb), window); - g_signal_connect ( - map, "geocoding-failed", - G_CALLBACK (map_contact_geocoding_failed_cb), window); - - /* HBox container */ - hbox = gtk_hbox_new (FALSE, 7); - - /* Spinner */ - button = gtk_spinner_new (); - gtk_container_add (GTK_CONTAINER (hbox), button); - gtk_widget_hide (button); - priv->spinner = button; - - /* Zoom-in button */ - button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_IN); - g_signal_connect ( - button, "clicked", - G_CALLBACK (contact_map_window_zoom_in_cb), window); - priv->zoom_in_btn = button; - gtk_container_add (GTK_CONTAINER (hbox), button); - - /* Zoom-out button */ - button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_OUT); - g_signal_connect ( - button, "clicked", - G_CALLBACK (contact_map_window_zoom_out_cb), window); - priv->zoom_out_btn = button; - gtk_container_add (GTK_CONTAINER (hbox), button); - - /* Completion model */ - completion_model = gtk_list_store_new (1, G_TYPE_STRING); - priv->completion_model = completion_model; - - /* Entry completion */ - entry_completion = gtk_entry_completion_new (); - gtk_entry_completion_set_model ( - entry_completion, GTK_TREE_MODEL (completion_model)); - gtk_entry_completion_set_text_column (entry_completion, 0); - g_signal_connect ( - entry_completion, "match-selected", - G_CALLBACK (entry_completion_match_selected_cb), window); - - /* Search entry */ - entry = gtk_entry_new (); - gtk_entry_set_completion (GTK_ENTRY (entry), entry_completion); - g_signal_connect ( - entry, "key-press-event", - G_CALLBACK (contact_map_window_entry_key_pressed_cb), window); - window->priv->search_entry = entry; - gtk_container_add (GTK_CONTAINER (hbox), entry); - - /* Search button */ - button = gtk_button_new_from_stock (GTK_STOCK_FIND); - g_signal_connect ( - button, "clicked", - G_CALLBACK (contact_map_window_find_contact_cb), window); - gtk_container_add (GTK_CONTAINER (hbox), button); - - viewport = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (viewport), map); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (vbox), viewport); - gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - gtk_widget_show_all (vbox); - gtk_widget_hide (priv->spinner); -} - -EContactMapWindow * -e_contact_map_window_new (void) -{ - return g_object_new ( - E_TYPE_CONTACT_MAP_WINDOW, NULL); -} - -/** - * Gets all contacts from @book and puts them - * on the map view - */ -void -e_contact_map_window_load_addressbook (EContactMapWindow *map, - EBookClient *book_client) -{ - EBookQuery *book_query; - gchar *query_string; - - g_return_if_fail (E_IS_CONTACT_MAP_WINDOW (map)); - g_return_if_fail (E_IS_BOOK_CLIENT (book_client)); - - /* Reference book, so that it does not get deleted before the callback is - * involved. The book is unrefed in the callback */ - g_object_ref (book_client); - - book_query = e_book_query_field_exists (E_CONTACT_ADDRESS); - query_string = e_book_query_to_string (book_query); - e_book_query_unref (book_query); - - e_book_client_get_contacts ( - book_client, query_string, NULL, - book_contacts_received_cb, map); - - g_free (query_string); -} - -EContactMap * -e_contact_map_window_get_map (EContactMapWindow *window) -{ - g_return_val_if_fail (E_IS_CONTACT_MAP_WINDOW (window), NULL); - - return window->priv->map; -} - -#endif /* WITH_CONTACT_MAPS */ diff --git a/widgets/misc/e-contact-map-window.h b/widgets/misc/e-contact-map-window.h deleted file mode 100644 index 821fe243d2..0000000000 --- a/widgets/misc/e-contact-map-window.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * e-contact-map-window.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - * - */ - -#ifndef E_CONTACT_MAP_WINDOW_H -#define E_CONTACT_MAP_WINDOW_H - -#include <gtk/gtk.h> - -#include <libebook/libebook.h> - -#include <e-contact-map.h> - -/* Standard GObject macros */ -#define E_TYPE_CONTACT_MAP_WINDOW \ - (e_contact_map_window_get_type ()) -#define E_CONTACT_MAP_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindow)) -#define E_CONTACT_MAP_WINDOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass)) -#define E_IS_CONTACT_MAP_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CONTACT_MAP_WINDOW)) -#define E_IS_CONTACT_MAP_WINDOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CONTACT_MAP_WINDOW)) -#define E_CONTACT_MAP_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass)) - -G_BEGIN_DECLS - -typedef struct _EContactMapWindow EContactMapWindow; -typedef struct _EContactMapWindowClass EContactMapWindowClass; -typedef struct _EContactMapWindowPrivate EContactMapWindowPrivate; - -struct _EContactMapWindow { - GtkWindow parent; - EContactMapWindowPrivate *priv; -}; - -struct _EContactMapWindowClass { - GtkWindowClass parent_class; - - void (*show_contact_editor) (EContactMapWindow *window, - const gchar *contact_uid); -}; - -GType e_contact_map_window_get_type (void) G_GNUC_CONST; -EContactMapWindow * e_contact_map_window_new (void); - -void e_contact_map_window_load_addressbook (EContactMapWindow *window, - EBookClient *book); - -EContactMap * e_contact_map_window_get_map (EContactMapWindow *window); - -G_END_DECLS - -#endif diff --git a/widgets/misc/e-contact-map.c b/widgets/misc/e-contact-map.c deleted file mode 100644 index 3ad17b441f..0000000000 --- a/widgets/misc/e-contact-map.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * e-contact-map.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef WITH_CONTACT_MAPS - -#include "e-contact-map.h" -#include "e-contact-marker.h" - -#include <e-util/e-marshal.h> - -#include <champlain/champlain.h> -#include <champlain-gtk/champlain-gtk.h> -#include <geoclue/geoclue-address.h> -#include <geoclue/geoclue-position.h> -#include <geocode-glib.h> - -#include <clutter/clutter.h> - -#include <string.h> -#include <glib/gi18n.h> -#include <math.h> - -#define E_CONTACT_MAP_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CONTACT_MAP, EContactMapPrivate)) - -typedef struct _AsyncContext AsyncContext; - -struct _EContactMapPrivate { - GHashTable *markers; /* Hash table contact-name -> marker */ - - ChamplainMarkerLayer *marker_layer; -}; - -struct _AsyncContext { - EContactMap *map; - EContactMarker *marker; -}; - -enum { - CONTACT_ADDED, - CONTACT_REMOVED, - GEOCODING_STARTED, - GEOCODING_FAILED, - LAST_SIGNAL -}; - -static gint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE (EContactMap, e_contact_map, GTK_CHAMPLAIN_TYPE_EMBED) - -static void -async_context_free (AsyncContext *async_context) -{ - if (async_context->map != NULL) - g_object_unref (async_context->map); - - g_slice_free (AsyncContext, async_context); -} - -static void -contact_map_address_resolved_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GHashTable *resolved = NULL; - gpointer marker_ptr; - const gchar *name; - gdouble latitude, longitude; - AsyncContext *async_context = user_data; - ChamplainMarkerLayer *marker_layer; - ChamplainMarker *marker; - GError *error = NULL; - - g_return_if_fail (async_context != NULL); - g_return_if_fail (E_IS_CONTACT_MAP (async_context->map)); - g_return_if_fail (E_IS_CONTACT_MARKER (async_context->marker)); - - marker = CHAMPLAIN_MARKER (async_context->marker); - marker_layer = async_context->map->priv->marker_layer; - - /* If the marker_layer does not exist anymore, the map has - * probably been destroyed before this callback was launched. - * It's not a failure, just silently clean up what was left - * behind and pretend nothing happened. */ - - if (!CHAMPLAIN_IS_MARKER_LAYER (marker_layer)) - goto exit; - - resolved = geocode_object_resolve_finish ( - GEOCODE_OBJECT (source), result, &error); - - if (resolved == NULL || - !geocode_object_get_coords (resolved, &longitude, &latitude)) { - const gchar *name; - if (error) - g_error_free (error); - name = champlain_label_get_text (CHAMPLAIN_LABEL (marker)); - g_signal_emit ( - async_context->map, - signals[GEOCODING_FAILED], 0, name); - goto exit; - } - - /* Move the marker to resolved position */ - champlain_location_set_location ( - CHAMPLAIN_LOCATION (marker), latitude, longitude); - champlain_marker_layer_add_marker (marker_layer, marker); - champlain_marker_set_selected (marker, FALSE); - - /* Store the marker in the hash table. Use it's label as key */ - name = champlain_label_get_text (CHAMPLAIN_LABEL (marker)); - marker_ptr = g_hash_table_lookup ( - async_context->map->priv->markers, name); - if (marker_ptr != NULL) { - g_hash_table_remove (async_context->map->priv->markers, name); - champlain_marker_layer_remove_marker (marker_layer, marker_ptr); - } - g_hash_table_insert ( - async_context->map->priv->markers, - g_strdup (name), marker); - - g_signal_emit ( - async_context->map, - signals[CONTACT_ADDED], 0, marker); - -exit: - async_context_free (async_context); - - if (resolved != NULL) - g_hash_table_unref (resolved); -} - -static void -resolve_marker_position (EContactMap *map, - EContactMarker *marker, - EContactAddress *address) -{ - GeocodeObject *geocoder; - AsyncContext *async_context; - const gchar *key; - - g_return_if_fail (E_IS_CONTACT_MAP (map)); - g_return_if_fail (address != NULL); - - geocoder = geocode_object_new (); - - key = GEOCODE_OBJECT_FIELD_POSTAL; - geocode_object_add (geocoder, key, address->code); - - key = GEOCODE_OBJECT_FIELD_COUNTRY; - geocode_object_add (geocoder, key, address->country); - - key = GEOCODE_OBJECT_FIELD_STATE; - geocode_object_add (geocoder, key, address->region); - - key = GEOCODE_OBJECT_FIELD_CITY; - geocode_object_add (geocoder, key, address->locality); - - key = GEOCODE_OBJECT_FIELD_STREET; - geocode_object_add (geocoder, key, address->street); - - async_context = g_slice_new0 (AsyncContext); - async_context->map = g_object_ref (map); - async_context->marker = marker; - - geocode_object_resolve_async ( - geocoder, NULL, - contact_map_address_resolved_cb, - async_context); - - g_object_unref (geocoder); - - g_signal_emit (map, signals[GEOCODING_STARTED], 0, marker); -} - -static void -contact_map_finalize (GObject *object) -{ - EContactMapPrivate *priv; - - priv = E_CONTACT_MAP (object)->priv; - - if (priv->markers) { - g_hash_table_destroy (priv->markers); - priv->markers = NULL; - } - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_contact_map_parent_class)->finalize (object); -} - -static void -e_contact_map_class_init (EContactMapClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EContactMapPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = contact_map_finalize; - - signals[CONTACT_ADDED] = g_signal_new ( - "contact-added", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMapClass, contact_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONTACT_REMOVED] = g_signal_new ( - "contact-removed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMapClass, contact_removed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[GEOCODING_STARTED] = g_signal_new ( - "geocoding-started", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMapClass, geocoding_started), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[GEOCODING_FAILED] = g_signal_new ( - "geocoding-failed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMapClass, geocoding_failed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} - -static void -e_contact_map_init (EContactMap *map) -{ - GHashTable *hash_table; - ChamplainMarkerLayer *layer; - ChamplainView *view; - - map->priv = E_CONTACT_MAP_GET_PRIVATE (map); - - hash_table = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, NULL); - - map->priv->markers = hash_table; - - view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map)); - /* This feature is somehow broken sometimes, so disable it for now */ - champlain_view_set_zoom_on_double_click (view, FALSE); - layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_SINGLE); - champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer)); - map->priv->marker_layer = layer; -} - -GtkWidget * -e_contact_map_new (void) -{ - return g_object_new ( - E_TYPE_CONTACT_MAP,NULL); -} - -void -e_contact_map_add_contact (EContactMap *map, - EContact *contact) -{ - EContactAddress *address; - EContactPhoto *photo; - const gchar *contact_uid; - gchar *name; - - g_return_if_fail (map && E_IS_CONTACT_MAP (map)); - g_return_if_fail (contact && E_IS_CONTACT (contact)); - - photo = e_contact_get (contact, E_CONTACT_PHOTO); - contact_uid = e_contact_get_const (contact, E_CONTACT_UID); - - address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME); - if (address) { - name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Home"), ")", NULL); - e_contact_map_add_marker (map, name, contact_uid, address, photo); - g_free (name); - e_contact_address_free (address); - } - - address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK); - if (address) { - name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Work"), ")", NULL); - e_contact_map_add_marker (map, name, contact_uid, address, photo); - g_free (name); - e_contact_address_free (address); - } - - if (photo) - e_contact_photo_free (photo); -} - -void -e_contact_map_add_marker (EContactMap *map, - const gchar *name, - const gchar *contact_uid, - EContactAddress *address, - EContactPhoto *photo) -{ - EContactMarker *marker; - - g_return_if_fail (map && E_IS_CONTACT_MAP (map)); - g_return_if_fail (name && *name); - g_return_if_fail (contact_uid && *contact_uid); - g_return_if_fail (address); - - marker = E_CONTACT_MARKER (e_contact_marker_new (name, contact_uid, photo)); - - resolve_marker_position (map, marker, address); -} - -/** - * The \name parameter must match the label of the - * marker (for example "John Smith (work)") - */ -void -e_contact_map_remove_contact (EContactMap *map, - const gchar *name) -{ - ChamplainMarker *marker; - - g_return_if_fail (map && E_IS_CONTACT_MAP (map)); - g_return_if_fail (name && *name); - - marker = g_hash_table_lookup (map->priv->markers, name); - - champlain_marker_layer_remove_marker (map->priv->marker_layer, marker); - - g_hash_table_remove (map->priv->markers, name); - - g_signal_emit (map, signals[CONTACT_REMOVED], 0, name); -} - -void -e_contact_map_remove_marker (EContactMap *map, - ClutterActor *marker) -{ - const gchar *name; - - g_return_if_fail (map && E_IS_CONTACT_MAP (map)); - g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker)); - - name = champlain_label_get_text (CHAMPLAIN_LABEL (marker)); - - e_contact_map_remove_contact (map, name); -} - -void -e_contact_map_zoom_on_marker (EContactMap *map, - ClutterActor *marker) -{ - ChamplainView *view; - gdouble lat, lng; - - g_return_if_fail (map && E_IS_CONTACT_MAP (map)); - g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker)); - - lat = champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker)); - lng = champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker)); - - view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map)); - - champlain_view_center_on (view, lat, lng); - champlain_view_set_zoom_level (view, 15); -} - -ChamplainView * -e_contact_map_get_view (EContactMap *map) -{ - g_return_val_if_fail (E_IS_CONTACT_MAP (map), NULL); - - return gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map)); -} - -#endif /* WITH_CONTACT_MAPS */ diff --git a/widgets/misc/e-contact-map.h b/widgets/misc/e-contact-map.h deleted file mode 100644 index d9503e2c9b..0000000000 --- a/widgets/misc/e-contact-map.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * e-contact-map.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - * - */ - -#ifndef E_CONTACT_MAP_H -#define E_CONTACT_MAP_H - -#ifdef WITH_CONTACT_MAPS - -#include <gtk/gtk.h> - -#include <champlain/champlain.h> -#include <champlain-gtk/champlain-gtk.h> - -#include <libebook/libebook.h> - -/* Standard GObject macros */ -#define E_TYPE_CONTACT_MAP \ - (e_contact_map_get_type ()) -#define E_CONTACT_MAP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CONTACT_MAP, EContactMap)) -#define E_CONTACT_MAP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CONTACT_MAP, EContactMapClass)) -#define E_IS_CONTACT_MAP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CONTACT_MAP)) -#define E_IS_CONTACT_MAP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CONTACT_MAP)) -#define E_CONTACT_MAP_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CONTACT_MAP, EContactMapClass)) - -G_BEGIN_DECLS - -typedef struct _EContactMap EContactMap; -typedef struct _EContactMapClass EContactMapClass; -typedef struct _EContactMapPrivate EContactMapPrivate; - -struct _EContactMap { - GtkChamplainEmbed parent; - EContactMapPrivate *priv; -}; - -struct _EContactMapClass { - GtkWindowClass parent_class; - - void (*contact_added) (EContactMap *map, - ClutterActor *marker); - - void (*contact_removed) (EContactMap *map, - const gchar *name); - - void (*geocoding_started) (EContactMap *map, - ClutterActor *marker); - - void (*geocoding_failed) (EContactMap *map, - const gchar *name); -}; - -GType e_contact_map_get_type (void) G_GNUC_CONST; -GtkWidget * e_contact_map_new (void); - -void e_contact_map_add_contact (EContactMap *map, - EContact *contact); - -void e_contact_map_add_marker (EContactMap *map, - const gchar *name, - const gchar *contact_uid, - EContactAddress *address, - EContactPhoto *photo); - -void e_contact_map_remove_contact (EContactMap *map, - const gchar *name); - -void e_contact_map_remove_marker (EContactMap *map, - ClutterActor *marker); - -void e_contact_map_zoom_on_marker (EContactMap *map, - ClutterActor *marker); - -ChamplainView * e_contact_map_get_view (EContactMap *map); - -G_END_DECLS - -#endif /* WITH_CONTACT_MAPS */ - -#endif diff --git a/widgets/misc/e-contact-marker.c b/widgets/misc/e-contact-marker.c deleted file mode 100644 index 9ac9417c9f..0000000000 --- a/widgets/misc/e-contact-marker.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * e-contact-marker.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com> - * Copyright (C) 2011 Jiri Techet <techet@gmail.com> - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef WITH_CONTACT_MAPS - -#include "e-contact-marker.h" - -#include <champlain/champlain.h> -#include <gtk/gtk.h> -#include <clutter/clutter.h> -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <cairo.h> -#include <math.h> -#include <string.h> - -#define E_CONTACT_MARKER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerPrivate)) - -G_DEFINE_TYPE (EContactMarker, e_contact_marker, CHAMPLAIN_TYPE_LABEL); - -struct _EContactMarkerPrivate -{ - gchar *contact_uid; - - ClutterActor *image; - ClutterActor *text_actor; - - ClutterActor *shadow; - ClutterActor *background; - - guint total_width; - guint total_height; - - ClutterGroup *content_group; - - guint redraw_id; -}; - -enum { - DOUBLE_CLICKED, - LAST_SIGNAL -}; - -static gint signals[LAST_SIGNAL] = {0}; - -#define DEFAULT_FONT_NAME "Serif 9" - -static ClutterColor DEFAULT_COLOR = { 0x33, 0x33, 0x33, 0xff }; - -#define RADIUS 10 -#define PADDING (RADIUS / 2) - -static gboolean -contact_marker_clicked_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - gint click_count = clutter_event_get_click_count (event); - - if (click_count == 2) - g_signal_emit (E_CONTACT_MARKER (actor), signals[DOUBLE_CLICKED], 0); - - return TRUE; -} - -static ClutterActor * -texture_new_from_pixbuf (GdkPixbuf *pixbuf, - GError **error) -{ - ClutterActor *texture = NULL; - const guchar *data; - gboolean has_alpha, success; - gint width, height, rowstride; - ClutterTextureFlags flags = 0; - - data = gdk_pixbuf_get_pixels (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - texture = clutter_texture_new (); - success = clutter_texture_set_from_rgb_data ( - CLUTTER_TEXTURE (texture), - data, has_alpha, width, height, rowstride, - (has_alpha ? 4: 3), flags, NULL); - - if (!success) { - clutter_actor_destroy (CLUTTER_ACTOR (texture)); - texture = NULL; - } - - return texture; -} - -static ClutterActor * -contact_photo_to_texture (EContactPhoto *photo) -{ - GdkPixbuf *pixbuf; - - if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { - GError *error = NULL; - - GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); - gdk_pixbuf_loader_write ( - loader, photo->data.inlined.data, - photo->data.inlined.length, NULL); - gdk_pixbuf_loader_close (loader, NULL); - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf) - g_object_ref (pixbuf); - g_object_unref (loader); - - if (error) { - g_error_free (error); - return NULL; - } - } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI) { - GError *error = NULL; - - pixbuf = gdk_pixbuf_new_from_file (photo->data.uri, &error); - - if (error) { - g_error_free (error); - return NULL; - } - } else - return NULL; - - if (pixbuf) { - ClutterActor *texture; - GError *error = NULL; - - texture = texture_new_from_pixbuf (pixbuf, &error); - if (error) { - g_error_free (error); - g_object_unref (pixbuf); - return NULL; - } - - g_object_unref (pixbuf); - return texture; - } - - return NULL; -} - -static void -draw_box (cairo_t *cr, - gint width, - gint height, - gint point) -{ - cairo_move_to (cr, RADIUS, 0); - cairo_line_to (cr, width - RADIUS, 0); - cairo_arc (cr, width - RADIUS, RADIUS, RADIUS - 1, 3 * M_PI / 2.0, 0); - cairo_line_to (cr, width, height - RADIUS); - cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS - 1, 0, M_PI / 2.0); - cairo_line_to (cr, point, height); - cairo_line_to (cr, 0, height + point); - cairo_arc (cr, RADIUS, RADIUS, RADIUS - 1, M_PI, 3 * M_PI / 2.0); - cairo_close_path (cr); -} - -static void -draw_shadow (EContactMarker *marker, - gint width, - gint height, - gint point) -{ - EContactMarkerPrivate *priv = marker->priv; - ClutterActor *shadow = NULL; - cairo_t *cr; - gdouble slope; - gdouble scaling; - gint x; - cairo_matrix_t matrix; - - slope = -0.3; - scaling = 0.65; - x = -40 * slope; - - shadow = clutter_cairo_texture_new (width + x, (height + point)); - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (shadow)); - - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - - cairo_matrix_init (&matrix, 1, 0, slope, scaling, x, 0); - cairo_set_matrix (cr, &matrix); - - draw_box (cr, width, height, point); - - cairo_set_source_rgba (cr, 0, 0, 0, 0.15); - cairo_fill (cr); - - cairo_destroy (cr); - - clutter_actor_set_position (shadow, 0, height / 2.0); - - clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), shadow); - - if (priv->shadow != NULL) { - clutter_container_remove_actor ( - CLUTTER_CONTAINER (priv->content_group), - priv->shadow); - } - - priv->shadow = shadow; -} - -static void -draw_background (EContactMarker *marker, - gint width, - gint height, - gint point) -{ - EContactMarkerPrivate *priv = marker->priv; - ClutterActor *bg = NULL; - const ClutterColor *color; - ClutterColor darker_color; - cairo_t *cr; - - bg = clutter_cairo_texture_new (width, height + point); - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (bg)); - - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - - /* If selected, add the selection color to the marker's color */ - if (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker))) - color = champlain_marker_get_selection_color (); - else - color = &DEFAULT_COLOR; - - draw_box (cr, width, height, point); - - clutter_color_darken (color, &darker_color); - - cairo_set_source_rgba ( - cr, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - cairo_fill_preserve (cr); - - cairo_set_line_width (cr, 1.0); - cairo_set_source_rgba ( - cr, - darker_color.red / 255.0, - darker_color.green / 255.0, - darker_color.blue / 255.0, - darker_color.alpha / 255.0); - cairo_stroke (cr); - cairo_destroy (cr); - - clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), bg); - - if (priv->background != NULL) { - clutter_container_remove_actor ( - CLUTTER_CONTAINER (priv->content_group), - priv->background); - } - - priv->background = bg; -} - -static void -draw_marker (EContactMarker *marker) -{ - EContactMarkerPrivate *priv = marker->priv; - ChamplainLabel *label = CHAMPLAIN_LABEL (marker); - guint height = 0, point = 0; - guint total_width = 0, total_height = 0; - ClutterText *text; - - if (priv->image) { - clutter_actor_set_position (priv->image, 2 *PADDING, 2 *PADDING); - if (clutter_actor_get_parent (priv->image) == NULL) - clutter_container_add_actor ( - CLUTTER_CONTAINER (priv->content_group), - priv->image); - } - - if (priv->text_actor == NULL) { - priv->text_actor = clutter_text_new_with_text ( - "Serif 8", - champlain_label_get_text (label)); - champlain_label_set_font_name (label, "Serif 8"); - } - - text = CLUTTER_TEXT (priv->text_actor); - clutter_text_set_text ( - text, - champlain_label_get_text (label)); - clutter_text_set_font_name ( - text, - champlain_label_get_font_name (label)); - clutter_text_set_line_alignment (text, PANGO_ALIGN_CENTER); - clutter_text_set_line_wrap (text, TRUE); - clutter_text_set_line_wrap_mode (text, PANGO_WRAP_WORD); - clutter_text_set_ellipsize ( - text, - champlain_label_get_ellipsize (label)); - clutter_text_set_attributes ( - text, - champlain_label_get_attributes (label)); - clutter_text_set_use_markup ( - text, - champlain_label_get_use_markup (label)); - - if (priv->image) { - clutter_actor_set_width ( - priv->text_actor, - clutter_actor_get_width (priv->image)); - total_height = clutter_actor_get_height (priv->image) + 2 *PADDING + - clutter_actor_get_height (priv->text_actor) + 2 *PADDING; - total_width = clutter_actor_get_width (priv->image) + 4 *PADDING; - clutter_actor_set_position ( - priv->text_actor, PADDING, - clutter_actor_get_height (priv->image) + 2 *PADDING + 3); - } else { - total_height = clutter_actor_get_height (priv->text_actor) + 2 *PADDING; - total_width = clutter_actor_get_width (priv->text_actor) + 4 *PADDING; - clutter_actor_set_position (priv->text_actor, 2 * PADDING, PADDING); - } - - height += 2 * PADDING; - if (height > total_height) - total_height = height; - - clutter_text_set_color ( - CLUTTER_TEXT (priv->text_actor), - (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)) ? - champlain_marker_get_selection_text_color () : - champlain_label_get_text_color (CHAMPLAIN_LABEL (marker)))); - if (clutter_actor_get_parent (priv->text_actor) == NULL) - clutter_container_add_actor ( - CLUTTER_CONTAINER (priv->content_group), - priv->text_actor); - - if (priv->text_actor == NULL && priv->image == NULL) { - total_width = 6 * PADDING; - total_height = 6 * PADDING; - } - - point = (total_height + 2 * PADDING) / 4.0; - priv->total_width = total_width; - priv->total_height = total_height; - - draw_shadow (marker, total_width, total_height, point); - draw_background (marker, total_width, total_height, point); - - if (priv->text_actor != NULL && priv->background != NULL) - clutter_actor_raise (priv->text_actor, priv->background); - if (priv->image != NULL && priv->background != NULL) - clutter_actor_raise (priv->image, priv->background); - - clutter_actor_set_anchor_point (CLUTTER_ACTOR (marker), 0, total_height + point); -} - -static gboolean -redraw_on_idle (gpointer gobject) -{ - EContactMarker *marker = E_CONTACT_MARKER (gobject); - - draw_marker (marker); - marker->priv->redraw_id = 0; - return FALSE; -} - -static void -queue_redraw (EContactMarker *marker) -{ - EContactMarkerPrivate *priv = marker->priv; - - if (!priv->redraw_id) { - priv->redraw_id = g_idle_add_full ( - G_PRIORITY_DEFAULT, - (GSourceFunc) redraw_on_idle, - g_object_ref (marker), - (GDestroyNotify) g_object_unref); - } -} - -static void -allocate (ClutterActor *self, - const ClutterActorBox *box, - ClutterAllocationFlags flags) -{ - ClutterActorBox child_box; - EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv; - - CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->allocate (self, box, flags); - - child_box.x1 = 0; - child_box.x2 = box->x2 - box->x1; - child_box.y1 = 0; - child_box.y2 = box->y2 - box->y1; - clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags); -} - -static void -paint (ClutterActor *self) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv; - - clutter_actor_paint (CLUTTER_ACTOR (priv->content_group)); -} - -static void -map (ClutterActor *self) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv; - - CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->map (self); - - clutter_actor_map (CLUTTER_ACTOR (priv->content_group)); -} - -static void -unmap (ClutterActor *self) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv; - - CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->unmap (self); - - clutter_actor_unmap (CLUTTER_ACTOR (priv->content_group)); -} - -static void -pick (ClutterActor *self, - const ClutterColor *color) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv; - gfloat width, height; - - if (!clutter_actor_should_pick_paint (self)) - return; - - width = priv->total_width; - height = priv->total_height; - - cogl_path_new (); - - cogl_set_source_color4ub ( - color->red, - color->green, - color->blue, - color->alpha); - - cogl_path_move_to (RADIUS, 0); - cogl_path_line_to (width - RADIUS, 0); - cogl_path_arc (width - RADIUS, RADIUS, RADIUS, RADIUS, -90, 0); - cogl_path_line_to (width, height - RADIUS); - cogl_path_arc (width - RADIUS, height - RADIUS, RADIUS, RADIUS, 0, 90); - cogl_path_line_to (RADIUS, height); - cogl_path_arc (RADIUS, height - RADIUS, RADIUS, RADIUS, 90, 180); - cogl_path_line_to (0, RADIUS); - cogl_path_arc (RADIUS, RADIUS, RADIUS, RADIUS, 180, 270); - cogl_path_close (); - cogl_path_fill (); -} - -static void -notify_selected (GObject *gobject, - G_GNUC_UNUSED GParamSpec *pspec, - G_GNUC_UNUSED gpointer user_data) -{ - queue_redraw (E_CONTACT_MARKER (gobject)); -} - -static void -e_contact_marker_finalize (GObject *object) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv; - - if (priv->contact_uid) { - g_free (priv->contact_uid); - priv->contact_uid = NULL; - } - - if (priv->redraw_id) { - g_source_remove (priv->redraw_id); - priv->redraw_id = 0; - } - - G_OBJECT_CLASS (e_contact_marker_parent_class)->finalize (object); -} - -static void -e_contact_marker_dispose (GObject *object) -{ - EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv; - - priv->background = NULL; - priv->shadow = NULL; - priv->text_actor = NULL; - - if (priv->content_group) { - clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group)); - priv->content_group = NULL; - } - - G_OBJECT_CLASS (e_contact_marker_parent_class)->dispose (object); -} - -static void -e_contact_marker_class_init (EContactMarkerClass *class) -{ - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - g_type_class_add_private (class, sizeof (EContactMarkerPrivate)); - - object_class->dispose = e_contact_marker_dispose; - object_class->finalize = e_contact_marker_finalize; - - actor_class->paint = paint; - actor_class->allocate = allocate; - actor_class->map = map; - actor_class->unmap = unmap; - actor_class->pick = pick; - - signals[DOUBLE_CLICKED] = g_signal_new ( - "double-clicked", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EContactMarkerClass, double_clicked), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_contact_marker_init (EContactMarker *marker) -{ - EContactMarkerPrivate *priv; - - priv = E_CONTACT_MARKER_GET_PRIVATE (marker); - - marker->priv = priv; - priv->contact_uid = NULL; - priv->image = NULL; - priv->background = NULL; - priv->shadow = NULL; - priv->text_actor = NULL; - priv->content_group = CLUTTER_GROUP (clutter_group_new ()); - priv->redraw_id = 0; - - clutter_actor_set_parent ( - CLUTTER_ACTOR (priv->content_group), CLUTTER_ACTOR (marker)); - clutter_actor_queue_relayout (CLUTTER_ACTOR (marker)); - - priv->total_width = 0; - priv->total_height = 0; - - g_signal_connect ( - marker, "notify::selected", - G_CALLBACK (notify_selected), NULL); - g_signal_connect ( - marker, "button-release-event", - G_CALLBACK (contact_marker_clicked_cb), NULL); -} - -ClutterActor * -e_contact_marker_new (const gchar *name, - const gchar *contact_uid, - EContactPhoto *photo) -{ - ClutterActor *marker = CLUTTER_ACTOR (g_object_new (E_TYPE_CONTACT_MARKER, NULL)); - EContactMarkerPrivate *priv = E_CONTACT_MARKER (marker)->priv; - - g_return_val_if_fail (name && *name, NULL); - g_return_val_if_fail (contact_uid && *contact_uid, NULL); - - champlain_label_set_text (CHAMPLAIN_LABEL (marker), name); - priv->contact_uid = g_strdup (contact_uid); - if (photo) - priv->image = contact_photo_to_texture (photo); - - queue_redraw (E_CONTACT_MARKER (marker)); - - return marker; -} - -const gchar * -e_contact_marker_get_contact_uid (EContactMarker *marker) -{ - g_return_val_if_fail (marker && E_IS_CONTACT_MARKER (marker), NULL); - - return marker->priv->contact_uid; -} - -#endif /* WITH_CONTACT_MAPS */ diff --git a/widgets/misc/e-contact-marker.h b/widgets/misc/e-contact-marker.h deleted file mode 100644 index 791a9c46b5..0000000000 --- a/widgets/misc/e-contact-marker.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * e-contact-marker.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com> - * Copyright (C) 2011 Jiri Techet <techet@gmail.com> - * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com> - * - */ - -#ifndef E_CONTACT_MARKER_H -#define E_CONTACT_MARKER_H - -#ifdef WITH_CONTACT_MAPS - -#include <libebook/libebook.h> - -#include <champlain/champlain.h> - -#include <glib-object.h> -#include <clutter/clutter.h> - -G_BEGIN_DECLS - -#define E_TYPE_CONTACT_MARKER e_contact_marker_get_type () - -#define E_CONTACT_MARKER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_MARKER, EContactMarker)) - -#define E_CONTACT_MARKER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_MARKER, EContactMarkerClass)) - -#define E_IS_CONTACT_MARKER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_MARKER)) - -#define E_IS_CONTACT_MARKER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT_MARKER)) - -#define E_CONTACT_MARKER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerClass)) - -typedef struct _EContactMarkerPrivate EContactMarkerPrivate; - -typedef struct _EContactMarker EContactMarker; -typedef struct _EContactMarkerClass EContactMarkerClass; - -struct _EContactMarker -{ - ChamplainLabel parent; - EContactMarkerPrivate *priv; -}; - -struct _EContactMarkerClass -{ - ChamplainLabelClass parent_class; - - void (*double_clicked) (ClutterActor *actor); -}; - -GType e_contact_marker_get_type (void); - -ClutterActor * e_contact_marker_new (const gchar *name, - const gchar *contact_uid, - EContactPhoto *photo); - -const gchar * e_contact_marker_get_contact_uid (EContactMarker *marker); - -G_END_DECLS - -#endif /* WITH_CONTACT_MAPS */ - -#endif diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c deleted file mode 100644 index fd2676a6b4..0000000000 --- a/widgets/misc/e-dateedit.c +++ /dev/null @@ -1,2498 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -/* - * EDateEdit - a widget based on GnomeDateEdit to provide a date & optional - * time field with popups for entering a date. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-dateedit.h" - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <gdk/gdkkeysyms.h> -#include <atk/atkrelation.h> -#include <atk/atkrelationset.h> -#include <glib/gi18n.h> - -#include <libebackend/libebackend.h> - -#include <e-util/e-util.h> -#include "e-calendar.h" - -#define E_DATE_EDIT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_DATE_EDIT, EDateEditPrivate)) - -struct _EDateEditPrivate { - GtkWidget *date_entry; - GtkWidget *date_button; - - GtkWidget *space; - - GtkWidget *time_combo; - - GtkWidget *cal_popup; - GtkWidget *calendar; - GtkWidget *now_button; - GtkWidget *today_button; - GtkWidget *none_button; /* This will only be visible if a - * 'None' date/time is permitted. */ - - GdkDevice *grabbed_keyboard; - GdkDevice *grabbed_pointer; - - gboolean show_date; - gboolean show_time; - gboolean use_24_hour_format; - - /* This is TRUE if we want to make the time field insensitive rather - * than hide it when set_show_time() is called. */ - gboolean make_time_insensitive; - - /* This is the range of hours we show in the time popup. */ - gint lower_hour; - gint upper_hour; - - /* This indicates whether the last date committed was invalid. - * (A date is committed by hitting Return, moving the keyboard focus, - * or selecting a date in the popup). Note that this only indicates - * that the date couldn't be parsed. A date set to 'None' is valid - * here, though e_date_edit_date_is_valid() will return FALSE if an - * empty date isn't actually permitted. */ - gboolean date_is_valid; - - /* This is the last valid date which was set. If the date was set to - * 'None' or empty, date_set_to_none will be TRUE and the other fields - * are undefined, so don't use them. */ - gboolean date_set_to_none; - gint year; - gint month; - gint day; - - /* This indicates whether the last time committed was invalid. - * (A time is committed by hitting Return, moving the keyboard focus, - * or selecting a time in the popup). Note that this only indicates - * that the time couldn't be parsed. An empty/None time is valid - * here, though e_date_edit_time_is_valid() will return FALSE if an - * empty time isn't actually permitted. */ - gboolean time_is_valid; - - /* This is the last valid time which was set. If the time was set to - * 'None' or empty, time_set_to_none will be TRUE and the other fields - * are undefined, so don't use them. */ - gboolean time_set_to_none; - gint hour; - gint minute; - - EDateEditGetTimeCallback time_callback; - gpointer time_callback_data; - GDestroyNotify time_callback_destroy; - - gboolean twodigit_year_can_future; - - /* set to TRUE when the date has been changed by typing to the entry */ - gboolean has_been_changed; - - gboolean allow_no_date_set; -}; - -enum { - PROP_0, - PROP_ALLOW_NO_DATE_SET, - PROP_SHOW_DATE, - PROP_SHOW_TIME, - PROP_SHOW_WEEK_NUMBERS, - PROP_USE_24_HOUR_FORMAT, - PROP_WEEK_START_DAY, - PROP_TWODIGIT_YEAR_CAN_FUTURE, - PROP_SET_NONE -}; - -enum { - CHANGED, - LAST_SIGNAL -}; - -static void create_children (EDateEdit *dedit); -static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling); -static void e_date_edit_grab_focus (GtkWidget *widget); - -static gint on_date_entry_key_press (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit); -static gint on_date_entry_key_release (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit); -static void on_date_button_clicked (GtkWidget *widget, - EDateEdit *dedit); -static void e_date_edit_show_date_popup (EDateEdit *dedit, - GdkEvent *event); -static void position_date_popup (EDateEdit *dedit); -static void on_date_popup_none_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_date_popup_today_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_date_popup_now_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static gint on_date_popup_delete_event (GtkWidget *widget, - EDateEdit *dedit); -static gint on_date_popup_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit); -static gint on_date_popup_button_press (GtkWidget *widget, - GdkEvent *button_event, - gpointer data); -static void on_date_popup_date_selected (ECalendarItem *calitem, - EDateEdit *dedit); -static void hide_date_popup (EDateEdit *dedit); -static void rebuild_time_popup (EDateEdit *dedit); -static gboolean field_set_to_none (const gchar *text); -static gboolean e_date_edit_parse_date (EDateEdit *dedit, - const gchar *date_text, - struct tm *date_tm); -static gboolean e_date_edit_parse_time (EDateEdit *dedit, - const gchar *time_text, - struct tm *time_tm); -static void on_date_edit_time_selected (GtkComboBox *combo, - EDateEdit *dedit); -static gint on_time_entry_key_press (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit); -static gint on_time_entry_key_release (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit); -static gint on_date_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit); -static gint on_time_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit); -static void e_date_edit_update_date_entry (EDateEdit *dedit); -static void e_date_edit_update_time_entry (EDateEdit *dedit); -static void e_date_edit_update_time_combo_state (EDateEdit *dedit); -static void e_date_edit_check_date_changed (EDateEdit *dedit); -static void e_date_edit_check_time_changed (EDateEdit *dedit); -static gboolean e_date_edit_set_date_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint year, - gint month, - gint day); -static gboolean e_date_edit_set_time_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint hour, - gint minute); - -static gint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE_WITH_CODE ( - EDateEdit, - e_date_edit, - GTK_TYPE_HBOX, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -static void -date_edit_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ALLOW_NO_DATE_SET: - e_date_edit_set_allow_no_date_set ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_SHOW_DATE: - e_date_edit_set_show_date ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_SHOW_TIME: - e_date_edit_set_show_time ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_SHOW_WEEK_NUMBERS: - e_date_edit_set_show_week_numbers ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_USE_24_HOUR_FORMAT: - e_date_edit_set_use_24_hour_format ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_WEEK_START_DAY: - e_date_edit_set_week_start_day ( - E_DATE_EDIT (object), - g_value_get_int (value)); - return; - - case PROP_TWODIGIT_YEAR_CAN_FUTURE: - e_date_edit_set_twodigit_year_can_future ( - E_DATE_EDIT (object), - g_value_get_boolean (value)); - return; - - case PROP_SET_NONE: - if (g_value_get_boolean (value)) - e_date_edit_set_time (E_DATE_EDIT (object), -1); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -date_edit_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ALLOW_NO_DATE_SET: - g_value_set_boolean ( - value, e_date_edit_get_allow_no_date_set ( - E_DATE_EDIT (object))); - return; - - case PROP_SHOW_DATE: - g_value_set_boolean ( - value, e_date_edit_get_show_date ( - E_DATE_EDIT (object))); - return; - - case PROP_SHOW_TIME: - g_value_set_boolean ( - value, e_date_edit_get_show_time ( - E_DATE_EDIT (object))); - return; - - case PROP_SHOW_WEEK_NUMBERS: - g_value_set_boolean ( - value, e_date_edit_get_show_week_numbers ( - E_DATE_EDIT (object))); - return; - - case PROP_USE_24_HOUR_FORMAT: - g_value_set_boolean ( - value, e_date_edit_get_use_24_hour_format ( - E_DATE_EDIT (object))); - return; - - case PROP_WEEK_START_DAY: - g_value_set_int ( - value, e_date_edit_get_week_start_day ( - E_DATE_EDIT (object))); - return; - - case PROP_TWODIGIT_YEAR_CAN_FUTURE: - g_value_set_boolean ( - value, e_date_edit_get_twodigit_year_can_future ( - E_DATE_EDIT (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -date_edit_dispose (GObject *object) -{ - EDateEdit *dedit; - - dedit = E_DATE_EDIT (object); - - e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL); - - if (dedit->priv->cal_popup != NULL) { - gtk_widget_destroy (dedit->priv->cal_popup); - dedit->priv->cal_popup = NULL; - } - - if (dedit->priv->grabbed_keyboard != NULL) { - gdk_device_ungrab ( - dedit->priv->grabbed_keyboard, - GDK_CURRENT_TIME); - g_object_unref (dedit->priv->grabbed_keyboard); - dedit->priv->grabbed_keyboard = NULL; - } - - if (dedit->priv->grabbed_pointer != NULL) { - gdk_device_ungrab ( - dedit->priv->grabbed_pointer, - GDK_CURRENT_TIME); - g_object_unref (dedit->priv->grabbed_pointer); - dedit->priv->grabbed_pointer = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_date_edit_parent_class)->dispose (object); -} - -static void -e_date_edit_class_init (EDateEditClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EDateEditPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = date_edit_set_property; - object_class->get_property = date_edit_get_property; - object_class->dispose = date_edit_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->mnemonic_activate = e_date_edit_mnemonic_activate; - widget_class->grab_focus = e_date_edit_grab_focus; - - g_object_class_install_property ( - object_class, - PROP_ALLOW_NO_DATE_SET, - g_param_spec_boolean ( - "allow-no-date-set", - "Allow No Date Set", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_DATE, - g_param_spec_boolean ( - "show-date", - "Show Date", - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_TIME, - g_param_spec_boolean ( - "show-time", - "Show Time", - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_WEEK_NUMBERS, - g_param_spec_boolean ( - "show-week-numbers", - "Show Week Numbers", - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_USE_24_HOUR_FORMAT, - g_param_spec_boolean ( - "use-24-hour-format", - "Use 24-Hour Format", - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WEEK_START_DAY, - g_param_spec_int ( - "week-start-day", - "Week Start Day", - NULL, - 0, /* Monday */ - 6, /* Sunday */ - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TWODIGIT_YEAR_CAN_FUTURE, - g_param_spec_boolean ( - "twodigit-year-can-future", - "Two-digit year can be treated as future", - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SET_NONE, - g_param_spec_boolean ( - "set-none", - "Sets None as selected date", - NULL, - FALSE, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EDateEditClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_date_edit_init (EDateEdit *dedit) -{ - dedit->priv = E_DATE_EDIT_GET_PRIVATE (dedit); - - dedit->priv->show_date = TRUE; - dedit->priv->show_time = TRUE; - dedit->priv->use_24_hour_format = TRUE; - - dedit->priv->make_time_insensitive = FALSE; - - dedit->priv->lower_hour = 0; - dedit->priv->upper_hour = 24; - - dedit->priv->date_is_valid = TRUE; - dedit->priv->date_set_to_none = TRUE; - dedit->priv->time_is_valid = TRUE; - dedit->priv->time_set_to_none = TRUE; - dedit->priv->time_callback = NULL; - dedit->priv->time_callback_data = NULL; - dedit->priv->time_callback_destroy = NULL; - - dedit->priv->twodigit_year_can_future = TRUE; - dedit->priv->has_been_changed = FALSE; - - create_children (dedit); - - /* Set it to the current time. */ - e_date_edit_set_time (dedit, 0); - - e_extensible_load_extensions (E_EXTENSIBLE (dedit)); -} - -/** - * e_date_edit_new: - * - * Description: Creates a new #EDateEdit widget which can be used - * to provide an easy to use way for entering dates and times. - * - * Returns: a new #EDateEdit widget. - */ -GtkWidget * -e_date_edit_new (void) -{ - EDateEdit *dedit; - AtkObject *a11y; - - dedit = g_object_new (E_TYPE_DATE_EDIT, NULL); - a11y = gtk_widget_get_accessible (GTK_WIDGET (dedit)); - atk_object_set_name (a11y, _("Date and Time")); - - return GTK_WIDGET (dedit); -} - -static void -create_children (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - ECalendar *calendar; - GtkWidget *frame, *arrow; - GtkWidget *vbox, *bbox; - GtkWidget *child; - AtkObject *a11y; - GtkListStore *time_store; - GList *cells; - GtkCssProvider *css_provider; - GtkStyleContext *style_context; - const gchar *css; - GError *error = NULL; - - priv = dedit->priv; - - priv->date_entry = gtk_entry_new (); - a11y = gtk_widget_get_accessible (priv->date_entry); - atk_object_set_description (a11y, _("Text entry to input date")); - atk_object_set_name (a11y, _("Date")); - gtk_box_pack_start (GTK_BOX (dedit), priv->date_entry, FALSE, TRUE, 0); - gtk_widget_set_size_request (priv->date_entry, 100, -1); - - g_signal_connect ( - priv->date_entry, "key_press_event", - G_CALLBACK (on_date_entry_key_press), dedit); - g_signal_connect ( - priv->date_entry, "key_release_event", - G_CALLBACK (on_date_entry_key_release), dedit); - g_signal_connect_after ( - priv->date_entry, "focus_out_event", - G_CALLBACK (on_date_entry_focus_out), dedit); - - priv->date_button = gtk_button_new (); - g_signal_connect ( - priv->date_button, "clicked", - G_CALLBACK (on_date_button_clicked), dedit); - gtk_box_pack_start ( - GTK_BOX (dedit), priv->date_button, - FALSE, FALSE, 0); - a11y = gtk_widget_get_accessible (priv->date_button); - atk_object_set_description (a11y, _("Click this button to show a calendar")); - atk_object_set_name (a11y, _("Date")); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (priv->date_button), arrow); - gtk_widget_show (arrow); - - if (priv->show_date) { - gtk_widget_show (priv->date_entry); - gtk_widget_show (priv->date_button); - } - - /* This is just to create a space between the date & time parts. */ - priv->space = gtk_drawing_area_new (); - gtk_box_pack_start (GTK_BOX (dedit), priv->space, FALSE, FALSE, 2); - - time_store = gtk_list_store_new (1, G_TYPE_STRING); - priv->time_combo = gtk_combo_box_new_with_model_and_entry ( - GTK_TREE_MODEL (time_store)); - gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->time_combo), 0); - g_object_unref (time_store); - - css_provider = gtk_css_provider_new (); - css = "GtkComboBox { -GtkComboBox-appears-as-list: 1; }"; - gtk_css_provider_load_from_data (css_provider, css, -1, &error); - style_context = gtk_widget_get_style_context (priv->time_combo); - if (error == NULL) { - gtk_style_context_add_provider ( - style_context, - GTK_STYLE_PROVIDER (css_provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - } else { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - g_object_unref (css_provider); - - child = gtk_bin_get_child (GTK_BIN (priv->time_combo)); - - /* We need to make sure labels are right-aligned, since we want - * digits to line up, and with a nonproportional font, the width - * of a space != width of a digit. Technically, only 12-hour - * format needs this, but we do it always, for consistency. */ - g_object_set (child, "xalign", 1.0, NULL); - cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->time_combo)); - if (cells) { - g_object_set (GTK_CELL_RENDERER (cells->data), "xalign", 1.0, NULL); - g_list_free (cells); - } - - gtk_box_pack_start (GTK_BOX (dedit), priv->time_combo, FALSE, TRUE, 0); - gtk_widget_set_size_request (priv->time_combo, 110, -1); - rebuild_time_popup (dedit); - a11y = gtk_widget_get_accessible (priv->time_combo); - atk_object_set_description (a11y, _("Drop-down combination box to select time")); - atk_object_set_name (a11y, _("Time")); - - g_signal_connect ( - child, "key_press_event", - G_CALLBACK (on_time_entry_key_press), dedit); - g_signal_connect ( - child, "key_release_event", - G_CALLBACK (on_time_entry_key_release), dedit); - g_signal_connect_after ( - child, "focus_out_event", - G_CALLBACK (on_time_entry_focus_out), dedit); - g_signal_connect_after ( - priv->time_combo, "changed", - G_CALLBACK (on_date_edit_time_selected), dedit); - - if (priv->show_time || priv->make_time_insensitive) - gtk_widget_show (priv->time_combo); - - if (!priv->show_time && priv->make_time_insensitive) - gtk_widget_set_sensitive (priv->time_combo, FALSE); - - if (priv->show_date - && (priv->show_time || priv->make_time_insensitive)) - gtk_widget_show (priv->space); - - priv->cal_popup = gtk_window_new (GTK_WINDOW_POPUP); - gtk_window_set_type_hint ( - GTK_WINDOW (priv->cal_popup), - GDK_WINDOW_TYPE_HINT_COMBO); - gtk_widget_set_events ( - priv->cal_popup, - gtk_widget_get_events (priv->cal_popup) - | GDK_KEY_PRESS_MASK); - g_signal_connect ( - priv->cal_popup, "delete_event", - G_CALLBACK (on_date_popup_delete_event), dedit); - g_signal_connect ( - priv->cal_popup, "key_press_event", - G_CALLBACK (on_date_popup_key_press), dedit); - g_signal_connect ( - priv->cal_popup, "button_press_event", - G_CALLBACK (on_date_popup_button_press), dedit); - gtk_window_set_resizable (GTK_WINDOW (priv->cal_popup), TRUE); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (priv->cal_popup), frame); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_widget_show (vbox); - - priv->calendar = e_calendar_new (); - calendar = E_CALENDAR (priv->calendar); - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (calendar->calitem), - "maximum_days_selected", 1, - "move_selection_when_moving", FALSE, - NULL); - - g_signal_connect ( - calendar->calitem, "selection_changed", - G_CALLBACK (on_date_popup_date_selected), dedit); - - gtk_box_pack_start (GTK_BOX (vbox), priv->calendar, FALSE, FALSE, 0); - gtk_widget_show (priv->calendar); - - bbox = gtk_hbutton_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (bbox), 4); - gtk_box_set_spacing (GTK_BOX (bbox), 2); - gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - priv->now_button = gtk_button_new_with_mnemonic (_("No_w")); - gtk_container_add (GTK_CONTAINER (bbox), priv->now_button); - gtk_widget_show (priv->now_button); - g_signal_connect ( - priv->now_button, "clicked", - G_CALLBACK (on_date_popup_now_button_clicked), dedit); - - priv->today_button = gtk_button_new_with_mnemonic (_("_Today")); - gtk_container_add (GTK_CONTAINER (bbox), priv->today_button); - gtk_widget_show (priv->today_button); - g_signal_connect ( - priv->today_button, "clicked", - G_CALLBACK (on_date_popup_today_button_clicked), dedit); - - /* Note that we don't show this here, since by default a 'None' date - * is not permitted. */ - priv->none_button = gtk_button_new_with_mnemonic (_("_None")); - gtk_container_add (GTK_CONTAINER (bbox), priv->none_button); - g_signal_connect ( - priv->none_button, "clicked", - G_CALLBACK (on_date_popup_none_button_clicked), dedit); - g_object_bind_property ( - dedit, "allow-no-date-set", - priv->none_button, "visible", - G_BINDING_SYNC_CREATE); -} - -/* GtkWidget::mnemonic_activate() handler for the EDateEdit */ -static gboolean -e_date_edit_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling) -{ - e_date_edit_grab_focus (widget); - return TRUE; -} - -/* Grab_focus handler for the EDateEdit. If the date field is being shown, we - * grab the focus to that, otherwise we grab it to the time field. */ -static void -e_date_edit_grab_focus (GtkWidget *widget) -{ - EDateEdit *dedit; - GtkWidget *child; - - g_return_if_fail (E_IS_DATE_EDIT (widget)); - - dedit = E_DATE_EDIT (widget); - child = gtk_bin_get_child (GTK_BIN (dedit->priv->time_combo)); - - if (dedit->priv->show_date) - gtk_widget_grab_focus (dedit->priv->date_entry); - else - gtk_widget_grab_focus (child); -} - -/** - * e_date_edit_set_editable: - * @dedit: an #EDateEdit widget. - * @editable: whether or not the widget should accept edits. - * - * Allows the programmer to disallow editing (and the popping up of - * the calendar widget), while still allowing the user to select the - * date from the GtkEntry. - */ -void -e_date_edit_set_editable (EDateEdit *dedit, - gboolean editable) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - gtk_editable_set_editable (GTK_EDITABLE (priv->date_entry), editable); - gtk_widget_set_sensitive (priv->date_button, editable); -} - -/** - * e_date_edit_get_time: - * @dedit: an #EDateEdit widget. - * @the_time: returns the last valid time entered. - * @Returns: the last valid time entered, or -1 if the time is not set. - * - * Returns the last valid time entered. If empty times are valid, by calling - * e_date_edit_set_allow_no_date_set(), then it may return -1. - * - * Note that the last time entered may actually have been invalid. You can - * check this with e_date_edit_time_is_valid(). - */ -time_t -e_date_edit_get_time (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - struct tm tmp_tm = { 0 }; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), -1); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_date_changed (dedit); - e_date_edit_check_time_changed (dedit); - - if (priv->date_set_to_none) - return -1; - - tmp_tm.tm_year = priv->year; - tmp_tm.tm_mon = priv->month; - tmp_tm.tm_mday = priv->day; - - if (!priv->show_time || priv->time_set_to_none) { - tmp_tm.tm_hour = 0; - tmp_tm.tm_min = 0; - } else { - tmp_tm.tm_hour = priv->hour; - tmp_tm.tm_min = priv->minute; - } - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = -1; - - return mktime (&tmp_tm); -} - -/** - * e_date_edit_set_time: - * @dedit: the EDateEdit widget - * @the_time: The time and date that should be set on the widget - * - * Description: Changes the displayed date and time in the EDateEdit - * widget to be the one represented by @the_time. If @the_time is 0 - * then current time is used. If it is -1, then the date is set to None. - * - * Note that the time is converted to local time using the Unix timezone, - * so if you are using your own timezones then you should use - * e_date_edit_set_date() and e_date_edit_set_time_of_day() instead. - */ -void -e_date_edit_set_time (EDateEdit *dedit, - time_t the_time) -{ - EDateEditPrivate *priv; - struct tm tmp_tm; - gboolean date_changed = FALSE, time_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (the_time == -1) { - date_changed = e_date_edit_set_date_internal ( - dedit, TRUE, - TRUE, 0, 0, 0); - time_changed = e_date_edit_set_time_internal ( - dedit, TRUE, - TRUE, 0, 0); - } else { - if (the_time == 0) { - if (priv->time_callback) { - tmp_tm = (*priv->time_callback) (dedit, priv->time_callback_data); - } else { - the_time = time (NULL); - tmp_tm = *localtime (&the_time); - } - } else { - tmp_tm = *localtime (&the_time); - } - - date_changed = e_date_edit_set_date_internal ( - dedit, TRUE, - FALSE, - tmp_tm.tm_year, - tmp_tm.tm_mon, - tmp_tm.tm_mday); - time_changed = e_date_edit_set_time_internal ( - dedit, TRUE, - FALSE, - tmp_tm.tm_hour, - tmp_tm.tm_min); - } - - e_date_edit_update_date_entry (dedit); - e_date_edit_update_time_entry (dedit); - e_date_edit_update_time_combo_state (dedit); - - /* Emit the signals if the date and/or time has actually changed. */ - if (date_changed || time_changed) - g_signal_emit (dedit, signals[CHANGED], 0); -} - -/** - * e_date_edit_get_date: - * @dedit: an #EDateEdit widget. - * @year: returns the year set. - * @month: returns the month set (1 - 12). - * @day: returns the day set (1 - 31). - * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'. - * - * Returns the last valid date entered into the date field. - */ -gboolean -e_date_edit_get_date (EDateEdit *dedit, - gint *year, - gint *month, - gint *day) -{ - EDateEditPrivate *priv; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_date_changed (dedit); - - *year = priv->year + 1900; - *month = priv->month + 1; - *day = priv->day; - - if (priv->date_set_to_none - && e_date_edit_get_allow_no_date_set (dedit)) - return FALSE; - - return TRUE; -} - -/** - * e_date_edit_set_date: - * @dedit: an #EDateEdit widget. - * @year: the year to set. - * @month: the month to set (1 - 12). - * @day: the day to set (1 - 31). - * - * Sets the date in the date field. - */ -void -e_date_edit_set_date (EDateEdit *dedit, - gint year, - gint month, - gint day) -{ - gboolean date_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - date_changed = e_date_edit_set_date_internal ( - dedit, TRUE, FALSE, - year - 1900, month - 1, - day); - - e_date_edit_update_date_entry (dedit); - e_date_edit_update_time_combo_state (dedit); - - /* Emit the signals if the date has actually changed. */ - if (date_changed) - g_signal_emit (dedit, signals[CHANGED], 0); -} - -/** - * e_date_edit_get_time_of_day: - * @dedit: an #EDateEdit widget. - * @hour: returns the hour set, or 0 if the time isn't set. - * @minute: returns the minute set, or 0 if the time isn't set. - * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'. - * - * Returns the last valid time entered into the time field. - */ -gboolean -e_date_edit_get_time_of_day (EDateEdit *dedit, - gint *hour, - gint *minute) -{ - EDateEditPrivate *priv; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_time_changed (dedit); - - if (priv->time_set_to_none) { - *hour = 0; - *minute = 0; - return FALSE; - } else { - *hour = priv->hour; - *minute = priv->minute; - return TRUE; - } -} - -/** - * e_date_edit_set_time_of_day: - * @dedit: an #EDateEdit widget. - * @hour: the hour to set, or -1 to set the time to None (i.e. empty). - * @minute: the minute to set. - * - * Description: Sets the time in the time field. - */ -void -e_date_edit_set_time_of_day (EDateEdit *dedit, - gint hour, - gint minute) -{ - EDateEditPrivate *priv; - gboolean time_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (hour == -1) { - gboolean allow_no_date_set = e_date_edit_get_allow_no_date_set (dedit); - g_return_if_fail (allow_no_date_set); - if (!priv->time_set_to_none) { - priv->time_set_to_none = TRUE; - time_changed = TRUE; - } - } else if (priv->time_set_to_none - || priv->hour != hour - || priv->minute != minute) { - priv->time_set_to_none = FALSE; - priv->hour = hour; - priv->minute = minute; - time_changed = TRUE; - } - - e_date_edit_update_time_entry (dedit); - - if (time_changed) - g_signal_emit (dedit, signals[CHANGED], 0); -} - -void -e_date_edit_set_date_and_time_of_day (EDateEdit *dedit, - gint year, - gint month, - gint day, - gint hour, - gint minute) -{ - gboolean date_changed, time_changed; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - date_changed = e_date_edit_set_date_internal ( - dedit, TRUE, FALSE, - year - 1900, month - 1, day); - time_changed = e_date_edit_set_time_internal ( - dedit, TRUE, FALSE, - hour, minute); - - e_date_edit_update_date_entry (dedit); - e_date_edit_update_time_entry (dedit); - e_date_edit_update_time_combo_state (dedit); - - if (date_changed || time_changed) - g_signal_emit (dedit, signals[CHANGED], 0); -} - -/** - * e_date_edit_get_show_date: - * @dedit: an #EDateEdit widget. - * @Returns: Whether the date field is shown. - * - * Description: Returns TRUE if the date field is currently shown. - */ -gboolean -e_date_edit_get_show_date (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->show_date; -} - -/** - * e_date_edit_set_show_date: - * @dedit: an #EDateEdit widget. - * @show_date: TRUE if the date field should be shown. - * - * Description: Specifies whether the date field should be shown. The date - * field would be hidden if only a time needed to be entered. - */ -void -e_date_edit_set_show_date (EDateEdit *dedit, - gboolean show_date) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->show_date == show_date) - return; - - priv->show_date = show_date; - - if (show_date) { - gtk_widget_show (priv->date_entry); - gtk_widget_show (priv->date_button); - } else { - gtk_widget_hide (priv->date_entry); - gtk_widget_hide (priv->date_button); - } - - e_date_edit_update_time_combo_state (dedit); - - if (priv->show_date - && (priv->show_time || priv->make_time_insensitive)) - gtk_widget_show (priv->space); - else - gtk_widget_hide (priv->space); - - g_object_notify (G_OBJECT (dedit), "show-date"); -} - -/** - * e_date_edit_get_show_time: - * @dedit: an #EDateEdit widget - * @Returns: Whether the time field is shown. - * - * Description: Returns TRUE if the time field is currently shown. - */ -gboolean -e_date_edit_get_show_time (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->show_time; -} - -/** - * e_date_edit_set_show_time: - * @dedit: an #EDateEdit widget - * @show_time: TRUE if the time field should be shown. - * - * Description: Specifies whether the time field should be shown. The time - * field would be hidden if only a date needed to be entered. - */ -void -e_date_edit_set_show_time (EDateEdit *dedit, - gboolean show_time) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->show_time == show_time) - return; - - priv->show_time = show_time; - - e_date_edit_update_time_combo_state (dedit); - - g_object_notify (G_OBJECT (dedit), "show-time"); -} - -/** - * e_date_edit_get_make_time_insensitive: - * @dedit: an #EDateEdit widget - * @Returns: Whether the time field is be made insensitive instead of hiding - * it. - * - * Description: Returns TRUE if the time field is made insensitive instead of - * hiding it. - */ -gboolean -e_date_edit_get_make_time_insensitive (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->make_time_insensitive; -} - -/** - * e_date_edit_set_make_time_insensitive: - * @dedit: an #EDateEdit widget - * @make_insensitive: TRUE if the time field should be made insensitive instead - * of hiding it. - * - * Description: Specifies whether the time field should be made insensitive - * rather than hiding it. Note that this doesn't make it insensitive - you - * need to call e_date_edit_set_show_time() with FALSE as show_time to do that. - * - * This is useful if you want to disable the time field, but don't want it to - * disappear as that may affect the layout of the widgets. - */ -void -e_date_edit_set_make_time_insensitive (EDateEdit *dedit, - gboolean make_insensitive) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->make_time_insensitive == make_insensitive) - return; - - priv->make_time_insensitive = make_insensitive; - - e_date_edit_update_time_combo_state (dedit); -} - -/** - * e_date_edit_get_week_start_day: - * @dedit: an #EDateEdit widget - * @Returns: the week start day, from 0 (Monday) to 6 (Sunday). - * - * Description: Returns the week start day currently used in the calendar - * popup. - */ -gint -e_date_edit_get_week_start_day (EDateEdit *dedit) -{ - gint week_start_day; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), 1); - - g_object_get ( - E_CALENDAR (dedit->priv->calendar)->calitem, - "week_start_day", &week_start_day, NULL); - - return week_start_day; -} - -/** - * e_date_edit_set_week_start_day: - * @dedit: an #EDateEdit widget - * @week_start_day: the week start day, from 0 (Monday) to 6 (Sunday). - * - * Description: Sets the week start day to use in the calendar popup. - */ -void -e_date_edit_set_week_start_day (EDateEdit *dedit, - gint week_start_day) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "week_start_day", week_start_day, NULL); - - g_object_notify (G_OBJECT (dedit), "week-start-day"); -} - -/* Whether we show week numbers in the date popup. */ -gboolean -e_date_edit_get_show_week_numbers (EDateEdit *dedit) -{ - gboolean show_week_numbers; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - g_object_get ( - E_CALENDAR (dedit->priv->calendar)->calitem, - "show_week_numbers", &show_week_numbers, NULL); - - return show_week_numbers; -} - -void -e_date_edit_set_show_week_numbers (EDateEdit *dedit, - gboolean show_week_numbers) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "show_week_numbers", show_week_numbers, NULL); - - g_object_notify (G_OBJECT (dedit), "show-week-numbers"); -} - -/* Whether we use 24 hour format in the time field & popup. */ -gboolean -e_date_edit_get_use_24_hour_format (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->use_24_hour_format; -} - -void -e_date_edit_set_use_24_hour_format (EDateEdit *dedit, - gboolean use_24_hour_format) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - if (dedit->priv->use_24_hour_format == use_24_hour_format) - return; - - dedit->priv->use_24_hour_format = use_24_hour_format; - - rebuild_time_popup (dedit); - - e_date_edit_update_time_entry (dedit); - - g_object_notify (G_OBJECT (dedit), "use-24-hour-format"); -} - -/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will - * return (time_t) -1 in this case. */ -gboolean -e_date_edit_get_allow_no_date_set (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - return dedit->priv->allow_no_date_set; -} - -void -e_date_edit_set_allow_no_date_set (EDateEdit *dedit, - gboolean allow_no_date_set) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - if (dedit->priv->allow_no_date_set == allow_no_date_set) - return; - - dedit->priv->allow_no_date_set = allow_no_date_set; - - if (!allow_no_date_set) { - /* If the date is showing, we make sure it isn't 'None' (we - * don't really mind if the time is empty), else if just the - * time is showing we make sure it isn't 'None'. */ - if (dedit->priv->show_date) { - if (dedit->priv->date_set_to_none) - e_date_edit_set_time (dedit, 0); - } else { - if (dedit->priv->time_set_to_none) - e_date_edit_set_time (dedit, 0); - } - } - - g_object_notify (G_OBJECT (dedit), "allow-no-date-set"); -} - -/* The range of time to show in the time combo popup. */ -void -e_date_edit_get_time_popup_range (EDateEdit *dedit, - gint *lower_hour, - gint *upper_hour) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - *lower_hour = dedit->priv->lower_hour; - *upper_hour = dedit->priv->upper_hour; -} - -void -e_date_edit_set_time_popup_range (EDateEdit *dedit, - gint lower_hour, - gint upper_hour) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->lower_hour == lower_hour - && priv->upper_hour == upper_hour) - return; - - priv->lower_hour = lower_hour; - priv->upper_hour = upper_hour; - - rebuild_time_popup (dedit); - - /* Setting the combo list items seems to mess up the time entry, so - * we set it again. We have to reset it to its last valid time. */ - priv->time_is_valid = TRUE; - e_date_edit_update_time_entry (dedit); -} - -/* The arrow button beside the date field has been clicked, so we show the - * popup with the ECalendar in. */ -static void -on_date_button_clicked (GtkWidget *widget, - EDateEdit *dedit) -{ - GdkEvent *event; - - /* Obtain the GdkEvent that triggered - * the date button's "clicked" signal. */ - event = gtk_get_current_event (); - e_date_edit_show_date_popup (dedit, event); -} - -static void -e_date_edit_show_date_popup (EDateEdit *dedit, - GdkEvent *event) -{ - EDateEditPrivate *priv; - ECalendar *calendar; - GdkDevice *event_device; - GdkDevice *assoc_device; - GdkDevice *keyboard_device; - GdkDevice *pointer_device; - GdkWindow *window; - GdkGrabStatus grab_status; - struct tm mtm; - const gchar *date_text; - GDate selected_day; - gboolean clear_selection = FALSE; - guint event_time; - - priv = dedit->priv; - calendar = E_CALENDAR (priv->calendar); - - date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry)); - if (field_set_to_none (date_text) - || !e_date_edit_parse_date (dedit, date_text, &mtm)) - clear_selection = TRUE; - - if (clear_selection) { - e_calendar_item_set_selection (calendar->calitem, NULL, NULL); - } else { - g_date_clear (&selected_day, 1); - g_date_set_dmy ( - &selected_day, mtm.tm_mday, mtm.tm_mon + 1, - mtm.tm_year + 1900); - e_calendar_item_set_selection ( - calendar->calitem, - &selected_day, NULL); - } - - /* FIXME: Hack. Change ECalendarItem so it doesn't queue signal - * emissions. */ - calendar->calitem->selection_changed = FALSE; - - position_date_popup (dedit); - gtk_widget_show (priv->cal_popup); - gtk_widget_grab_focus (priv->cal_popup); - gtk_grab_add (priv->cal_popup); - - window = gtk_widget_get_window (priv->cal_popup); - - g_return_if_fail (priv->grabbed_keyboard == NULL); - g_return_if_fail (priv->grabbed_pointer == NULL); - - event_device = gdk_event_get_device (event); - assoc_device = gdk_device_get_associated_device (event_device); - - event_time = gdk_event_get_time (event); - - if (gdk_device_get_source (event_device) == GDK_SOURCE_KEYBOARD) { - keyboard_device = event_device; - pointer_device = assoc_device; - } else { - keyboard_device = assoc_device; - pointer_device = event_device; - } - - if (keyboard_device != NULL) { - grab_status = gdk_device_grab ( - keyboard_device, - window, - GDK_OWNERSHIP_WINDOW, - TRUE, - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK, - NULL, - event_time); - if (grab_status == GDK_GRAB_SUCCESS) { - priv->grabbed_keyboard = - g_object_ref (keyboard_device); - } - } - - if (pointer_device != NULL) { - grab_status = gdk_device_grab ( - pointer_device, - window, - GDK_OWNERSHIP_WINDOW, - TRUE, - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK, - NULL, - event_time); - if (grab_status == GDK_GRAB_SUCCESS) { - priv->grabbed_pointer = - g_object_ref (pointer_device); - } else if (priv->grabbed_keyboard != NULL) { - gdk_device_ungrab ( - priv->grabbed_keyboard, - event_time); - g_object_unref (priv->grabbed_keyboard); - priv->grabbed_keyboard = NULL; - } - } - - gdk_window_focus (window, event_time); -} - -/* This positions the date popup below and to the left of the arrow button, - * just before it is shown. */ -static void -position_date_popup (EDateEdit *dedit) -{ - gint x, y; - gint win_x, win_y; - gint bwidth, bheight; - GtkWidget *toplevel; - GdkWindow *window; - GtkRequisition cal_req, button_req; - gint screen_width, screen_height; - - gtk_widget_get_preferred_size (dedit->priv->cal_popup, &cal_req, NULL); - - gtk_widget_get_preferred_size (dedit->priv->date_button, &button_req, NULL); - bwidth = button_req.width; - gtk_widget_get_preferred_size ( - gtk_widget_get_parent (dedit->priv->date_button), &button_req, NULL); - bheight = button_req.height; - - gtk_widget_translate_coordinates ( - dedit->priv->date_button, - gtk_widget_get_toplevel (dedit->priv->date_button), - bwidth - cal_req.width, bheight, &x, &y); - - toplevel = gtk_widget_get_toplevel (dedit->priv->date_button); - window = gtk_widget_get_window (toplevel); - gdk_window_get_origin (window, &win_x, &win_y); - - x += win_x; - y += win_y; - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - x = CLAMP (x, 0, MAX (0, screen_width - cal_req.width)); - y = CLAMP (y, 0, MAX (0, screen_height - cal_req.height)); - - gtk_window_move (GTK_WINDOW (dedit->priv->cal_popup), x, y); -} - -/* A date has been selected in the date popup, so we set the date field - * and hide the popup. */ -static void -on_date_popup_date_selected (ECalendarItem *calitem, - EDateEdit *dedit) -{ - GDate start_date, end_date; - - hide_date_popup (dedit); - - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return; - - e_date_edit_set_date ( - dedit, g_date_get_year (&start_date), - g_date_get_month (&start_date), - g_date_get_day (&start_date)); -} - -static void -on_date_popup_now_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - e_date_edit_set_time (dedit, 0); -} - -static void -on_date_popup_today_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - EDateEditPrivate *priv; - struct tm tmp_tm; - time_t t; - - priv = dedit->priv; - - hide_date_popup (dedit); - - if (priv->time_callback) { - tmp_tm = (*priv->time_callback) (dedit, priv->time_callback_data); - } else { - t = time (NULL); - tmp_tm = *localtime (&t); - } - - e_date_edit_set_date ( - dedit, tmp_tm.tm_year + 1900, - tmp_tm.tm_mon + 1, tmp_tm.tm_mday); -} - -static void -on_date_popup_none_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - e_date_edit_set_time (dedit, -1); -} - -/* A key has been pressed while the date popup is showing. If it is the Escape - * key we hide the popup. */ -static gint -on_date_popup_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit) -{ - if (event->keyval == GDK_KEY_Escape) { - g_signal_stop_emission_by_name (widget, "key_press_event"); - hide_date_popup (dedit); - return TRUE; - } - - return FALSE; -} - -/* A mouse button has been pressed while the date popup is showing. - * Any button press events used to select days etc. in the popup will have - * have been handled elsewhere, so here we just hide the popup. - * (This function is yanked from gtkcombo.c) */ -static gint -on_date_popup_button_press (GtkWidget *widget, - GdkEvent *button_event, - gpointer data) -{ - EDateEdit *dedit; - GtkWidget *child; - - dedit = data; - - child = gtk_get_event_widget (button_event); - - /* We don't ask for button press events on the grab widget, so - * if an event is reported directly to the grab widget, it must - * be on a window outside the application (and thus we remove - * the popup window). Otherwise, we check if the widget is a child - * of the grab widget, and only remove the popup window if it - * is not. - */ - if (child != widget) { - while (child) { - if (child == widget) - return FALSE; - child = gtk_widget_get_parent (child); - } - } - - hide_date_popup (dedit); - - return TRUE; -} - -/* A delete event has been received for the date popup, so we hide it and - * return TRUE so it doesn't get destroyed. */ -static gint -on_date_popup_delete_event (GtkWidget *widget, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - return TRUE; -} - -/* Hides the date popup, removing any grabs. */ -static void -hide_date_popup (EDateEdit *dedit) -{ - gtk_widget_hide (dedit->priv->cal_popup); - gtk_grab_remove (dedit->priv->cal_popup); - - if (dedit->priv->grabbed_keyboard != NULL) { - gdk_device_ungrab ( - dedit->priv->grabbed_keyboard, - GDK_CURRENT_TIME); - g_object_unref (dedit->priv->grabbed_keyboard); - dedit->priv->grabbed_keyboard = NULL; - } - - if (dedit->priv->grabbed_pointer != NULL) { - gdk_device_ungrab ( - dedit->priv->grabbed_pointer, - GDK_CURRENT_TIME); - g_object_unref (dedit->priv->grabbed_pointer); - dedit->priv->grabbed_pointer = NULL; - } -} - -/* Clears the time popup and rebuilds it using the lower_hour, upper_hour - * and use_24_hour_format settings. */ -static void -rebuild_time_popup (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - GtkTreeModel *model; - GtkListStore *list_store; - GtkTreeIter iter; - gchar buffer[40]; - struct tm tmp_tm; - gint hour, min; - - priv = dedit->priv; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->time_combo)); - list_store = GTK_LIST_STORE (model); - gtk_list_store_clear (list_store); - - /* Fill the struct tm with some sane values. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = 0; - - for (hour = priv->lower_hour; hour <= priv->upper_hour; hour++) { - - /* We don't want to display midnight at the end, - * since that is really in the next day. */ - if (hour == 24) - break; - - /* We want to finish on upper_hour, with min == 0. */ - for (min = 0; - min == 0 || (min < 60 && hour != priv->upper_hour); - min += 30) { - tmp_tm.tm_hour = hour; - tmp_tm.tm_min = min; - - if (priv->use_24_hour_format) - /* This is a strftime() format. - * %H = hour (0-23), %M = minute. */ - e_time_format_time ( - &tmp_tm, 1, 0, - buffer, sizeof (buffer)); - else - /* This is a strftime() format. - * %I = hour (1-12), %M = minute, - * %p = am/pm string. */ - e_time_format_time ( - &tmp_tm, 0, 0, - buffer, sizeof (buffer)); - - /* For 12-hour am/pm format, we want space padding, - * not zero padding. This can be done with strftime's - * %l, but it's a potentially unportable extension. */ - if (!priv->use_24_hour_format && buffer[0] == '0') - buffer[0] = ' '; - - gtk_list_store_append (list_store, &iter); - gtk_list_store_set (list_store, &iter, 0, buffer, -1); - } - } -} - -static gboolean -e_date_edit_parse_date (EDateEdit *dedit, - const gchar *date_text, - struct tm *date_tm) -{ - gboolean twodigit_year = FALSE; - - if (e_time_parse_date_ex (date_text, date_tm, &twodigit_year) != E_TIME_PARSE_OK) - return FALSE; - - if (twodigit_year && !dedit->priv->twodigit_year_can_future) { - time_t t = time (NULL); - struct tm *today_tm = localtime (&t); - - /* It was only 2 digit year in dedit and it was interpreted as - * in the future, but we don't want it as this, so decrease by - * 100 years to last century. */ - if (date_tm->tm_year > today_tm->tm_year) - date_tm->tm_year -= 100; - } - - return TRUE; -} - -static gboolean -e_date_edit_parse_time (EDateEdit *dedit, - const gchar *time_text, - struct tm *time_tm) -{ - if (field_set_to_none (time_text)) { - time_tm->tm_hour = 0; - time_tm->tm_min = 0; - return TRUE; - } - - if (e_time_parse_time (time_text, time_tm) != E_TIME_PARSE_OK) - return FALSE; - - return TRUE; -} - -/* Returns TRUE if the string is empty or is "None" in the current locale. - * It ignores whitespace. */ -static gboolean -field_set_to_none (const gchar *text) -{ - const gchar *pos; - const gchar *none_string; - gint n; - - pos = text; - while (n = (gint)((guchar) * pos), isspace (n)) - pos++; - - /* Translators: "None" for date field of a date edit, shown when - * there is no date set. */ - none_string = C_("date", "None"); - - if (*pos == '\0' || !strncmp (pos, none_string, strlen (none_string))) - return TRUE; - return FALSE; -} - -static void -on_date_edit_time_selected (GtkComboBox *combo, - EDateEdit *dedit) -{ - GtkWidget *child; - - child = gtk_bin_get_child (GTK_BIN (combo)); - - /* We only want to emit signals when an item is selected explicitly, - * not when it is selected by the silly combo update thing. */ - if (gtk_combo_box_get_active (combo) == -1) - return; - - if (!gtk_widget_get_mapped (child)) - return; - - e_date_edit_check_time_changed (dedit); -} - -static gint -on_date_entry_key_press (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit) -{ - GdkModifierType event_state = 0; - guint event_keyval = 0; - - gdk_event_get_keyval (key_event, &event_keyval); - gdk_event_get_state (key_event, &event_state); - - if (event_state & GDK_MOD1_MASK - && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down - || event_keyval == GDK_KEY_Return)) { - g_signal_stop_emission_by_name (widget, "key_press_event"); - e_date_edit_show_date_popup (dedit, key_event); - return TRUE; - } - - /* If the user hits the return key emit a "date_changed" signal if - * needed. But let the signal carry on. */ - if (event_keyval == GDK_KEY_Return) { - e_date_edit_check_date_changed (dedit); - return FALSE; - } - - return FALSE; -} - -static gint -on_time_entry_key_press (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit) -{ - GtkWidget *child; - GdkModifierType event_state = 0; - guint event_keyval = 0; - - gdk_event_get_keyval (key_event, &event_keyval); - gdk_event_get_state (key_event, &event_state); - - child = gtk_bin_get_child (GTK_BIN (dedit->priv->time_combo)); - - /* I'd like to use Alt+Up/Down for popping up the list, like Win32, - * but the combo steals any Up/Down keys, so we use Alt + Return. */ -#if 0 - if (event_state & GDK_MOD1_MASK - && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down)) { -#else - if (event_state & GDK_MOD1_MASK && event_keyval == GDK_KEY_Return) { -#endif - g_signal_stop_emission_by_name (widget, "key_press_event"); - g_signal_emit_by_name (child, "activate", 0); - return TRUE; - } - - /* Stop the return key from emitting the activate signal, and check - * if we need to emit a "time_changed" signal. */ - if (event_keyval == GDK_KEY_Return) { - g_signal_stop_emission_by_name (widget, "key_press_event"); - e_date_edit_check_time_changed (dedit); - return TRUE; - } - - return FALSE; -} - -static gint -on_date_entry_key_release (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit) -{ - e_date_edit_check_date_changed (dedit); - return TRUE; -} - -static gint -on_time_entry_key_release (GtkWidget *widget, - GdkEvent *key_event, - EDateEdit *dedit) -{ - guint event_keyval = 0; - - gdk_event_get_keyval (key_event, &event_keyval); - - if (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down) { - g_signal_stop_emission_by_name (widget, "key_release_event"); - e_date_edit_check_time_changed (dedit); - return TRUE; - } - - return FALSE; -} - -static gint -on_date_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit) -{ - struct tm tmp_tm; - GtkWidget *msg_dialog; - - tmp_tm.tm_year = 0; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 0; - - e_date_edit_check_date_changed (dedit); - - if (!e_date_edit_date_is_valid (dedit)) { - msg_dialog = gtk_message_dialog_new ( - NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - "%s", _("Invalid Date Value")); - gtk_dialog_run (GTK_DIALOG (msg_dialog)); - gtk_widget_destroy (msg_dialog); - e_date_edit_get_date ( - dedit, &tmp_tm.tm_year, - &tmp_tm.tm_mon, &tmp_tm.tm_mday); - e_date_edit_set_date ( - dedit, tmp_tm.tm_year, - tmp_tm.tm_mon, tmp_tm.tm_mday); - gtk_widget_grab_focus (GTK_WIDGET (entry)); - return FALSE; - } else if (e_date_edit_get_date ( - dedit, &tmp_tm.tm_year, &tmp_tm.tm_mon, &tmp_tm.tm_mday)) { - - e_date_edit_set_date ( - dedit,tmp_tm.tm_year,tmp_tm.tm_mon,tmp_tm.tm_mday); - - if (dedit->priv->has_been_changed) { - /* The previous one didn't emit changed signal, - * but we want it even here, thus doing itself. */ - g_signal_emit (dedit, signals[CHANGED], 0); - dedit->priv->has_been_changed = FALSE; - } - } else { - dedit->priv->date_set_to_none = TRUE; - e_date_edit_update_date_entry (dedit); - } - return FALSE; -} - -static gint -on_time_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit) -{ - GtkWidget *msg_dialog; - - e_date_edit_check_time_changed (dedit); - - if (!e_date_edit_time_is_valid (dedit)) { - msg_dialog = gtk_message_dialog_new ( - NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - "%s", _("Invalid Time Value")); - gtk_dialog_run (GTK_DIALOG (msg_dialog)); - gtk_widget_destroy (msg_dialog); - e_date_edit_set_time (dedit,e_date_edit_get_time (dedit)); - gtk_widget_grab_focus (GTK_WIDGET (entry)); - return FALSE; - } - return FALSE; -} - -static void -add_relation (EDateEdit *dedit, - GtkWidget *widget) -{ - AtkObject *a11yEdit, *a11yWidget; - AtkRelationSet *set; - AtkRelation *relation; - GPtrArray *target; - gpointer target_object; - - /* add a labelled_by relation for widget for accessibility */ - - a11yEdit = gtk_widget_get_accessible (GTK_WIDGET (dedit)); - a11yWidget = gtk_widget_get_accessible (widget); - - set = atk_object_ref_relation_set (a11yWidget); - if (set != NULL) { - relation = atk_relation_set_get_relation_by_type ( - set, ATK_RELATION_LABELLED_BY); - /* check whether has a labelled_by relation already */ - if (relation != NULL) - return; - } - - set = atk_object_ref_relation_set (a11yEdit); - if (!set) - return; - - relation = atk_relation_set_get_relation_by_type ( - set, ATK_RELATION_LABELLED_BY); - if (relation != NULL) { - target = atk_relation_get_target (relation); - target_object = g_ptr_array_index (target, 0); - if (ATK_IS_OBJECT (target_object)) { - atk_object_add_relationship ( - a11yWidget, - ATK_RELATION_LABELLED_BY, - ATK_OBJECT (target_object)); - } - } -} - -/* This sets the text in the date entry according to the current settings. */ -static void -e_date_edit_update_date_entry (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - gchar buffer[100]; - struct tm tmp_tm = { 0 }; - - priv = dedit->priv; - - if (priv->date_set_to_none || !priv->date_is_valid) { - gtk_entry_set_text (GTK_ENTRY (priv->date_entry), C_("date", "None")); - } else { - /* This is a strftime() format for a short date. - * %x the preferred date representation for the current locale - * without the time, but is forced to use 4 digit year. */ - gchar *format = e_time_get_d_fmt_with_4digit_year (); - time_t tt; - - tmp_tm.tm_year = priv->year; - tmp_tm.tm_mon = priv->month; - tmp_tm.tm_mday = priv->day; - tmp_tm.tm_isdst = -1; - - /* initialize all 'struct tm' members properly */ - tt = mktime (&tmp_tm); - if (tt && localtime (&tt)) - tmp_tm = *localtime (&tt); - - e_utf8_strftime (buffer, sizeof (buffer), format, &tmp_tm); - g_free (format); - gtk_entry_set_text (GTK_ENTRY (priv->date_entry), buffer); - } - - add_relation (dedit, priv->date_entry); - add_relation (dedit, priv->date_button); -} - -/* This sets the text in the time entry according to the current settings. */ -static void -e_date_edit_update_time_entry (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - GtkComboBox *combo_box; - GtkWidget *child; - gchar buffer[40]; - struct tm tmp_tm = { 0 }; - - priv = dedit->priv; - - combo_box = GTK_COMBO_BOX (priv->time_combo); - child = gtk_bin_get_child (GTK_BIN (priv->time_combo)); - - if (priv->time_set_to_none || !priv->time_is_valid) { - gtk_combo_box_set_active (combo_box, -1); - gtk_entry_set_text (GTK_ENTRY (child), ""); - } else { - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid; - gchar *b; - - /* Set these to reasonable values just in case. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - - tmp_tm.tm_hour = priv->hour; - tmp_tm.tm_min = priv->minute; - - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = -1; - - if (priv->use_24_hour_format) - /* This is a strftime() format. - * %H = hour (0-23), %M = minute. */ - e_time_format_time ( - &tmp_tm, 1, 0, buffer, sizeof (buffer)); - else - /* This is a strftime() format. - * %I = hour (1-12), %M = minute, %p = am/pm. */ - e_time_format_time ( - &tmp_tm, 0, 0, buffer, sizeof (buffer)); - - /* For 12-hour am/pm format, we want space padding, not - * zero padding. This can be done with strftime's %l, - * but it's a potentially unportable extension. */ - if (!priv->use_24_hour_format && buffer[0] == '0') - buffer[0] = ' '; - - gtk_entry_set_text (GTK_ENTRY (child), buffer); - - /* truncate left spaces */ - b = buffer; - while (*b == ' ') - b++; - - model = gtk_combo_box_get_model (combo_box); - valid = gtk_tree_model_get_iter_first (model, &iter); - - while (valid) { - gchar *text = NULL; - - gtk_tree_model_get (model, &iter, 0, &text, -1); - if (text) { - gchar *t = text; - - /* truncate left spaces */ - while (*t == ' ') - t++; - - if (strcmp (b, t) == 0) { - gtk_combo_box_set_active_iter ( - combo_box, &iter); - g_free (text); - break; - } - } - - g_free (text); - - valid = gtk_tree_model_iter_next (model, &iter); - } - } - - add_relation (dedit, priv->time_combo); -} - -static void -e_date_edit_update_time_combo_state (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - gboolean show = TRUE, show_now_button = TRUE; - gboolean clear_entry = FALSE, sensitive = TRUE; - const gchar *text; - - priv = dedit->priv; - - /* If the date entry is currently shown, and it is set to None, - * clear the time entry and disable the time combo. */ - if (priv->show_date && priv->date_set_to_none) { - clear_entry = TRUE; - sensitive = FALSE; - } - - if (!priv->show_time) { - if (priv->make_time_insensitive) { - clear_entry = TRUE; - sensitive = FALSE; - } else { - show = FALSE; - } - - show_now_button = FALSE; - } - - if (clear_entry) { - GtkWidget *child; - - /* Only clear it if it isn't empty already. */ - child = gtk_bin_get_child (GTK_BIN (priv->time_combo)); - text = gtk_entry_get_text (GTK_ENTRY (child)); - if (text[0]) - gtk_entry_set_text (GTK_ENTRY (child), ""); - } - - gtk_widget_set_sensitive (priv->time_combo, sensitive); - - if (show) - gtk_widget_show (priv->time_combo); - else - gtk_widget_hide (priv->time_combo); - - if (show_now_button) - gtk_widget_show (priv->now_button); - else - gtk_widget_hide (priv->now_button); - - if (priv->show_date - && (priv->show_time || priv->make_time_insensitive)) - gtk_widget_show (priv->space); - else - gtk_widget_hide (priv->space); -} - -/* Parses the date, and if it is different from the current settings it - * updates the settings and emits a "date_changed" signal. */ -static void -e_date_edit_check_date_changed (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - const gchar *date_text; - struct tm tmp_tm; - gboolean none = FALSE, valid = TRUE, date_changed = FALSE; - - priv = dedit->priv; - - tmp_tm.tm_year = 0; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 0; - - date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry)); - if (field_set_to_none (date_text)) { - none = TRUE; - } else if (!e_date_edit_parse_date (dedit, date_text, &tmp_tm)) { - valid = FALSE; - tmp_tm.tm_year = 0; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 0; - } - - date_changed = e_date_edit_set_date_internal ( - dedit, valid, none, - tmp_tm.tm_year, - tmp_tm.tm_mon, - tmp_tm.tm_mday); - - if (date_changed) { - priv->has_been_changed = TRUE; - g_signal_emit (dedit, signals[CHANGED], 0); - } -} - -/* Parses the time, and if it is different from the current settings it - * updates the settings and emits a "time_changed" signal. */ -static void -e_date_edit_check_time_changed (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - GtkWidget *child; - const gchar *time_text; - struct tm tmp_tm; - gboolean none = FALSE, valid = TRUE, time_changed; - - priv = dedit->priv; - - tmp_tm.tm_hour = 0; - tmp_tm.tm_min = 0; - - child = gtk_bin_get_child (GTK_BIN (priv->time_combo)); - time_text = gtk_entry_get_text (GTK_ENTRY (child)); - if (field_set_to_none (time_text)) - none = TRUE; - else if (!e_date_edit_parse_time (dedit, time_text, &tmp_tm)) - valid = FALSE; - - time_changed = e_date_edit_set_time_internal ( - dedit, valid, none, - tmp_tm.tm_hour, - tmp_tm.tm_min); - - if (time_changed) { - e_date_edit_update_time_entry (dedit); - g_signal_emit (dedit, signals[CHANGED], 0); - } -} - -/** - * e_date_edit_date_is_valid: - * @dedit: an #EDateEdit widget. - * @Returns: TRUE if the last date entered was valid. - * - * Returns TRUE if the last date entered was valid. - * - * Note that if this returns FALSE, you can still use e_date_edit_get_time() - * or e_date_edit_get_date() to get the last time or date entered which was - * valid. - */ -gboolean -e_date_edit_date_is_valid (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - if (!dedit->priv->date_is_valid) - return FALSE; - - /* If the date is empty/None and that isn't permitted, return FALSE. */ - if (dedit->priv->date_set_to_none - && !e_date_edit_get_allow_no_date_set (dedit)) - return FALSE; - - return TRUE; -} - -/** - * e_date_edit_time_is_valid: - * @dedit: an #EDateEdit widget. - * @Returns: TRUE if the last time entered was valid. - * - * Returns TRUE if the last time entered was valid. - * - * Note that if this returns FALSE, you can still use e_date_edit_get_time() - * or e_date_edit_get_time_of_day() to get the last time or time of the day - * entered which was valid. - */ -gboolean -e_date_edit_time_is_valid (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - if (!dedit->priv->time_is_valid) - return FALSE; - - /* If the time is empty and that isn't permitted, return FALSE. - * Note that we don't mind an empty time if the date field is shown - * - in that case we just assume 0:00. */ - if (dedit->priv->time_set_to_none && !dedit->priv->show_date - && !e_date_edit_get_allow_no_date_set (dedit)) - return FALSE; - - return TRUE; -} - -static gboolean -e_date_edit_set_date_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint year, - gint month, - gint day) -{ - EDateEditPrivate *priv; - gboolean date_changed = FALSE; - - priv = dedit->priv; - - if (!valid) { - /* Date is invalid. */ - if (priv->date_is_valid) { - priv->date_is_valid = FALSE; - date_changed = TRUE; - } - } else if (none) { - /* Date has been set to 'None'. */ - if (!priv->date_is_valid - || !priv->date_set_to_none) { - priv->date_is_valid = TRUE; - priv->date_set_to_none = TRUE; - date_changed = TRUE; - } - } else { - /* Date has been set to a specific date. */ - if (!priv->date_is_valid - || priv->date_set_to_none - || priv->year != year - || priv->month != month - || priv->day != day) { - priv->date_is_valid = TRUE; - priv->date_set_to_none = FALSE; - priv->year = year; - priv->month = month; - priv->day = day; - date_changed = TRUE; - } - } - - return date_changed; -} - -static gboolean -e_date_edit_set_time_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint hour, - gint minute) -{ - EDateEditPrivate *priv; - gboolean time_changed = FALSE; - - priv = dedit->priv; - - if (!valid) { - /* Time is invalid. */ - if (priv->time_is_valid) { - priv->time_is_valid = FALSE; - time_changed = TRUE; - } - } else if (none) { - /* Time has been set to empty/'None'. */ - if (!priv->time_is_valid - || !priv->time_set_to_none) { - priv->time_is_valid = TRUE; - priv->time_set_to_none = TRUE; - time_changed = TRUE; - } - } else { - /* Time has been set to a specific time. */ - if (!priv->time_is_valid - || priv->time_set_to_none - || priv->hour != hour - || priv->minute != minute) { - priv->time_is_valid = TRUE; - priv->time_set_to_none = FALSE; - priv->hour = hour; - priv->minute = minute; - time_changed = TRUE; - } - } - - return time_changed; -} - -gboolean -e_date_edit_get_twodigit_year_can_future (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - return dedit->priv->twodigit_year_can_future; -} - -void -e_date_edit_set_twodigit_year_can_future (EDateEdit *dedit, - gboolean value) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - dedit->priv->twodigit_year_can_future = value; -} - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void -e_date_edit_set_get_time_callback (EDateEdit *dedit, - EDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->time_callback_data && priv->time_callback_destroy) - (*priv->time_callback_destroy) (priv->time_callback_data); - - priv->time_callback = cb; - priv->time_callback_data = data; - priv->time_callback_destroy = destroy; - -} - -GtkWidget * -e_date_edit_get_entry (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), NULL); - - return GTK_WIDGET (dedit->priv->date_entry); -} diff --git a/widgets/misc/e-dateedit.h b/widgets/misc/e-dateedit.h deleted file mode 100644 index 7da72ec975..0000000000 --- a/widgets/misc/e-dateedit.h +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Based on the GnomeDateEdit, part of the Gnome Library. - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 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 - */ - -/* - * EDateEdit - a widget based on GnomeDateEdit to provide a date & optional - * time field with popups for entering a date. - * - * It emits a "changed" signal when the date and/or time has changed. - * You can check if the last date or time entered was invalid by - * calling e_date_edit_date_is_valid() and e_date_edit_time_is_valid(). - * - * Note that when the user types in a date or time, it will only emit the - * signals when the user presses the return key or switches the keyboard - * focus to another widget, or you call one of the _get_time/date functions. - */ - -#ifndef E_DATE_EDIT_H -#define E_DATE_EDIT_H - -#include <time.h> -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_DATE_EDIT \ - (e_date_edit_get_type ()) -#define E_DATE_EDIT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_DATE_EDIT, EDateEdit)) -#define E_DATE_EDIT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_DATE_EDIT, EDateEditClass)) -#define E_IS_DATE_EDIT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_DATE_EDIT)) -#define E_IS_DATE_EDIT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_DATE_EDIT)) -#define E_DATE_EDIT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_DATE_EDIT, EDateEditClass)) - -G_BEGIN_DECLS - -typedef struct _EDateEdit EDateEdit; -typedef struct _EDateEditClass EDateEditClass; -typedef struct _EDateEditPrivate EDateEditPrivate; - -/* The type of the callback function optionally used to get the current time. - */ -typedef struct tm (*EDateEditGetTimeCallback) - (EDateEdit *dedit, - gpointer data); - -struct _EDateEdit { - GtkBox hbox; - EDateEditPrivate *priv; -}; - -struct _EDateEditClass { - GtkBoxClass parent_class; - - /* Signals */ - void (*changed) (EDateEdit *dedit); -}; - -GType e_date_edit_get_type (void); -GtkWidget * e_date_edit_new (void); - -/* Analogous to gtk_editable_set_editable. disable editing, while still - * allowing selection. */ -void e_date_edit_set_editable (EDateEdit *dedit, - gboolean editable); - -/* Returns TRUE if the last date and time set were valid. The date and time - * are only set when the user hits Return or switches keyboard focus, or - * selects a date or time from the popup. */ -gboolean e_date_edit_date_is_valid (EDateEdit *dedit); -gboolean e_date_edit_time_is_valid (EDateEdit *dedit); - -/* Returns the last valid date & time set, or -1 if the date & time was set to - * 'None' and this is permitted via e_date_edit_set_allow_no_date_set. */ -time_t e_date_edit_get_time (EDateEdit *dedit); -void e_date_edit_set_time (EDateEdit *dedit, - time_t the_time); - -/* This returns the last valid date set, without the time. It returns TRUE - * if a date is set, or FALSE if the date is set to 'None' and this is - * permitted via e_date_edit_set_allow_no_date_set. (Month is 1 - 12). */ -gboolean e_date_edit_get_date (EDateEdit *dedit, - gint *year, - gint *month, - gint *day); -void e_date_edit_set_date (EDateEdit *dedit, - gint year, - gint month, - gint day); - -/* This returns the last valid time set, without the date. It returns TRUE - * if a time is set, or FALSE if the time is set to 'None' and this is - * permitted via e_date_edit_set_allow_no_date_set. */ -gboolean e_date_edit_get_time_of_day (EDateEdit *dedit, - gint *hour, - gint *minute); -/* Set the time. Pass -1 as hour to set to empty. */ -void e_date_edit_set_time_of_day (EDateEdit *dedit, - gint hour, - gint minute); - -void e_date_edit_set_date_and_time_of_day - (EDateEdit *dedit, - gint year, - gint month, - gint day, - gint hour, - gint minute); - -/* Whether we show the date field. */ -gboolean e_date_edit_get_show_date (EDateEdit *dedit); -void e_date_edit_set_show_date (EDateEdit *dedit, - gboolean show_date); - -/* Whether we show the time field. */ -gboolean e_date_edit_get_show_time (EDateEdit *dedit); -void e_date_edit_set_show_time (EDateEdit *dedit, - gboolean show_time); - -/* The week start day, used in the date popup. 0 (Mon) to 6 (Sun). */ -gint e_date_edit_get_week_start_day (EDateEdit *dedit); -void e_date_edit_set_week_start_day (EDateEdit *dedit, - gint week_start_day); - -/* Whether we show week numbers in the date popup. */ -gboolean e_date_edit_get_show_week_numbers - (EDateEdit *dedit); -void e_date_edit_set_show_week_numbers - (EDateEdit *dedit, - gboolean show_week_numbers); - -/* Whether we use 24 hour format in the time field & popup. */ -gboolean e_date_edit_get_use_24_hour_format - (EDateEdit *dedit); -void e_date_edit_set_use_24_hour_format - (EDateEdit *dedit, - gboolean use_24_hour_format); - -/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will - * return (time_t) -1 in this case. */ -gboolean e_date_edit_get_allow_no_date_set - (EDateEdit *dedit); -void e_date_edit_set_allow_no_date_set - (EDateEdit *dedit, - gboolean allow_no_date_set); - -/* The range of time to show in the time combo popup. */ -void e_date_edit_get_time_popup_range - (EDateEdit *dedit, - gint *lower_hour, - gint *upper_hour); -void e_date_edit_set_time_popup_range - (EDateEdit *dedit, - gint lower_hour, - gint upper_hour); - -/* Whether the time field is made insensitive rather than hiding it. */ -gboolean e_date_edit_get_make_time_insensitive - (EDateEdit *dedit); -void e_date_edit_set_make_time_insensitive - (EDateEdit *dedit, - gboolean make_insensitive); - -/* Whether two-digit years in date could be modified as in future; default is TRUE */ -gboolean e_date_edit_get_twodigit_year_can_future - (EDateEdit *dedit); -void e_date_edit_set_twodigit_year_can_future - (EDateEdit *dedit, - gboolean value); - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void e_date_edit_set_get_time_callback - (EDateEdit *dedit, - EDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy); - -GtkWidget * e_date_edit_get_entry (EDateEdit *dedit); - -G_END_DECLS - -#endif /* E_DATE_EDIT_H */ diff --git a/widgets/misc/e-focus-tracker.c b/widgets/misc/e-focus-tracker.c deleted file mode 100644 index 505d991a2f..0000000000 --- a/widgets/misc/e-focus-tracker.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - * e-focus-tracker.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-focus-tracker.h" - -#include <glib/gi18n-lib.h> - -#include <misc/e-selectable.h> - -#define E_FOCUS_TRACKER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_FOCUS_TRACKER, EFocusTrackerPrivate)) - -struct _EFocusTrackerPrivate { - GtkWidget *focus; /* not referenced */ - GtkWindow *window; - - GtkAction *cut_clipboard; - GtkAction *copy_clipboard; - GtkAction *paste_clipboard; - GtkAction *delete_selection; - GtkAction *select_all; -}; - -enum { - PROP_0, - PROP_FOCUS, - PROP_WINDOW, - PROP_CUT_CLIPBOARD_ACTION, - PROP_COPY_CLIPBOARD_ACTION, - PROP_PASTE_CLIPBOARD_ACTION, - PROP_DELETE_SELECTION_ACTION, - PROP_SELECT_ALL_ACTION -}; - -G_DEFINE_TYPE ( - EFocusTracker, - e_focus_tracker, - G_TYPE_OBJECT) - -static void -focus_tracker_disable_actions (EFocusTracker *focus_tracker) -{ - GtkAction *action; - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - if (action != NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - if (action != NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - if (action != NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_delete_selection_action (focus_tracker); - if (action != NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_select_all_action (focus_tracker); - if (action != NULL) - gtk_action_set_sensitive (action, FALSE); -} - -static void -focus_tracker_editable_update_actions (EFocusTracker *focus_tracker, - GtkEditable *editable, - GdkAtom *targets, - gint n_targets) -{ - GtkAction *action; - gboolean can_edit_text; - gboolean clipboard_has_text; - gboolean text_is_selected; - gboolean sensitive; - - can_edit_text = - gtk_editable_get_editable (editable); - - clipboard_has_text = (targets != NULL) && - gtk_targets_include_text (targets, n_targets); - - text_is_selected = - gtk_editable_get_selection_bounds (editable, NULL, NULL); - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - if (action != NULL) { - sensitive = can_edit_text && text_is_selected; - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, _("Cut the selection")); - } - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - if (action != NULL) { - sensitive = text_is_selected; - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, _("Copy the selection")); - } - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - if (action != NULL) { - sensitive = can_edit_text && clipboard_has_text; - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, _("Paste the clipboard")); - } - - action = e_focus_tracker_get_delete_selection_action (focus_tracker); - if (action != NULL) { - sensitive = can_edit_text && text_is_selected; - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, _("Delete the selection")); - } - - action = e_focus_tracker_get_select_all_action (focus_tracker); - if (action != NULL) { - sensitive = TRUE; /* always enabled */ - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, _("Select all text")); - } -} - -static void -focus_tracker_selectable_update_actions (EFocusTracker *focus_tracker, - ESelectable *selectable, - GdkAtom *targets, - gint n_targets) -{ - ESelectableInterface *interface; - GtkAction *action; - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - e_selectable_update_actions ( - selectable, focus_tracker, targets, n_targets); - - /* Disable actions for which the corresponding method is not - * implemented. This allows update_actions() implementations - * to simply skip the actions they don't support, which in turn - * allows us to add new actions without disturbing the existing - * ESelectable implementations. */ - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - if (action != NULL && interface->cut_clipboard == NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - if (action != NULL && interface->copy_clipboard == NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - if (action != NULL && interface->paste_clipboard == NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_delete_selection_action (focus_tracker); - if (action != NULL && interface->delete_selection == NULL) - gtk_action_set_sensitive (action, FALSE); - - action = e_focus_tracker_get_select_all_action (focus_tracker); - if (action != NULL && interface->select_all == NULL) - gtk_action_set_sensitive (action, FALSE); -} - -static void -focus_tracker_targets_received_cb (GtkClipboard *clipboard, - GdkAtom *targets, - gint n_targets, - EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (focus == NULL) - focus_tracker_disable_actions (focus_tracker); - - else if (GTK_IS_EDITABLE (focus)) - focus_tracker_editable_update_actions ( - focus_tracker, GTK_EDITABLE (focus), - targets, n_targets); - - else if (E_IS_SELECTABLE (focus)) - focus_tracker_selectable_update_actions ( - focus_tracker, E_SELECTABLE (focus), - targets, n_targets); - - g_object_unref (focus_tracker); -} - -static void -focus_tracker_set_focus_cb (GtkWindow *window, - GtkWidget *focus, - EFocusTracker *focus_tracker) -{ - while (focus != NULL) { - if (GTK_IS_EDITABLE (focus)) - break; - - if (E_IS_SELECTABLE (focus)) - break; - - focus = gtk_widget_get_parent (focus); - } - - if (focus == focus_tracker->priv->focus) - return; - - focus_tracker->priv->focus = focus; - g_object_notify (G_OBJECT (focus_tracker), "focus"); - - e_focus_tracker_update_actions (focus_tracker); -} - -static void -focus_tracker_set_window (EFocusTracker *focus_tracker, - GtkWindow *window) -{ - g_return_if_fail (GTK_IS_WINDOW (window)); - g_return_if_fail (focus_tracker->priv->window == NULL); - - focus_tracker->priv->window = g_object_ref (window); - - g_signal_connect ( - window, "set-focus", - G_CALLBACK (focus_tracker_set_focus_cb), focus_tracker); -} - -static void -focus_tracker_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_WINDOW: - focus_tracker_set_window ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - - case PROP_CUT_CLIPBOARD_ACTION: - e_focus_tracker_set_cut_clipboard_action ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - - case PROP_COPY_CLIPBOARD_ACTION: - e_focus_tracker_set_copy_clipboard_action ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - - case PROP_PASTE_CLIPBOARD_ACTION: - e_focus_tracker_set_paste_clipboard_action ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - - case PROP_DELETE_SELECTION_ACTION: - e_focus_tracker_set_delete_selection_action ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - - case PROP_SELECT_ALL_ACTION: - e_focus_tracker_set_select_all_action ( - E_FOCUS_TRACKER (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -focus_tracker_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_FOCUS: - g_value_set_object ( - value, - e_focus_tracker_get_focus ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_WINDOW: - g_value_set_object ( - value, - e_focus_tracker_get_window ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_CUT_CLIPBOARD_ACTION: - g_value_set_object ( - value, - e_focus_tracker_get_cut_clipboard_action ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_COPY_CLIPBOARD_ACTION: - g_value_set_object ( - value, - e_focus_tracker_get_copy_clipboard_action ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_PASTE_CLIPBOARD_ACTION: - g_value_set_object ( - value, - e_focus_tracker_get_paste_clipboard_action ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_DELETE_SELECTION_ACTION: - g_value_set_object ( - value, - e_focus_tracker_get_delete_selection_action ( - E_FOCUS_TRACKER (object))); - return; - - case PROP_SELECT_ALL_ACTION: - g_value_set_object ( - value, - e_focus_tracker_get_select_all_action ( - E_FOCUS_TRACKER (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -focus_tracker_dispose (GObject *object) -{ - EFocusTrackerPrivate *priv; - - priv = E_FOCUS_TRACKER_GET_PRIVATE (object); - - g_signal_handlers_disconnect_matched ( - gtk_clipboard_get (GDK_SELECTION_PRIMARY), - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, object); - - g_signal_handlers_disconnect_matched ( - gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, object); - - if (priv->window != NULL) { - g_signal_handlers_disconnect_matched ( - priv->window, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->window); - priv->window = NULL; - } - - if (priv->cut_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - priv->cut_clipboard, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->cut_clipboard); - priv->cut_clipboard = NULL; - } - - if (priv->copy_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - priv->copy_clipboard, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->copy_clipboard); - priv->copy_clipboard = NULL; - } - - if (priv->paste_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - priv->paste_clipboard, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->paste_clipboard); - priv->paste_clipboard = NULL; - } - - if (priv->delete_selection != NULL) { - g_signal_handlers_disconnect_matched ( - priv->delete_selection, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->delete_selection); - priv->delete_selection = NULL; - } - - if (priv->select_all != NULL) { - g_signal_handlers_disconnect_matched ( - priv->select_all, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->select_all); - priv->select_all = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_focus_tracker_parent_class)->dispose (object); -} - -static void -focus_tracker_constructed (GObject *object) -{ - GtkClipboard *clipboard; - - /* Listen for "owner-change" signals from the primary selection - * clipboard to learn when text selections change in GtkEditable - * widgets. It's a bit of an overkill, but I don't know of any - * other notification mechanism. */ - - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); - - g_signal_connect_swapped ( - clipboard, "owner-change", - G_CALLBACK (e_focus_tracker_update_actions), object); - - /* Listen for "owner-change" signals from the default clipboard - * so we can update the paste action when the user cuts or copies - * something. This is how GEdit does it. */ - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - - g_signal_connect_swapped ( - clipboard, "owner-change", - G_CALLBACK (e_focus_tracker_update_actions), object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_focus_tracker_parent_class)->constructed (object); -} - -static void -e_focus_tracker_class_init (EFocusTrackerClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EFocusTrackerPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = focus_tracker_set_property; - object_class->get_property = focus_tracker_get_property; - object_class->dispose = focus_tracker_dispose; - object_class->constructed = focus_tracker_constructed; - - g_object_class_install_property ( - object_class, - PROP_FOCUS, - g_param_spec_object ( - "focus", - "Focus", - NULL, - GTK_TYPE_WIDGET, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_WINDOW, - g_param_spec_object ( - "window", - "Window", - NULL, - GTK_TYPE_WINDOW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property ( - object_class, - PROP_CUT_CLIPBOARD_ACTION, - g_param_spec_object ( - "cut-clipboard-action", - "Cut Clipboard Action", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_COPY_CLIPBOARD_ACTION, - g_param_spec_object ( - "copy-clipboard-action", - "Copy Clipboard Action", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_PASTE_CLIPBOARD_ACTION, - g_param_spec_object ( - "paste-clipboard-action", - "Paste Clipboard Action", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_DELETE_SELECTION_ACTION, - g_param_spec_object ( - "delete-selection-action", - "Delete Selection Action", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SELECT_ALL_ACTION, - g_param_spec_object ( - "select-all-action", - "Select All Action", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); -} - -static void -e_focus_tracker_init (EFocusTracker *focus_tracker) -{ - GtkAction *action; - - focus_tracker->priv = E_FOCUS_TRACKER_GET_PRIVATE (focus_tracker); - - /* Define dummy actions. These will most likely be overridden, - * but for cases where they're not it ensures ESelectable objects - * will always get a valid GtkAction when they ask us for one. */ - - action = gtk_action_new ( - "cut-clipboard", NULL, - _("Cut the selection"), GTK_STOCK_CUT); - focus_tracker->priv->cut_clipboard = action; - - action = gtk_action_new ( - "copy-clipboard", NULL, - _("Copy the selection"), GTK_STOCK_COPY); - focus_tracker->priv->copy_clipboard = action; - - action = gtk_action_new ( - "paste-clipboard", NULL, - _("Paste the clipboard"), GTK_STOCK_PASTE); - focus_tracker->priv->paste_clipboard = action; - - action = gtk_action_new ( - "delete-selection", NULL, - _("Delete the selection"), GTK_STOCK_DELETE); - focus_tracker->priv->delete_selection = action; - - action = gtk_action_new ( - "select-all", NULL, - _("Select all text"), GTK_STOCK_SELECT_ALL); - focus_tracker->priv->select_all = action; -} - -EFocusTracker * -e_focus_tracker_new (GtkWindow *window) -{ - g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); - - return g_object_new (E_TYPE_FOCUS_TRACKER, "window", window, NULL); -} - -GtkWidget * -e_focus_tracker_get_focus (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->focus; -} - -GtkWindow * -e_focus_tracker_get_window (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->window; -} - -GtkAction * -e_focus_tracker_get_cut_clipboard_action (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->cut_clipboard; -} - -void -e_focus_tracker_set_cut_clipboard_action (EFocusTracker *focus_tracker, - GtkAction *cut_clipboard) -{ - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - if (cut_clipboard != NULL) { - g_return_if_fail (GTK_IS_ACTION (cut_clipboard)); - g_object_ref (cut_clipboard); - } - - if (focus_tracker->priv->cut_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - focus_tracker->priv->cut_clipboard, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - focus_tracker); - g_object_unref (focus_tracker->priv->cut_clipboard); - } - - focus_tracker->priv->cut_clipboard = cut_clipboard; - - if (cut_clipboard != NULL) - g_signal_connect_swapped ( - cut_clipboard, "activate", - G_CALLBACK (e_focus_tracker_cut_clipboard), - focus_tracker); - - g_object_notify (G_OBJECT (focus_tracker), "cut-clipboard-action"); -} - -GtkAction * -e_focus_tracker_get_copy_clipboard_action (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->copy_clipboard; -} - -void -e_focus_tracker_set_copy_clipboard_action (EFocusTracker *focus_tracker, - GtkAction *copy_clipboard) -{ - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - if (copy_clipboard != NULL) { - g_return_if_fail (GTK_IS_ACTION (copy_clipboard)); - g_object_ref (copy_clipboard); - } - - if (focus_tracker->priv->copy_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - focus_tracker->priv->copy_clipboard, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - focus_tracker); - g_object_unref (focus_tracker->priv->copy_clipboard); - } - - focus_tracker->priv->copy_clipboard = copy_clipboard; - - if (copy_clipboard != NULL) - g_signal_connect_swapped ( - copy_clipboard, "activate", - G_CALLBACK (e_focus_tracker_copy_clipboard), - focus_tracker); - - g_object_notify (G_OBJECT (focus_tracker), "copy-clipboard-action"); -} - -GtkAction * -e_focus_tracker_get_paste_clipboard_action (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->paste_clipboard; -} - -void -e_focus_tracker_set_paste_clipboard_action (EFocusTracker *focus_tracker, - GtkAction *paste_clipboard) -{ - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - if (paste_clipboard != NULL) { - g_return_if_fail (GTK_IS_ACTION (paste_clipboard)); - g_object_ref (paste_clipboard); - } - - if (focus_tracker->priv->paste_clipboard != NULL) { - g_signal_handlers_disconnect_matched ( - focus_tracker->priv->paste_clipboard, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - focus_tracker); - g_object_unref (focus_tracker->priv->paste_clipboard); - } - - focus_tracker->priv->paste_clipboard = paste_clipboard; - - if (paste_clipboard != NULL) - g_signal_connect_swapped ( - paste_clipboard, "activate", - G_CALLBACK (e_focus_tracker_paste_clipboard), - focus_tracker); - - g_object_notify (G_OBJECT (focus_tracker), "paste-clipboard-action"); -} - -GtkAction * -e_focus_tracker_get_delete_selection_action (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->delete_selection; -} - -void -e_focus_tracker_set_delete_selection_action (EFocusTracker *focus_tracker, - GtkAction *delete_selection) -{ - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - if (delete_selection != NULL) { - g_return_if_fail (GTK_IS_ACTION (delete_selection)); - g_object_ref (delete_selection); - } - - if (focus_tracker->priv->delete_selection != NULL) { - g_signal_handlers_disconnect_matched ( - focus_tracker->priv->delete_selection, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - focus_tracker); - g_object_unref (focus_tracker->priv->delete_selection); - } - - focus_tracker->priv->delete_selection = delete_selection; - - if (delete_selection != NULL) - g_signal_connect_swapped ( - delete_selection, "activate", - G_CALLBACK (e_focus_tracker_delete_selection), - focus_tracker); - - g_object_notify (G_OBJECT (focus_tracker), "delete-selection-action"); -} - -GtkAction * -e_focus_tracker_get_select_all_action (EFocusTracker *focus_tracker) -{ - g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); - - return focus_tracker->priv->select_all; -} - -void -e_focus_tracker_set_select_all_action (EFocusTracker *focus_tracker, - GtkAction *select_all) -{ - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - if (select_all != NULL) { - g_return_if_fail (GTK_IS_ACTION (select_all)); - g_object_ref (select_all); - } - - if (focus_tracker->priv->select_all != NULL) { - g_signal_handlers_disconnect_matched ( - focus_tracker->priv->select_all, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - focus_tracker); - g_object_unref (focus_tracker->priv->select_all); - } - - focus_tracker->priv->select_all = select_all; - - if (select_all != NULL) - g_signal_connect_swapped ( - select_all, "activate", - G_CALLBACK (e_focus_tracker_select_all), - focus_tracker); - - g_object_notify (G_OBJECT (focus_tracker), "select-all-action"); -} - -void -e_focus_tracker_update_actions (EFocusTracker *focus_tracker) -{ - GtkClipboard *clipboard; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - /* Request clipboard targets asynchronously. */ - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - - gtk_clipboard_request_targets ( - clipboard, (GtkClipboardTargetsReceivedFunc) - focus_tracker_targets_received_cb, - g_object_ref (focus_tracker)); -} - -void -e_focus_tracker_cut_clipboard (EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (GTK_IS_EDITABLE (focus)) - gtk_editable_cut_clipboard (GTK_EDITABLE (focus)); - - else if (E_IS_SELECTABLE (focus)) - e_selectable_cut_clipboard (E_SELECTABLE (focus)); -} - -void -e_focus_tracker_copy_clipboard (EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (GTK_IS_EDITABLE (focus)) - gtk_editable_copy_clipboard (GTK_EDITABLE (focus)); - - else if (E_IS_SELECTABLE (focus)) - e_selectable_copy_clipboard (E_SELECTABLE (focus)); -} - -void -e_focus_tracker_paste_clipboard (EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (GTK_IS_EDITABLE (focus)) - gtk_editable_paste_clipboard (GTK_EDITABLE (focus)); - - else if (E_IS_SELECTABLE (focus)) - e_selectable_paste_clipboard (E_SELECTABLE (focus)); -} - -void -e_focus_tracker_delete_selection (EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (GTK_IS_EDITABLE (focus)) - gtk_editable_delete_selection (GTK_EDITABLE (focus)); - - else if (E_IS_SELECTABLE (focus)) - e_selectable_delete_selection (E_SELECTABLE (focus)); -} - -void -e_focus_tracker_select_all (EFocusTracker *focus_tracker) -{ - GtkWidget *focus; - - g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); - - focus = e_focus_tracker_get_focus (focus_tracker); - - if (GTK_IS_EDITABLE (focus)) - gtk_editable_select_region (GTK_EDITABLE (focus), 0, -1); - - else if (E_IS_SELECTABLE (focus)) - e_selectable_select_all (E_SELECTABLE (focus)); -} diff --git a/widgets/misc/e-focus-tracker.h b/widgets/misc/e-focus-tracker.h deleted file mode 100644 index 86b206e240..0000000000 --- a/widgets/misc/e-focus-tracker.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * e-focus-tracker.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FOCUS_TRACKER_H -#define E_FOCUS_TRACKER_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_FOCUS_TRACKER \ - (e_focus_tracker_get_type ()) -#define E_FOCUS_TRACKER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FOCUS_TRACKER, EFocusTracker)) -#define E_FOCUS_TRACKER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FOCUS_TRACKER, EFocusTrackerClass)) -#define E_IS_FOCUS_TRACKER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FOCUS_TRACKER)) -#define E_IS_FOCUS_TRACKER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FOCUS_TRACKER)) -#define E_FOCUS_TRACKER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FOCUS_TRACKER, EFocusTrackerClass)) - -G_BEGIN_DECLS - -typedef struct _EFocusTracker EFocusTracker; -typedef struct _EFocusTrackerClass EFocusTrackerClass; -typedef struct _EFocusTrackerPrivate EFocusTrackerPrivate; - -struct _EFocusTracker { - GObject parent; - EFocusTrackerPrivate *priv; -}; - -struct _EFocusTrackerClass { - GObjectClass parent_class; -}; - -GType e_focus_tracker_get_type (void); -EFocusTracker * e_focus_tracker_new (GtkWindow *window); -GtkWidget * e_focus_tracker_get_focus (EFocusTracker *focus_tracker); -GtkWindow * e_focus_tracker_get_window (EFocusTracker *focus_tracker); -GtkAction * e_focus_tracker_get_cut_clipboard_action - (EFocusTracker *focus_tracker); -void e_focus_tracker_set_cut_clipboard_action - (EFocusTracker *focus_tracker, - GtkAction *cut_clipboard); -GtkAction * e_focus_tracker_get_copy_clipboard_action - (EFocusTracker *focus_tracker); -void e_focus_tracker_set_copy_clipboard_action - (EFocusTracker *focus_tracker, - GtkAction *copy_clipboard); -GtkAction * e_focus_tracker_get_paste_clipboard_action - (EFocusTracker *focus_tracker); -void e_focus_tracker_set_paste_clipboard_action - (EFocusTracker *focus_tracker, - GtkAction *paste_clipboard); -GtkAction * e_focus_tracker_get_delete_selection_action - (EFocusTracker *focus_tracker); -void e_focus_tracker_set_delete_selection_action - (EFocusTracker *focus_tracker, - GtkAction *delete_selection); -GtkAction * e_focus_tracker_get_select_all_action - (EFocusTracker *focus_tracker); -void e_focus_tracker_set_select_all_action - (EFocusTracker *focus_tracker, - GtkAction *select_all); -void e_focus_tracker_update_actions (EFocusTracker *focus_tracker); -void e_focus_tracker_cut_clipboard (EFocusTracker *focus_tracker); -void e_focus_tracker_copy_clipboard (EFocusTracker *focus_tracker); -void e_focus_tracker_paste_clipboard (EFocusTracker *focus_tracker); -void e_focus_tracker_delete_selection - (EFocusTracker *focus_tracker); -void e_focus_tracker_select_all (EFocusTracker *focus_tracker); - -G_END_DECLS - -#endif /* E_FOCUS_TRACKER_H */ diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c deleted file mode 100644 index 5fe6941d58..0000000000 --- a/widgets/misc/e-image-chooser.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * e-image-chooser.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include <glib/gi18n.h> - -#include "e-image-chooser.h" -#include "e-util/e-util.h" -#include "e-util/e-icon-factory.h" - -#define E_IMAGE_CHOOSER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserPrivate)) - -struct _EImageChooserPrivate { - GtkWidget *frame; - GtkWidget *image; - - gchar *image_buf; - gint image_buf_size; - gint image_width; - gint image_height; - - /* Default Image */ - gchar *icon_name; -}; - -enum { - PROP_0, - PROP_ICON_NAME -}; - -enum { - CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -#define URI_LIST_TYPE "text/uri-list" - -G_DEFINE_TYPE ( - EImageChooser, - e_image_chooser, - GTK_TYPE_VBOX) - -static gboolean -set_image_from_data (EImageChooser *chooser, - gchar *data, - gint length) -{ - GdkPixbufLoader *loader; - GdkPixbuf *pixbuf; - gfloat scale; - gint new_height; - gint new_width; - - loader = gdk_pixbuf_loader_new (); - gdk_pixbuf_loader_write (loader, (guchar *) data, length, NULL); - gdk_pixbuf_loader_close (loader, NULL); - - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf) - g_object_ref (pixbuf); - - g_object_unref (loader); - - if (pixbuf == NULL) - return FALSE; - - new_height = gdk_pixbuf_get_height (pixbuf); - new_width = gdk_pixbuf_get_width (pixbuf); - - if (chooser->priv->image_height == 0 - && chooser->priv->image_width == 0) { - scale = 1.0; - } else if (chooser->priv->image_height < new_height - || chooser->priv->image_width < new_width) { - /* we need to scale down */ - if (new_height > new_width) - scale = (gfloat) chooser->priv->image_height / new_height; - else - scale = (gfloat) chooser->priv->image_width / new_width; - } else { - /* we need to scale up */ - if (new_height > new_width) - scale = (gfloat) new_height / chooser->priv->image_height; - else - scale = (gfloat) new_width / chooser->priv->image_width; - } - - if (scale == 1.0) { - gtk_image_set_from_pixbuf ( - GTK_IMAGE (chooser->priv->image), pixbuf); - chooser->priv->image_width = new_width; - chooser->priv->image_height = new_height; - } else { - GdkPixbuf *scaled; - GdkPixbuf *composite; - - new_width *= scale; - new_height *= scale; - new_width = MIN (new_width, chooser->priv->image_width); - new_height = MIN (new_height, chooser->priv->image_height); - - scaled = gdk_pixbuf_scale_simple ( - pixbuf, new_width, new_height, - GDK_INTERP_BILINEAR); - - composite = gdk_pixbuf_new ( - GDK_COLORSPACE_RGB, TRUE, - gdk_pixbuf_get_bits_per_sample (pixbuf), - chooser->priv->image_width, - chooser->priv->image_height); - - gdk_pixbuf_fill (composite, 0x00000000); - - gdk_pixbuf_copy_area ( - scaled, 0, 0, new_width, new_height, - composite, - chooser->priv->image_width / 2 - new_width / 2, - chooser->priv->image_height / 2 - new_height / 2); - - gtk_image_set_from_pixbuf ( - GTK_IMAGE (chooser->priv->image), composite); - - g_object_unref (scaled); - g_object_unref (composite); - } - - g_object_unref (pixbuf); - - g_free (chooser->priv->image_buf); - chooser->priv->image_buf = data; - chooser->priv->image_buf_size = length; - - g_signal_emit (chooser, signals[CHANGED], 0); - - return TRUE; -} - -static gboolean -image_drag_motion_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EImageChooser *chooser) -{ - GtkFrame *frame; - GList *targets, *p; - - frame = GTK_FRAME (chooser->priv->frame); - targets = gdk_drag_context_list_targets (context); - - for (p = targets; p != NULL; p = p->next) { - gchar *possible_type; - - possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data)); - if (!strcmp (possible_type, URI_LIST_TYPE)) { - g_free (possible_type); - gdk_drag_status (context, GDK_ACTION_COPY, time); - gtk_frame_set_shadow_type (frame, GTK_SHADOW_IN); - return TRUE; - } - - g_free (possible_type); - } - - gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); - - return FALSE; -} - -static void -image_drag_leave_cb (GtkWidget *widget, - GdkDragContext *context, - guint time, - EImageChooser *chooser) -{ - GtkFrame *frame; - - frame = GTK_FRAME (chooser->priv->frame); - gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); -} - -static gboolean -image_drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EImageChooser *chooser) -{ - GtkFrame *frame; - GList *targets, *p; - - frame = GTK_FRAME (chooser->priv->frame); - targets = gdk_drag_context_list_targets (context); - - if (targets == NULL) { - gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); - return FALSE; - } - - for (p = targets; p != NULL; p = p->next) { - gchar *possible_type; - - possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data)); - if (!strcmp (possible_type, URI_LIST_TYPE)) { - g_free (possible_type); - gtk_drag_get_data ( - widget, context, - GDK_POINTER_TO_ATOM (p->data), time); - gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); - return TRUE; - } - - g_free (possible_type); - } - - gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); - - return FALSE; -} - -static void -image_chooser_file_loaded_cb (GFile *file, - GAsyncResult *result, - EImageChooser *chooser) -{ - gchar *contents; - gsize length; - GError *error = NULL; - - g_file_load_contents_finish ( - file, result, &contents, &length, NULL, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - goto exit; - } - - set_image_from_data (chooser, contents, length); - - g_free (contents); - -exit: - g_object_unref (chooser); -} - -static void -image_drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - EImageChooser *chooser) -{ - GFile *file; - gboolean handled = FALSE; - gchar **uris; - - uris = gtk_selection_data_get_uris (selection_data); - - if (uris == NULL) - goto exit; - - file = g_file_new_for_uri (uris[0]); - - /* XXX Not cancellable. */ - g_file_load_contents_async ( - file, NULL, (GAsyncReadyCallback) - image_chooser_file_loaded_cb, - g_object_ref (chooser)); - - g_object_unref (file); - g_strfreev (uris); - - /* Assume success. We won't know til later. */ - handled = TRUE; - -exit: - gtk_drag_finish (context, handled, FALSE, time); -} - -static void -image_chooser_set_icon_name (EImageChooser *chooser, - const gchar *icon_name) -{ - GtkIconTheme *icon_theme; - GtkIconInfo *icon_info; - const gchar *filename; - gint width, height; - - g_return_if_fail (chooser->priv->icon_name == NULL); - - chooser->priv->icon_name = g_strdup (icon_name); - - icon_theme = gtk_icon_theme_get_default (); - gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &width, &height); - - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, icon_name, height, 0); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - e_image_chooser_set_from_file (chooser, filename); - gtk_icon_info_free (icon_info); -} - -static void -image_chooser_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ICON_NAME: - image_chooser_set_icon_name ( - E_IMAGE_CHOOSER (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -image_chooser_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ICON_NAME: - g_value_set_string ( - value, - e_image_chooser_get_icon_name ( - E_IMAGE_CHOOSER (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -image_chooser_dispose (GObject *object) -{ - EImageChooserPrivate *priv; - - priv = E_IMAGE_CHOOSER_GET_PRIVATE (object); - - if (priv->frame != NULL) { - g_object_unref (priv->frame); - priv->frame = NULL; - } - - if (priv->image != NULL) { - g_object_unref (priv->image); - priv->image = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_image_chooser_parent_class)->dispose (object); -} - -static void -image_chooser_finalize (GObject *object) -{ - EImageChooserPrivate *priv; - - priv = E_IMAGE_CHOOSER_GET_PRIVATE (object); - - g_free (priv->image_buf); - g_free (priv->icon_name); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_image_chooser_parent_class)->finalize (object); -} - -static void -e_image_chooser_class_init (EImageChooserClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EImageChooserPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = image_chooser_set_property; - object_class->get_property = image_chooser_get_property; - object_class->dispose = image_chooser_dispose; - object_class->finalize = image_chooser_finalize; - - g_object_class_install_property ( - object_class, - PROP_ICON_NAME, - g_param_spec_string ( - "icon-name", - "Icon Name", - NULL, - "avatar-default", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EImageChooserClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_image_chooser_init (EImageChooser *chooser) -{ - GtkWidget *container; - GtkWidget *widget; - - chooser->priv = E_IMAGE_CHOOSER_GET_PRIVATE (chooser); - - container = GTK_WIDGET (chooser); - - widget = gtk_frame_new (""); - gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - chooser->priv->frame = g_object_ref (widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_alignment_new (0, 0, 0, 0); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new (); - gtk_container_add (GTK_CONTAINER (container), widget); - chooser->priv->image = g_object_ref (widget); - gtk_widget_show (widget); - - gtk_drag_dest_set (widget, 0, NULL, 0, GDK_ACTION_COPY); - gtk_drag_dest_add_uri_targets (widget); - - g_signal_connect ( - widget, "drag-motion", - G_CALLBACK (image_drag_motion_cb), chooser); - g_signal_connect ( - widget, "drag-leave", - G_CALLBACK (image_drag_leave_cb), chooser); - g_signal_connect ( - widget, "drag-drop", - G_CALLBACK (image_drag_drop_cb), chooser); - g_signal_connect ( - widget, "drag-data-received", - G_CALLBACK (image_drag_data_received_cb), chooser); -} - -const gchar * -e_image_chooser_get_icon_name (EImageChooser *chooser) -{ - g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), NULL); - - return chooser->priv->icon_name; -} - -GtkWidget * -e_image_chooser_new (const gchar *icon_name) -{ - g_return_val_if_fail (icon_name != NULL, NULL); - - return g_object_new ( - E_TYPE_IMAGE_CHOOSER, - "icon-name", icon_name, NULL); -} - -gboolean -e_image_chooser_set_from_file (EImageChooser *chooser, - const gchar *filename) -{ - gchar *data; - gsize data_length; - - g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - if (!g_file_get_contents (filename, &data, &data_length, NULL)) - return FALSE; - - if (!set_image_from_data (chooser, data, data_length)) - g_free (data); - - return TRUE; -} - -gboolean -e_image_chooser_get_image_data (EImageChooser *chooser, - gchar **data, - gsize *data_length) -{ - g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (data_length != NULL, FALSE); - - *data_length = chooser->priv->image_buf_size; - *data = g_malloc (*data_length); - memcpy (*data, chooser->priv->image_buf, *data_length); - - return TRUE; -} - -gboolean -e_image_chooser_set_image_data (EImageChooser *chooser, - gchar *data, - gsize data_length) -{ - gchar *buf; - - g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); - g_return_val_if_fail (data != NULL, FALSE); - - /* yuck, a copy... */ - buf = g_malloc (data_length); - memcpy (buf, data, data_length); - - if (!set_image_from_data (chooser, buf, data_length)) { - g_free (buf); - return FALSE; - } - - return TRUE; -} diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h deleted file mode 100644 index cf983c641d..0000000000 --- a/widgets/misc/e-image-chooser.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * e-image-chooser.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_IMAGE_CHOOSER_H -#define E_IMAGE_CHOOSER_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_IMAGE_CHOOSER \ - (e_image_chooser_get_type ()) -#define E_IMAGE_CHOOSER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser)) -#define E_IMAGE_CHOOSER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) -#define E_IS_IMAGE_CHOOSER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_IMAGE_CHOOSER)) -#define E_IS_IMAGE_CHOOSER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_IMAGE_CHOOSER)) -#define E_IMAGE_CHOOSER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) - -G_BEGIN_DECLS - -typedef struct _EImageChooser EImageChooser; -typedef struct _EImageChooserClass EImageChooserClass; -typedef struct _EImageChooserPrivate EImageChooserPrivate; - -struct _EImageChooser { - GtkBox parent; - EImageChooserPrivate *priv; -}; - -struct _EImageChooserClass { - GtkBoxClass parent_class; - - /* signals */ - void (*changed) (EImageChooser *chooser); -}; - -GType e_image_chooser_get_type (void); -GtkWidget * e_image_chooser_new (const gchar *icon_name); -const gchar * e_image_chooser_get_icon_name (EImageChooser *chooser); -gboolean e_image_chooser_set_from_file (EImageChooser *chooser, - const gchar *filename); -gboolean e_image_chooser_set_image_data (EImageChooser *chooser, - gchar *data, - gsize data_length); -gboolean e_image_chooser_get_image_data (EImageChooser *chooser, - gchar **data, - gsize *data_length); - -#endif /* E_IMAGE_CHOOSER_H */ diff --git a/widgets/misc/e-import-assistant.c b/widgets/misc/e-import-assistant.c deleted file mode 100644 index 9e06324ab6..0000000000 --- a/widgets/misc/e-import-assistant.c +++ /dev/null @@ -1,1436 +0,0 @@ -/* - * e-import-assistant.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-import-assistant.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> - -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> -#include <libebackend/libebackend.h> - -#include <e-util/e-import.h> -#include <e-util/e-util-private.h> - -#define E_IMPORT_ASSISTANT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_IMPORT_ASSISTANT, EImportAssistantPrivate)) - -typedef struct _ImportFilePage ImportFilePage; -typedef struct _ImportDestinationPage ImportDestinationPage; -typedef struct _ImportTypePage ImportTypePage; -typedef struct _ImportSelectionPage ImportSelectionPage; -typedef struct _ImportProgressPage ImportProgressPage; -typedef struct _ImportSimplePage ImportSimplePage; - -struct _ImportFilePage { - GtkWidget *filename; - GtkWidget *filetype; - - EImportTargetURI *target; - EImportImporter *importer; -}; - -struct _ImportDestinationPage { - GtkWidget *control; -}; - -struct _ImportTypePage { - GtkWidget *intelligent; - GtkWidget *file; -}; - -struct _ImportSelectionPage { - GSList *importers; - GSList *current; - EImportTargetHome *target; -}; - -struct _ImportProgressPage { - GtkWidget *progress_bar; -}; - -struct _ImportSimplePage { - GtkWidget *actionlabel; - GtkWidget *filetypetable; - GtkWidget *filetype; - GtkWidget *control; /* importer's destination or preview widget in an alignment */ - gboolean has_preview; /* TRUE when 'control' holds a preview widget, - otherwise holds destination widget */ - - EImportTargetURI *target; - EImportImporter *importer; -}; - -struct _EImportAssistantPrivate { - ImportFilePage file_page; - ImportDestinationPage destination_page; - ImportTypePage type_page; - ImportSelectionPage selection_page; - ImportProgressPage progress_page; - ImportSimplePage simple_page; - - EImport *import; - - gboolean is_simple; - GPtrArray *fileuris; /* each element is a file URI, as a newly allocated string */ - - /* Used for importing phase of operation */ - EImportTarget *import_target; - EImportImporter *import_importer; -}; - -enum { - PAGE_START, - PAGE_INTELI_OR_DIRECT, - PAGE_INTELI_SOURCE, - PAGE_FILE_CHOOSE, - PAGE_FILE_DEST, - PAGE_FINISH, - PAGE_PROGRESS -}; - -enum { - PROP_0, - PROP_IS_SIMPLE -}; - -enum { - FINISHED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE_WITH_CODE ( - EImportAssistant, - e_import_assistant, - GTK_TYPE_ASSISTANT, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -/* Importing functions */ - -static void -import_assistant_emit_finished (EImportAssistant *import_assistant) -{ - g_signal_emit (import_assistant, signals[FINISHED], 0); -} - -static void -filename_changed (GtkWidget *widget, - GtkAssistant *assistant) -{ - EImportAssistantPrivate *priv; - ImportFilePage *page; - const gchar *filename; - gint fileok; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->file_page; - - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); - - fileok = - filename != NULL && *filename != '\0' && - g_file_test (filename, G_FILE_TEST_IS_REGULAR); - - if (fileok) { - GtkTreeIter iter; - GtkTreeModel *model; - gboolean valid; - GSList *l; - EImportImporter *first = NULL; - gint i = 0, firstitem = 0; - - g_free (page->target->uri_src); - page->target->uri_src = g_filename_to_uri (filename, NULL, NULL); - - l = e_import_get_importers ( - priv->import, (EImportTarget *) page->target); - model = gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype)); - valid = gtk_tree_model_get_iter_first (model, &iter); - while (valid) { - gpointer eii = NULL; - - gtk_tree_model_get (model, &iter, 2, &eii, -1); - - if (g_slist_find (l, eii) != NULL) { - if (first == NULL) { - firstitem = i; - first = eii; - } - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, TRUE, -1); - } else { - if (page->importer == eii) - page->importer = NULL; - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, FALSE, -1); - } - i++; - valid = gtk_tree_model_iter_next (model, &iter); - } - g_slist_free (l); - - if (page->importer == NULL && first) { - page->importer = first; - gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), firstitem); - } - fileok = first != NULL; - } else { - GtkTreeIter iter; - GtkTreeModel *model; - gboolean valid; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype)); - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, FALSE, -1); - } - } - - widget = gtk_assistant_get_nth_page (assistant, PAGE_FILE_CHOOSE); - gtk_assistant_set_page_complete (assistant, widget, fileok); -} - -static void -filetype_changed_cb (GtkComboBox *combo_box, - GtkAssistant *assistant) -{ - EImportAssistantPrivate *priv; - GtkTreeModel *model; - GtkTreeIter iter; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - - g_return_if_fail (gtk_combo_box_get_active_iter (combo_box, &iter)); - - model = gtk_combo_box_get_model (combo_box); - gtk_tree_model_get (model, &iter, 2, &priv->file_page.importer, -1); - filename_changed (priv->file_page.filename, assistant); -} - -static GtkWidget * -import_assistant_file_page_init (EImportAssistant *import_assistant) -{ - GtkWidget *page; - GtkWidget *label; - GtkWidget *container; - GtkWidget *widget; - GtkCellRenderer *cell; - GtkListStore *store; - const gchar *text; - gint row = 0; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - text = _("Choose the file that you want to import into Evolution, " - "and select what type of file it is from the list."); - - widget = gtk_label_new (text); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - widget = gtk_table_new (2, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (widget), 2); - gtk_table_set_col_spacings (GTK_TABLE (widget), 10); - gtk_container_set_border_width (GTK_CONTAINER (widget), 8); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_label_new_with_mnemonic (_("F_ilename:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = widget; - - widget = gtk_file_chooser_button_new ( - _("Select a file"), GTK_FILE_CHOOSER_ACTION_OPEN); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_table_attach ( - GTK_TABLE (container), widget, 1, 2, - row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); - import_assistant->priv->file_page.filename = widget; - gtk_widget_show (widget); - - g_signal_connect ( - widget, "selection-changed", - G_CALLBACK (filename_changed), import_assistant); - - row++; - - widget = gtk_label_new_with_mnemonic (_("File _type:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = widget; - - store = gtk_list_store_new ( - 3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER); - widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); - import_assistant->priv->file_page.filetype = widget; - gtk_widget_show (widget); - g_object_unref (store); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE); - gtk_cell_layout_set_attributes ( - GTK_CELL_LAYOUT (widget), cell, - "text", 0, "sensitive", 1, NULL); - - return page; -} - -static GtkWidget * -import_assistant_destination_page_init (EImportAssistant *import_assistant) -{ - GtkWidget *page; - GtkWidget *container; - GtkWidget *widget; - const gchar *text; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - text = _("Choose the destination for this import"); - - widget = gtk_label_new (text); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - return page; -} - -static GtkWidget * -import_assistant_type_page_init (EImportAssistant *import_assistant) -{ - GtkRadioButton *radio_button; - GtkWidget *page; - GtkWidget *container; - GtkWidget *widget; - const gchar *text; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - text = _("Choose the type of importer to run:"); - - widget = gtk_label_new (text); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - widget = gtk_radio_button_new_with_mnemonic ( - NULL, _("Import data and settings from _older programs")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - import_assistant->priv->type_page.intelligent = widget; - gtk_widget_show (widget); - - radio_button = GTK_RADIO_BUTTON (widget); - - widget = gtk_radio_button_new_with_mnemonic_from_widget ( - radio_button, _("Import a _single file")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - import_assistant->priv->type_page.file = widget; - gtk_widget_show (widget); - - return page; -} - -static GtkWidget * -import_assistant_selection_page_init (EImportAssistant *import_assistant) -{ - GtkWidget *page; - GtkWidget *container; - GtkWidget *widget; - const gchar *text; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - text = _("Please select the information " - "that you would like to import:"); - - widget = gtk_label_new (text); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - widget = gtk_hseparator_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - return page; -} - -static GtkWidget * -import_assistant_progress_page_init (EImportAssistant *import_assistant) -{ - GtkWidget *page; - GtkWidget *container; - GtkWidget *widget; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - widget = gtk_progress_bar_new (); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, FALSE, 0); - import_assistant->priv->progress_page.progress_bar = widget; - gtk_widget_show (widget); - - return page; -} - -static GtkWidget * -import_assistant_simple_page_init (EImportAssistant *import_assistant) -{ - GtkWidget *page; - GtkWidget *label; - GtkWidget *container; - GtkWidget *widget; - GtkCellRenderer *cell; - GtkListStore *store; - gint row = 0; - - page = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - gtk_widget_show (page); - - container = page; - - widget = gtk_label_new (""); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - import_assistant->priv->simple_page.actionlabel = widget; - - widget = gtk_table_new (2, 1, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (widget), 2); - gtk_table_set_col_spacings (GTK_TABLE (widget), 10); - gtk_container_set_border_width (GTK_CONTAINER (widget), 8); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - import_assistant->priv->simple_page.filetypetable = widget; - - container = widget; - - widget = gtk_label_new_with_mnemonic (_("File _type:")); - gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = widget; - - store = gtk_list_store_new ( - 3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER); - widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); - import_assistant->priv->simple_page.filetype = widget; - gtk_widget_show (widget); - g_object_unref (store); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE); - gtk_cell_layout_set_attributes ( - GTK_CELL_LAYOUT (widget), cell, - "text", 0, "sensitive", 1, NULL); - - import_assistant->priv->simple_page.control = NULL; - - return page; -} - -static void -prepare_intelligent_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - GSList *l; - GtkWidget *table; - gint row; - ImportSelectionPage *page; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->selection_page; - - if (page->target != NULL) { - gtk_assistant_set_page_complete (assistant, vbox, FALSE); - return; - } - - page->target = e_import_target_new_home (priv->import); - - if (page->importers) - g_slist_free (page->importers); - l = page->importers = - e_import_get_importers ( - priv->import, (EImportTarget *) page->target); - - if (l == NULL) { - GtkWidget *widget; - const gchar *text; - - text = _("Evolution checked for settings to import from " - "the following applications: Pine, Netscape, Elm, " - "iCalendar. No importable settings found. If you " - "would like to try again, please click the " - "\"Back\" button."); - - widget = gtk_label_new (text); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - gtk_assistant_set_page_complete (assistant, vbox, FALSE); - - return; - } - - table = gtk_table_new (g_slist_length (l), 2, FALSE); - row = 0; - for (; l; l = l->next) { - EImportImporter *eii = l->data; - gchar *str; - GtkWidget *w, *label; - - w = e_import_get_widget ( - priv->import, (EImportTarget *) page->target, eii); - - str = g_strdup_printf (_("From %s:"), eii->name); - label = gtk_label_new (str); - gtk_widget_show (label); - g_free (str); - - gtk_misc_set_alignment (GTK_MISC (label), 0, .5); - - gtk_table_attach ( - GTK_TABLE (table), label, - 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); - if (w) - gtk_table_attach ( - GTK_TABLE (table), w, - 1, 2, row, row + 1, GTK_FILL, 0, 3, 0); - row++; - } - - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); - - gtk_assistant_set_page_complete (assistant, vbox, TRUE); -} - -static void -import_status (EImport *import, - const gchar *what, - gint percent, - gpointer user_data) -{ - EImportAssistant *import_assistant = user_data; - GtkProgressBar *progress_bar; - - progress_bar = GTK_PROGRESS_BAR ( - import_assistant->priv->progress_page.progress_bar); - gtk_progress_bar_set_fraction (progress_bar, percent / 100.0); - gtk_progress_bar_set_text (progress_bar, what); -} - -static void -import_done (EImport *ei, - gpointer user_data) -{ - EImportAssistant *import_assistant = user_data; - - import_assistant_emit_finished (import_assistant); -} - -static void -import_simple_done (EImport *ei, - gpointer user_data) -{ - EImportAssistant *import_assistant = user_data; - EImportAssistantPrivate *priv; - - g_return_if_fail (import_assistant != NULL); - - priv = import_assistant->priv; - g_return_if_fail (priv != NULL); - g_return_if_fail (priv->fileuris != NULL); - g_return_if_fail (priv->simple_page.target != NULL); - - if (import_assistant->priv->fileuris->len > 0) { - import_status (ei, "", 0, import_assistant); - - /* process next file URI */ - g_free (priv->simple_page.target->uri_src); - priv->simple_page.target->uri_src = - g_ptr_array_remove_index (priv->fileuris, 0); - - e_import_import ( - priv->import, priv->import_target, - priv->import_importer, import_status, - import_simple_done, import_assistant); - } else - import_done (ei, import_assistant); -} - -static void -import_intelligent_done (EImport *ei, - gpointer user_data) -{ - EImportAssistant *import_assistant = user_data; - ImportSelectionPage *page; - - page = &import_assistant->priv->selection_page; - - if (page->current && (page->current = page->current->next)) { - import_status (ei, "", 0, import_assistant); - import_assistant->priv->import_importer = page->current->data; - e_import_import ( - import_assistant->priv->import, - (EImportTarget *) page->target, - import_assistant->priv->import_importer, - import_status, import_intelligent_done, - import_assistant); - } else - import_done (ei, import_assistant); -} - -static void -import_cancelled (EImportAssistant *assistant) -{ - e_import_cancel ( - assistant->priv->import, - assistant->priv->import_target, - assistant->priv->import_importer); -} - -static void -prepare_file_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - GSList *importers, *imp; - GtkListStore *store; - ImportFilePage *page; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->file_page; - - if (page->target != NULL) { - filename_changed (priv->file_page.filename, assistant); - return; - } - - page->target = e_import_target_new_uri (priv->import, NULL, NULL); - importers = e_import_get_importers (priv->import, (EImportTarget *) page->target); - - store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype))); - gtk_list_store_clear (store); - - for (imp = importers; imp; imp = imp->next) { - GtkTreeIter iter; - EImportImporter *eii = imp->data; - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - 0, eii->name, - 1, TRUE, - 2, eii, - -1); - } - - g_slist_free (importers); - - gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), 0); - - filename_changed (priv->file_page.filename, assistant); - - g_signal_connect ( - page->filetype, "changed", - G_CALLBACK (filetype_changed_cb), assistant); -} - -static GtkWidget * -create_importer_control (EImport *import, - EImportTarget *target, - EImportImporter *importer) -{ - GtkWidget *control; - - control = e_import_get_widget (import, target, importer); - if (control == NULL) { - /* Coding error, not needed for translators */ - control = gtk_label_new ( - "** PLUGIN ERROR ** No settings for importer"); - gtk_widget_show (control); - } - - return control; -} - -static gboolean -prepare_destination_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - ImportDestinationPage *page; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->destination_page; - - if (page->control) - gtk_container_remove (GTK_CONTAINER (vbox), page->control); - - page->control = create_importer_control ( - priv->import, (EImportTarget *) - priv->file_page.target, priv->file_page.importer); - - gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0); - gtk_assistant_set_page_complete (assistant, vbox, TRUE); - - return FALSE; -} - -static void -prepare_progress_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - EImportCompleteFunc done = NULL; - ImportSelectionPage *page; - GtkWidget *cancel_button; - gboolean intelligent_import; - gboolean is_simple = FALSE; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->selection_page; - - /* Because we're a GTK_ASSISTANT_PAGE_PROGRESS, this will - * prevent the assistant window from being closed via window - * manager decorations while importing. */ - gtk_assistant_commit (assistant); - - /* Install a custom "Cancel Import" button. */ - cancel_button = gtk_button_new_with_mnemonic (_("_Cancel Import")); - gtk_button_set_image ( - GTK_BUTTON (cancel_button), - gtk_image_new_from_stock ( - GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON)); - g_signal_connect_swapped ( - cancel_button, "clicked", - G_CALLBACK (import_cancelled), assistant); - gtk_assistant_add_action_widget (assistant, cancel_button); - gtk_widget_show (cancel_button); - - g_object_get (assistant, "is-simple", &is_simple, NULL); - - intelligent_import = is_simple ? FALSE : gtk_toggle_button_get_active ( - GTK_TOGGLE_BUTTON (priv->type_page.intelligent)); - - if (is_simple) { - priv->import_importer = priv->simple_page.importer; - priv->import_target = (EImportTarget *) priv->simple_page.target; - done = import_simple_done; - } else if (intelligent_import) { - page->current = page->importers; - if (page->current) { - priv->import_target = (EImportTarget *) page->target; - priv->import_importer = page->current->data; - done = import_intelligent_done; - } - } else { - if (priv->file_page.importer) { - priv->import_importer = priv->file_page.importer; - priv->import_target = (EImportTarget *) priv->file_page.target; - done = import_done; - } - } - - if (done) - e_import_import ( - priv->import, priv->import_target, - priv->import_importer, import_status, - done, assistant); - else - import_assistant_emit_finished (E_IMPORT_ASSISTANT (assistant)); -} - -static void -simple_filetype_changed_cb (GtkComboBox *combo_box, - GtkAssistant *assistant) -{ - EImportAssistantPrivate *priv; - ImportSimplePage *page; - GtkTreeModel *model; - GtkTreeIter iter; - GtkWidget *vbox; - GtkWidget *control; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->simple_page; - - g_return_if_fail (gtk_combo_box_get_active_iter (combo_box, &iter)); - - model = gtk_combo_box_get_model (combo_box); - gtk_tree_model_get (model, &iter, 2, &page->importer, -1); - - vbox = g_object_get_data (G_OBJECT (combo_box), "page-vbox"); - g_return_if_fail (vbox != NULL); - - if (page->control) - gtk_widget_destroy (page->control); - page->has_preview = FALSE; - - control = e_import_get_preview_widget ( - priv->import, (EImportTarget *) - page->target, page->importer); - if (control) { - page->has_preview = TRUE; - gtk_widget_set_size_request (control, 440, 360); - } else - control = create_importer_control ( - priv->import, (EImportTarget *) - page->target, page->importer); - - page->control = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_widget_show (page->control); - gtk_container_add (GTK_CONTAINER (page->control), control); - - gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0); - gtk_assistant_set_page_complete (assistant, vbox, TRUE); -} - -static void -prepare_simple_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - GSList *importers, *imp; - GtkListStore *store; - ImportSimplePage *page; - gchar *uri; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->simple_page; - - g_return_if_fail (priv->fileuris != NULL); - - if (page->target != NULL) { - return; - } - - uri = g_ptr_array_remove_index (priv->fileuris, 0); - page->target = e_import_target_new_uri (priv->import, uri, NULL); - g_free (uri); - importers = e_import_get_importers (priv->import, (EImportTarget *) page->target); - - store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype))); - gtk_list_store_clear (store); - - for (imp = importers; imp; imp = imp->next) { - GtkTreeIter iter; - EImportImporter *eii = imp->data; - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - 0, eii->name, - 1, TRUE, - 2, eii, - -1); - } - - gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), 0); - g_object_set_data (G_OBJECT (page->filetype), "page-vbox", vbox); - - simple_filetype_changed_cb (GTK_COMBO_BOX (page->filetype), assistant); - - g_signal_connect ( - page->filetype, "changed", - G_CALLBACK (simple_filetype_changed_cb), assistant); - - if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1) { - gchar *title; - - /* only one importer found, make it even simpler */ - gtk_label_set_text ( - GTK_LABEL (page->actionlabel), - page->has_preview ? - _("Preview data to be imported") : - _("Choose the destination for this import")); - - gtk_widget_hide (page->filetypetable); - - title = g_strconcat ( - _("Import Data"), " - ", - ((EImportImporter *) importers->data)->name, NULL); - gtk_assistant_set_page_title (assistant, vbox, title); - g_free (title); - } else { - /* multiple importers found, be able to choose from them */ - gtk_label_set_text ( - GTK_LABEL (page->actionlabel), - _("Select what type of file you " - "want to import from the list.")); - - gtk_widget_show (page->filetypetable); - - gtk_assistant_set_page_title (assistant, vbox, _("Import Data")); - } - - g_slist_free (importers); -} - -static gboolean -prepare_simple_destination_page (GtkAssistant *assistant, - GtkWidget *vbox) -{ - EImportAssistantPrivate *priv; - ImportDestinationPage *page; - ImportSimplePage *simple_page; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - page = &priv->destination_page; - simple_page = &priv->simple_page; - - if (page->control) - gtk_container_remove (GTK_CONTAINER (vbox), page->control); - - page->control = create_importer_control ( - priv->import, (EImportTarget *) - simple_page->target, simple_page->importer); - - gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0); - gtk_assistant_set_page_complete (assistant, vbox, TRUE); - - return FALSE; -} - -static gint -forward_cb (gint current_page, - EImportAssistant *import_assistant) -{ - GtkToggleButton *toggle_button; - gboolean is_simple = FALSE; - - g_object_get (import_assistant, "is-simple", &is_simple, NULL); - - if (is_simple) { - if (!import_assistant->priv->simple_page.has_preview) - current_page++; - - return current_page + 1; - } - - toggle_button = GTK_TOGGLE_BUTTON ( - import_assistant->priv->type_page.intelligent); - - switch (current_page) { - case PAGE_INTELI_OR_DIRECT: - if (gtk_toggle_button_get_active (toggle_button)) - return PAGE_INTELI_SOURCE; - else - return PAGE_FILE_CHOOSE; - case PAGE_INTELI_SOURCE: - return PAGE_FINISH; - } - - return current_page + 1; -} - -static gboolean -set_import_uris (EImportAssistant *assistant, - const gchar * const *uris) -{ - EImportAssistantPrivate *priv; - GPtrArray *fileuris = NULL; - gint i; - - g_return_val_if_fail (assistant != NULL, FALSE); - g_return_val_if_fail (assistant->priv != NULL, FALSE); - g_return_val_if_fail (assistant->priv->import != NULL, FALSE); - g_return_val_if_fail (uris != NULL, FALSE); - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); - - for (i = 0; uris[i]; i++) { - const gchar *uri = uris[i]; - gchar *filename; - - filename = g_filename_from_uri (uri, NULL, NULL); - if (!filename) - filename = g_strdup (uri); - - if (filename && *filename && - g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { - gchar *furi; - - if (!g_path_is_absolute (filename)) { - gchar *tmp, *curr; - - curr = g_get_current_dir (); - tmp = g_build_filename (curr, filename, NULL); - g_free (curr); - - g_free (filename); - filename = tmp; - } - - if (fileuris == NULL) { - EImportTargetURI *target; - GSList *importers; - - furi = g_filename_to_uri (filename, NULL, NULL); - target = e_import_target_new_uri (priv->import, furi, NULL); - importers = e_import_get_importers ( - priv->import, (EImportTarget *) target); - - if (importers != NULL) { - /* there is at least one importer which can be used, - * thus there can be done an import */ - fileuris = g_ptr_array_new (); - } - - g_slist_free (importers); - e_import_target_free (priv->import, target); - g_free (furi); - - if (fileuris == NULL) { - g_free (filename); - break; - } - } - - furi = g_filename_to_uri (filename, NULL, NULL); - if (furi) - g_ptr_array_add (fileuris, furi); - } - - g_free (filename); - } - - if (fileuris != NULL) { - priv->fileuris = fileuris; - } - - return fileuris != NULL; -} - -static void -import_assistant_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - EImportAssistantPrivate *priv; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); - - switch (property_id) { - case PROP_IS_SIMPLE: - priv->is_simple = g_value_get_boolean (value); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -import_assistant_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EImportAssistantPrivate *priv; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); - - switch (property_id) { - case PROP_IS_SIMPLE: - g_value_set_boolean (value, priv->is_simple); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -import_assistant_dispose (GObject *object) -{ - EImportAssistantPrivate *priv; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); - - if (priv->file_page.target != NULL) { - e_import_target_free ( - priv->import, (EImportTarget *) - priv->file_page.target); - priv->file_page.target = NULL; - } - - if (priv->selection_page.target != NULL) { - e_import_target_free ( - priv->import, (EImportTarget *) - priv->selection_page.target); - priv->selection_page.target = NULL; - } - - if (priv->simple_page.target != NULL) { - e_import_target_free ( - priv->import, (EImportTarget *) - priv->simple_page.target); - priv->simple_page.target = NULL; - } - - if (priv->import != NULL) { - g_object_unref (priv->import); - priv->import = NULL; - } - - if (priv->fileuris != NULL) { - g_ptr_array_foreach (priv->fileuris, (GFunc) g_free, NULL); - g_ptr_array_free (priv->fileuris, TRUE); - priv->fileuris = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_import_assistant_parent_class)->dispose (object); -} - -static void -import_assistant_finalize (GObject *object) -{ - EImportAssistantPrivate *priv; - - priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); - - g_slist_free (priv->selection_page.importers); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_import_assistant_parent_class)->finalize (object); -} - -static gboolean -import_assistant_key_press_event (GtkWidget *widget, - GdkEventKey *event) -{ - GtkWidgetClass *parent_class; - - if (event->keyval == GDK_KEY_Escape) { - g_signal_emit_by_name (widget, "cancel"); - return TRUE; - } - - /* Chain up to parent's key_press_event () method. */ - parent_class = GTK_WIDGET_CLASS (e_import_assistant_parent_class); - return parent_class->key_press_event (widget, event); -} - -static void -import_assistant_prepare (GtkAssistant *assistant, - GtkWidget *page) -{ - gint page_no = gtk_assistant_get_current_page (assistant); - gboolean is_simple = FALSE; - - g_object_get (assistant, "is-simple", &is_simple, NULL); - - if (is_simple) { - if (page_no == 0) { - prepare_simple_page (assistant, page); - } else if (page_no == 1) { - prepare_simple_destination_page (assistant, page); - } else if (page_no == 2) { - prepare_progress_page (assistant, page); - } - - return; - } - - switch (page_no) { - case PAGE_INTELI_SOURCE: - prepare_intelligent_page (assistant, page); - break; - case PAGE_FILE_CHOOSE: - prepare_file_page (assistant, page); - break; - case PAGE_FILE_DEST: - prepare_destination_page (assistant, page); - break; - case PAGE_PROGRESS: - prepare_progress_page (assistant, page); - break; - default: - break; - } -} - -static void -e_import_assistant_class_init (EImportAssistantClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkAssistantClass *assistant_class; - - g_type_class_add_private (class, sizeof (EImportAssistantPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = import_assistant_dispose; - object_class->finalize = import_assistant_finalize; - object_class->set_property = import_assistant_set_property; - object_class->get_property = import_assistant_get_property; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->key_press_event = import_assistant_key_press_event; - - assistant_class = GTK_ASSISTANT_CLASS (class); - assistant_class->prepare = import_assistant_prepare; - - g_object_class_install_property ( - object_class, - PROP_IS_SIMPLE, - g_param_spec_boolean ( - "is-simple", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - signals[FINISHED] = g_signal_new ( - "finished", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -import_assistant_construct (EImportAssistant *import_assistant) -{ - GtkAssistant *assistant; - GtkWidget *page; - - assistant = GTK_ASSISTANT (import_assistant); - - import_assistant->priv->import = - e_import_new ("org.gnome.evolution.shell.importer"); - - gtk_window_set_position (GTK_WINDOW (assistant), GTK_WIN_POS_CENTER); - gtk_window_set_title (GTK_WINDOW (assistant), _("Evolution Import Assistant")); - gtk_window_set_default_size (GTK_WINDOW (assistant), 500, 330); - - e_extensible_load_extensions (E_EXTENSIBLE (import_assistant)); - - if (import_assistant->priv->is_simple) { - /* simple import assistant page, URIs of files will be known later */ - page = import_assistant_simple_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title (assistant, page, _("Import Data")); - gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - - /* File destination page - when with preview*/ - page = import_assistant_destination_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title (assistant, page, _("Import Location")); - gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - } else { - /* complex import assistant pages */ - - /* Start page */ - page = gtk_label_new (""); - gtk_label_set_line_wrap (GTK_LABEL (page), TRUE); - gtk_misc_set_alignment (GTK_MISC (page), 0.0, 0.5); - gtk_misc_set_padding (GTK_MISC (page), 12, 12); - gtk_label_set_text (GTK_LABEL (page), _( - "Welcome to the Evolution Import Assistant.\n" - "With this assistant you will be guided through the " - "process of importing external files into Evolution.")); - gtk_widget_show (page); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title ( - assistant, page, _("Evolution Import Assistant")); - gtk_assistant_set_page_type ( - assistant, page, GTK_ASSISTANT_PAGE_INTRO); - gtk_assistant_set_page_complete (assistant, page, TRUE); - - /* Intelligent or direct import page */ - page = import_assistant_type_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title ( - assistant, page, _("Importer Type")); - gtk_assistant_set_page_type ( - assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_complete (assistant, page, TRUE); - - /* Intelligent importer source page */ - page = import_assistant_selection_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title ( - assistant, page, _("Select Information to Import")); - gtk_assistant_set_page_type ( - assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - - /* File selection and file type page */ - page = import_assistant_file_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title ( - assistant, page, _("Select a File")); - gtk_assistant_set_page_type ( - assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - - /* File destination page */ - page = import_assistant_destination_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title ( - assistant, page, _("Import Location")); - gtk_assistant_set_page_type ( - assistant, page, GTK_ASSISTANT_PAGE_CONTENT); - - /* Finish page */ - page = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (page), 0.5, 0.5); - gtk_label_set_text ( - GTK_LABEL (page), _("Click \"Apply\" to " - "begin importing the file into Evolution.")); - gtk_widget_show (page); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title (assistant, page, _("Import Data")); - gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_complete (assistant, page, TRUE); - } - - /* Progress Page */ - page = import_assistant_progress_page_init (import_assistant); - - gtk_assistant_append_page (assistant, page); - gtk_assistant_set_page_title (assistant, page, _("Import Data")); - gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_PROGRESS); - gtk_assistant_set_page_complete (assistant, page, TRUE); - - gtk_assistant_set_forward_page_func ( - assistant, (GtkAssistantPageFunc) - forward_cb, import_assistant, NULL); - - gtk_assistant_update_buttons_state (assistant); -} - -static void -e_import_assistant_init (EImportAssistant *import_assistant) -{ - import_assistant->priv = - E_IMPORT_ASSISTANT_GET_PRIVATE (import_assistant); -} - -GtkWidget * -e_import_assistant_new (GtkWindow *parent) -{ - GtkWidget *assistant; - - assistant = g_object_new ( - E_TYPE_IMPORT_ASSISTANT, - "transient-for", parent, NULL); - - import_assistant_construct (E_IMPORT_ASSISTANT (assistant)); - - return assistant; -} - -/* Creates a simple assistant with only page to choose an import type - * and where to import, and then finishes. It shows import types based - * on the first valid URI given. - * - * Returns: EImportAssistant widget. - */ -GtkWidget * -e_import_assistant_new_simple (GtkWindow *parent, - const gchar * const *uris) -{ - GtkWidget *assistant; - - assistant = g_object_new ( - E_TYPE_IMPORT_ASSISTANT, - "transient-for", parent, - "is-simple", TRUE, - NULL); - - import_assistant_construct (E_IMPORT_ASSISTANT (assistant)); - - if (!set_import_uris (E_IMPORT_ASSISTANT (assistant), uris)) { - g_object_ref_sink (assistant); - g_object_unref (assistant); - return NULL; - } - - return assistant; -} diff --git a/widgets/misc/e-import-assistant.h b/widgets/misc/e-import-assistant.h deleted file mode 100644 index e120844dfd..0000000000 --- a/widgets/misc/e-import-assistant.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * e-import-assistant.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_IMPORT_ASSISTANT_H -#define E_IMPORT_ASSISTANT_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_IMPORT_ASSISTANT \ - (e_import_assistant_get_type ()) -#define E_IMPORT_ASSISTANT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_IMPORT_ASSISTANT, EImportAssistant)) -#define E_IMPORT_ASSISTANT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_IMPORT_ASSISTANT, EImportAssistantClass)) -#define E_IS_IMPORT_ASSISTANT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_IMPORT_ASSISTANT)) -#define E_IS_IMPORT_ASSISTANT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_IMPORT_ASSISTANT)) -#define E_IMPORT_ASSISTANT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_IMPORT_ASSISTANT, EImportAssistantClass)) - -G_BEGIN_DECLS - -typedef struct _EImportAssistant EImportAssistant; -typedef struct _EImportAssistantClass EImportAssistantClass; -typedef struct _EImportAssistantPrivate EImportAssistantPrivate; - -struct _EImportAssistant { - GtkAssistant parent; - EImportAssistantPrivate *priv; -}; - -struct _EImportAssistantClass { - GtkAssistantClass parent_class; -}; - -GType e_import_assistant_get_type (void); -GtkWidget * e_import_assistant_new (GtkWindow *parent); -GtkWidget * e_import_assistant_new_simple (GtkWindow *parent, - const gchar * const *uris); - -G_END_DECLS - -#endif /* E_IMPORT_ASSISTANT_H */ diff --git a/widgets/misc/e-interval-chooser.c b/widgets/misc/e-interval-chooser.c deleted file mode 100644 index 5a2b4e04ad..0000000000 --- a/widgets/misc/e-interval-chooser.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * e-interval-chooser.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-interval-chooser.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#include <e-util/e-util.h> - -#define E_INTERVAL_CHOOSER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_INTERVAL_CHOOSER, EIntervalChooserPrivate)) - -#define MINUTES_PER_HOUR (60) -#define MINUTES_PER_DAY (MINUTES_PER_HOUR * 24) - -struct _EIntervalChooserPrivate { - GtkComboBox *combo_box; /* not referenced */ - GtkSpinButton *spin_button; /* not referenced */ -}; - -enum { - PROP_0, - PROP_INTERVAL_MINUTES -}; - -G_DEFINE_TYPE ( - EIntervalChooser, - e_interval_chooser, - GTK_TYPE_BOX) - -static void -interval_chooser_notify_interval (GObject *object) -{ - g_object_notify (object, "interval-minutes"); -} - -static void -interval_chooser_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_INTERVAL_MINUTES: - e_interval_chooser_set_interval_minutes ( - E_INTERVAL_CHOOSER (object), - g_value_get_uint (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -interval_chooser_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_INTERVAL_MINUTES: - g_value_set_uint ( - value, - e_interval_chooser_get_interval_minutes ( - E_INTERVAL_CHOOSER (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_interval_chooser_class_init (EIntervalChooserClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EIntervalChooserPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = interval_chooser_set_property; - object_class->get_property = interval_chooser_get_property; - - g_object_class_install_property ( - object_class, - PROP_INTERVAL_MINUTES, - g_param_spec_uint ( - "interval-minutes", - "Interval in Minutes", - "Refresh interval in minutes", - 0, G_MAXUINT, 60, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_interval_chooser_init (EIntervalChooser *chooser) -{ - GtkWidget *widget; - - chooser->priv = E_INTERVAL_CHOOSER_GET_PRIVATE (chooser); - - gtk_orientable_set_orientation ( - GTK_ORIENTABLE (chooser), GTK_ORIENTATION_HORIZONTAL); - - gtk_box_set_spacing (GTK_BOX (chooser), 6); - - widget = gtk_spin_button_new_with_range (0, G_MAXUINT, 1); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE); - gtk_spin_button_set_update_policy ( - GTK_SPIN_BUTTON (widget), GTK_UPDATE_IF_VALID); - gtk_box_pack_start (GTK_BOX (chooser), widget, TRUE, TRUE, 0); - chooser->priv->spin_button = GTK_SPIN_BUTTON (widget); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "notify::value", - G_CALLBACK (interval_chooser_notify_interval), chooser); - - widget = gtk_combo_box_text_new (); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("minutes")); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("hours")); - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (widget), _("days")); - gtk_box_pack_start (GTK_BOX (chooser), widget, FALSE, FALSE, 0); - chooser->priv->combo_box = GTK_COMBO_BOX (widget); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "notify::active", - G_CALLBACK (interval_chooser_notify_interval), chooser); -} - -GtkWidget * -e_interval_chooser_new (void) -{ - return g_object_new (E_TYPE_INTERVAL_CHOOSER, NULL); -} - -guint -e_interval_chooser_get_interval_minutes (EIntervalChooser *chooser) -{ - EDurationType units; - gdouble interval_minutes; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG_REFRESH (chooser), 0); - - units = gtk_combo_box_get_active (chooser->priv->combo_box); - - interval_minutes = gtk_spin_button_get_value ( - chooser->priv->spin_button); - - switch (units) { - case E_DURATION_HOURS: - interval_minutes *= MINUTES_PER_HOUR; - break; - case E_DURATION_DAYS: - interval_minutes *= MINUTES_PER_DAY; - break; - default: - break; - } - - return (guint) interval_minutes; -} - -void -e_interval_chooser_set_interval_minutes (EIntervalChooser *chooser, - guint interval_minutes) -{ - EDurationType units; - - g_return_if_fail (E_IS_SOURCE_CONFIG_REFRESH (chooser)); - - if (interval_minutes == 0) { - units = E_DURATION_MINUTES; - } else if (interval_minutes % MINUTES_PER_DAY == 0) { - interval_minutes /= MINUTES_PER_DAY; - units = E_DURATION_DAYS; - } else if (interval_minutes % MINUTES_PER_HOUR == 0) { - interval_minutes /= MINUTES_PER_HOUR; - units = E_DURATION_HOURS; - } else { - units = E_DURATION_MINUTES; - } - - g_object_freeze_notify (G_OBJECT (chooser)); - - gtk_combo_box_set_active (chooser->priv->combo_box, units); - - gtk_spin_button_set_value ( - chooser->priv->spin_button, interval_minutes); - - g_object_thaw_notify (G_OBJECT (chooser)); -} diff --git a/widgets/misc/e-interval-chooser.h b/widgets/misc/e-interval-chooser.h deleted file mode 100644 index 351cbbe336..0000000000 --- a/widgets/misc/e-interval-chooser.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * e-interval-chooser.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_INTERVAL_CHOOSER_H -#define E_INTERVAL_CHOOSER_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_INTERVAL_CHOOSER \ - (e_interval_chooser_get_type ()) -#define E_INTERVAL_CHOOSER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_INTERVAL_CHOOSER, EIntervalChooser)) -#define E_INTERVAL_CHOOSER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_INTERVAL_CHOOSER, EIntervalChooserClass)) -#define E_IS_SOURCE_CONFIG_REFRESH(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_INTERVAL_CHOOSER)) -#define E_IS_SOURCE_CONFIG_REFRESH_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_INTERVAL_CHOOSER)) -#define E_INTERVAL_CHOOSER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_INTERVAL_CHOOSER, EIntervalChooserClass)) - -G_BEGIN_DECLS - -typedef struct _EIntervalChooser EIntervalChooser; -typedef struct _EIntervalChooserClass EIntervalChooserClass; -typedef struct _EIntervalChooserPrivate EIntervalChooserPrivate; - -struct _EIntervalChooser { - GtkBox parent; - EIntervalChooserPrivate *priv; -}; - -struct _EIntervalChooserClass { - GtkBoxClass parent_class; -}; - -GType e_interval_chooser_get_type (void) G_GNUC_CONST; -GtkWidget * e_interval_chooser_new (void); -guint e_interval_chooser_get_interval_minutes - (EIntervalChooser *refresh); -void e_interval_chooser_set_interval_minutes - (EIntervalChooser *refresh, - guint interval_minutes); - -G_END_DECLS - -#endif /* E_INTERVAL_CHOOSER_H */ diff --git a/widgets/misc/e-mail-identity-combo-box.c b/widgets/misc/e-mail-identity-combo-box.c deleted file mode 100644 index b76e0ee6bc..0000000000 --- a/widgets/misc/e-mail-identity-combo-box.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * e-mail-identity-combo-box.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-identity-combo-box.h" - -#define E_MAIL_IDENTITY_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxPrivate)) - -#define SOURCE_IS_MAIL_IDENTITY(source) \ - (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_IDENTITY)) - -struct _EMailIdentityComboBoxPrivate { - ESourceRegistry *registry; - guint refresh_idle_id; -}; - -enum { - PROP_0, - PROP_REGISTRY -}; - -enum { - COLUMN_DISPLAY_NAME, - COLUMN_UID -}; - -G_DEFINE_TYPE ( - EMailIdentityComboBox, - e_mail_identity_combo_box, - GTK_TYPE_COMBO_BOX) - -static gboolean -mail_identity_combo_box_refresh_idle_cb (EMailIdentityComboBox *combo_box) -{ - /* The refresh function will clear the idle ID. */ - e_mail_identity_combo_box_refresh (combo_box); - - return FALSE; -} - -static void -mail_identity_combo_box_registry_changed (ESourceRegistry *registry, - ESource *source, - EMailIdentityComboBox *combo_box) -{ - /* If the ESource in question has a "Mail Identity" extension, - * schedule a refresh of the tree model. Otherwise ignore it. - * We use an idle callback to limit how frequently we refresh - * the tree model, in case the registry is emitting lots of - * signals at once. */ - - if (!SOURCE_IS_MAIL_IDENTITY (source)) - return; - - if (combo_box->priv->refresh_idle_id > 0) - return; - - combo_box->priv->refresh_idle_id = g_idle_add ( - (GSourceFunc) mail_identity_combo_box_refresh_idle_cb, - combo_box); -} - -static void -mail_identity_combo_box_activate_default (EMailIdentityComboBox *combo_box) -{ - ESource *source; - ESourceRegistry *registry; - - registry = e_mail_identity_combo_box_get_registry (combo_box); - source = e_source_registry_ref_default_mail_identity (registry); - - if (source != NULL) { - const gchar *uid = e_source_get_uid (source); - gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid); - g_object_unref (source); - } -} - -static void -mail_identity_combo_box_set_registry (EMailIdentityComboBox *combo_box, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (combo_box->priv->registry == NULL); - - combo_box->priv->registry = g_object_ref (registry); - - g_signal_connect ( - registry, "source-added", - G_CALLBACK (mail_identity_combo_box_registry_changed), - combo_box); - - g_signal_connect ( - registry, "source-changed", - G_CALLBACK (mail_identity_combo_box_registry_changed), - combo_box); - - g_signal_connect ( - registry, "source-removed", - G_CALLBACK (mail_identity_combo_box_registry_changed), - combo_box); -} - -static void -mail_identity_combo_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - mail_identity_combo_box_set_registry ( - E_MAIL_IDENTITY_COMBO_BOX (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_identity_combo_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_identity_combo_box_get_registry ( - E_MAIL_IDENTITY_COMBO_BOX (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_identity_combo_box_dispose (GObject *object) -{ - EMailIdentityComboBoxPrivate *priv; - - priv = E_MAIL_IDENTITY_COMBO_BOX_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; - } - - if (priv->refresh_idle_id > 0) { - g_source_remove (priv->refresh_idle_id); - priv->refresh_idle_id = 0; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_identity_combo_box_parent_class)-> - dispose (object); -} - -static void -mail_identity_combo_box_constructed (GObject *object) -{ - GtkListStore *list_store; - GtkComboBox *combo_box; - GtkCellLayout *cell_layout; - GtkCellRenderer *cell_renderer; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_identity_combo_box_parent_class)-> - constructed (object); - - combo_box = GTK_COMBO_BOX (object); - cell_layout = GTK_CELL_LAYOUT (object); - - list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store)); - gtk_combo_box_set_id_column (combo_box, COLUMN_UID); - g_object_unref (list_store); - - cell_renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE); - gtk_cell_layout_add_attribute ( - cell_layout, cell_renderer, "text", COLUMN_DISPLAY_NAME); - - e_mail_identity_combo_box_refresh (E_MAIL_IDENTITY_COMBO_BOX (object)); -} - -static void -e_mail_identity_combo_box_class_init (EMailIdentityComboBoxClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private ( - class, sizeof (EMailIdentityComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_identity_combo_box_set_property; - object_class->get_property = mail_identity_combo_box_get_property; - object_class->dispose = mail_identity_combo_box_dispose; - object_class->constructed = mail_identity_combo_box_constructed; - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - NULL, - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_mail_identity_combo_box_init (EMailIdentityComboBox *combo_box) -{ - combo_box->priv = E_MAIL_IDENTITY_COMBO_BOX_GET_PRIVATE (combo_box); -} - -GtkWidget * -e_mail_identity_combo_box_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_MAIL_IDENTITY_COMBO_BOX, - "registry", registry, NULL); -} - -void -e_mail_identity_combo_box_refresh (EMailIdentityComboBox *combo_box) -{ - ESourceRegistry *registry; - GtkTreeModel *tree_model; - GtkComboBox *gtk_combo_box; - ESource *source; - GList *list, *link; - GHashTable *address_table; - const gchar *extension_name; - const gchar *saved_uid; - - g_return_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box)); - - if (combo_box->priv->refresh_idle_id > 0) { - g_source_remove (combo_box->priv->refresh_idle_id); - combo_box->priv->refresh_idle_id = 0; - } - - gtk_combo_box = GTK_COMBO_BOX (combo_box); - tree_model = gtk_combo_box_get_model (gtk_combo_box); - - /* This is an interned string, which means it's safe - * to use even after clearing the combo box model. */ - saved_uid = gtk_combo_box_get_active_id (gtk_combo_box); - - gtk_list_store_clear (GTK_LIST_STORE (tree_model)); - - extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - registry = e_mail_identity_combo_box_get_registry (combo_box); - list = e_source_registry_list_sources (registry, extension_name); - - /* Build a hash table of GQueues by email address so we can - * spot duplicate email addresses. Then if the GQueue for a - * given email address has multiple elements, we use a more - * verbose description in the combo box. */ - - address_table = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_queue_free); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESourceMailIdentity *extension; - GQueue *queue; - const gchar *address; - - source = E_SOURCE (link->data); - extension = e_source_get_extension (source, extension_name); - address = e_source_mail_identity_get_address (extension); - - if (address == NULL) - continue; - - queue = g_hash_table_lookup (address_table, address); - if (queue == NULL) { - queue = g_queue_new (); - g_hash_table_insert ( - address_table, - g_strdup (address), queue); - } - - g_queue_push_tail (queue, source); - } - - for (link = list; link != NULL; link = g_list_next (link)) { - ESourceMailIdentity *extension; - GtkTreeIter iter; - GQueue *queue; - GString *string; - const gchar *address; - const gchar *display_name; - const gchar *name; - const gchar *uid; - - source = E_SOURCE (link->data); - - if (!e_source_registry_check_enabled (registry, source)) - continue; - - extension = e_source_get_extension (source, extension_name); - name = e_source_mail_identity_get_name (extension); - address = e_source_mail_identity_get_address (extension); - - if (name == NULL || address == NULL) - continue; - - queue = g_hash_table_lookup (address_table, address); - - display_name = e_source_get_display_name (source); - uid = e_source_get_uid (source); - - string = g_string_sized_new (512); - g_string_append_printf (string, "%s <%s>", name, address); - - /* Show the account name for duplicate email addresses. */ - if (queue != NULL && g_queue_get_length (queue) > 1) - g_string_append_printf (string, " (%s)", display_name); - - gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (tree_model), &iter, - COLUMN_DISPLAY_NAME, string->str, - COLUMN_UID, uid, -1); - - g_string_free (string, TRUE); - } - - g_hash_table_destroy (address_table); - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - /* Try and restore the previous selected source, or else pick - * the default identity of the default mail account. If even - * that fails, just pick the first item. */ - - if (saved_uid != NULL) - gtk_combo_box_set_active_id (gtk_combo_box, saved_uid); - - if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL) - mail_identity_combo_box_activate_default (combo_box); - - if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL) - gtk_combo_box_set_active (gtk_combo_box, 0); -} - -ESourceRegistry * -e_mail_identity_combo_box_get_registry (EMailIdentityComboBox *combo_box) -{ - g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), NULL); - - return combo_box->priv->registry; -} diff --git a/widgets/misc/e-mail-identity-combo-box.h b/widgets/misc/e-mail-identity-combo-box.h deleted file mode 100644 index 691d69bde2..0000000000 --- a/widgets/misc/e-mail-identity-combo-box.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * e-mail-identity-combo-box.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_IDENTITY_COMBO_BOX_H -#define E_MAIL_IDENTITY_COMBO_BOX_H - -#include <gtk/gtk.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_IDENTITY_COMBO_BOX \ - (e_mail_identity_combo_box_get_type ()) -#define E_MAIL_IDENTITY_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBox)) -#define E_MAIL_IDENTITY_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxClass)) -#define E_IS_MAIL_IDENTITY_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX)) -#define E_IS_MAIL_IDENTITY_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_IDENTITY_COMBO_BOX)) -#define E_MAIL_IDENTITY_COMBO_BOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_IDENTITY_COMBO_BOX, EMailIdentityComboBoxClass)) - -G_BEGIN_DECLS - -typedef struct _EMailIdentityComboBox EMailIdentityComboBox; -typedef struct _EMailIdentityComboBoxClass EMailIdentityComboBoxClass; -typedef struct _EMailIdentityComboBoxPrivate EMailIdentityComboBoxPrivate; - -struct _EMailIdentityComboBox { - GtkComboBox parent; - EMailIdentityComboBoxPrivate *priv; -}; - -struct _EMailIdentityComboBoxClass { - GtkComboBoxClass parent_class; -}; - -GType e_mail_identity_combo_box_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_identity_combo_box_new - (ESourceRegistry *registry); -void e_mail_identity_combo_box_refresh - (EMailIdentityComboBox *combo_box); -ESourceRegistry * - e_mail_identity_combo_box_get_registry - (EMailIdentityComboBox *combo_box); - -G_END_DECLS - -#endif /* E_MAIL_IDENTITY_COMBO_BOX_H */ diff --git a/widgets/misc/e-mail-signature-combo-box.c b/widgets/misc/e-mail-signature-combo-box.c deleted file mode 100644 index 275c2538b9..0000000000 --- a/widgets/misc/e-mail-signature-combo-box.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * e-mail-signature-combo-box.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-combo-box.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#define E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_COMBO_BOX, EMailSignatureComboBoxPrivate)) - -#define SOURCE_IS_MAIL_SIGNATURE(source) \ - (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_SIGNATURE)) - -struct _EMailSignatureComboBoxPrivate { - ESourceRegistry *registry; - guint refresh_idle_id; - gchar *identity_uid; -}; - -enum { - PROP_0, - PROP_IDENTITY_UID, - PROP_REGISTRY -}; - -enum { - COLUMN_DISPLAY_NAME, - COLUMN_UID -}; - -G_DEFINE_TYPE ( - EMailSignatureComboBox, - e_mail_signature_combo_box, - GTK_TYPE_COMBO_BOX) - -static gboolean -mail_signature_combo_box_refresh_idle_cb (EMailSignatureComboBox *combo_box) -{ - /* The refresh function will clear the idle ID. */ - e_mail_signature_combo_box_refresh (combo_box); - - return FALSE; -} - -static void -mail_signature_combo_box_registry_changed (ESourceRegistry *registry, - ESource *source, - EMailSignatureComboBox *combo_box) -{ - /* If the ESource in question has a "Mail Signature" extension, - * schedule a refresh of the tree model. Otherwise ignore it. - * We use an idle callback to limit how frequently we refresh - * the tree model, in case the registry is emitting lots of - * signals at once. */ - - if (!SOURCE_IS_MAIL_SIGNATURE (source)) - return; - - if (combo_box->priv->refresh_idle_id > 0) - return; - - combo_box->priv->refresh_idle_id = g_idle_add ( - (GSourceFunc) mail_signature_combo_box_refresh_idle_cb, - combo_box); -} - -static gboolean -mail_signature_combo_box_identity_to_signature (GBinding *binding, - const GValue *source_value, - GValue *target_value, - gpointer user_data) -{ - EMailSignatureComboBox *combo_box; - ESourceRegistry *registry; - GObject *source_object; - ESource *source; - ESourceMailIdentity *extension; - const gchar *identity_uid; - const gchar *signature_uid = "none"; - const gchar *extension_name; - - /* Source and target are the same object. */ - source_object = g_binding_get_source (binding); - combo_box = E_MAIL_SIGNATURE_COMBO_BOX (source_object); - registry = e_mail_signature_combo_box_get_registry (combo_box); - - identity_uid = g_value_get_string (source_value); - if (identity_uid == NULL) - return FALSE; - - source = e_source_registry_ref_source (registry, identity_uid); - if (source == NULL) - return FALSE; - - extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - if (!e_source_has_extension (source, extension_name)) { - g_object_unref (source); - return FALSE; - } - - extension = e_source_get_extension (source, extension_name); - signature_uid = e_source_mail_identity_get_signature_uid (extension); - g_value_set_string (target_value, signature_uid); - - g_object_unref (source); - - return TRUE; -} - -static void -mail_signature_combo_box_set_registry (EMailSignatureComboBox *combo_box, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (combo_box->priv->registry == NULL); - - combo_box->priv->registry = g_object_ref (registry); - - g_signal_connect ( - registry, "source-added", - G_CALLBACK (mail_signature_combo_box_registry_changed), - combo_box); - - g_signal_connect ( - registry, "source-changed", - G_CALLBACK (mail_signature_combo_box_registry_changed), - combo_box); - - g_signal_connect ( - registry, "source-removed", - G_CALLBACK (mail_signature_combo_box_registry_changed), - combo_box); -} - -static void -mail_signature_combo_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_IDENTITY_UID: - e_mail_signature_combo_box_set_identity_uid ( - E_MAIL_SIGNATURE_COMBO_BOX (object), - g_value_get_string (value)); - return; - - case PROP_REGISTRY: - mail_signature_combo_box_set_registry ( - E_MAIL_SIGNATURE_COMBO_BOX (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_combo_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_IDENTITY_UID: - g_value_set_string ( - value, - e_mail_signature_combo_box_get_identity_uid ( - E_MAIL_SIGNATURE_COMBO_BOX (object))); - return; - - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_combo_box_get_registry ( - E_MAIL_SIGNATURE_COMBO_BOX (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_combo_box_dispose (GObject *object) -{ - EMailSignatureComboBoxPrivate *priv; - - priv = E_MAIL_SIGNATURE_COMBO_BOX_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; - } - - if (priv->refresh_idle_id > 0) { - g_source_remove (priv->refresh_idle_id); - priv->refresh_idle_id = 0; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)-> - dispose (object); -} - -static void -mail_signature_combo_box_finalize (GObject *object) -{ - EMailSignatureComboBoxPrivate *priv; - - priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (object); - - g_free (priv->identity_uid); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)-> - finalize (object); -} - -static void -mail_signature_combo_box_constructed (GObject *object) -{ - GtkListStore *list_store; - GtkComboBox *combo_box; - GtkCellLayout *cell_layout; - GtkCellRenderer *cell_renderer; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)-> - constructed (object); - - combo_box = GTK_COMBO_BOX (object); - cell_layout = GTK_CELL_LAYOUT (object); - - list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store)); - gtk_combo_box_set_id_column (combo_box, COLUMN_UID); - g_object_unref (list_store); - - cell_renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE); - gtk_cell_layout_add_attribute ( - cell_layout, cell_renderer, "text", COLUMN_DISPLAY_NAME); - - g_object_bind_property_full ( - combo_box, "identity-uid", - combo_box, "active-id", - G_BINDING_DEFAULT, - mail_signature_combo_box_identity_to_signature, - NULL, - NULL, (GDestroyNotify) NULL); - - e_mail_signature_combo_box_refresh ( - E_MAIL_SIGNATURE_COMBO_BOX (object)); -} - -static void -e_mail_signature_combo_box_class_init (EMailSignatureComboBoxClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private ( - class, sizeof (EMailSignatureComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_combo_box_set_property; - object_class->get_property = mail_signature_combo_box_get_property; - object_class->dispose = mail_signature_combo_box_dispose; - object_class->finalize = mail_signature_combo_box_finalize; - object_class->constructed = mail_signature_combo_box_constructed; - - g_object_class_install_property ( - object_class, - PROP_IDENTITY_UID, - g_param_spec_string ( - "identity-uid", - "Identity UID", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - NULL, - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_mail_signature_combo_box_init (EMailSignatureComboBox *combo_box) -{ - combo_box->priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (combo_box); -} - -GtkWidget * -e_mail_signature_combo_box_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_COMBO_BOX, - "registry", registry, NULL); -} - -void -e_mail_signature_combo_box_refresh (EMailSignatureComboBox *combo_box) -{ - ESourceRegistry *registry; - GtkComboBox *gtk_combo_box; - GtkTreeModel *tree_model; - GtkTreeIter iter; - ESource *source; - GList *list, *link; - const gchar *extension_name; - const gchar *saved_uid; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box)); - - if (combo_box->priv->refresh_idle_id > 0) { - g_source_remove (combo_box->priv->refresh_idle_id); - combo_box->priv->refresh_idle_id = 0; - } - - gtk_combo_box = GTK_COMBO_BOX (combo_box); - tree_model = gtk_combo_box_get_model (gtk_combo_box); - - /* This is an interned string, which means it's safe - * to use even after clearing the combo box model. */ - saved_uid = gtk_combo_box_get_active_id (gtk_combo_box); - - gtk_list_store_clear (GTK_LIST_STORE (tree_model)); - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - registry = e_mail_signature_combo_box_get_registry (combo_box); - list = e_source_registry_list_sources (registry, extension_name); - - /* The "None" option always comes first. */ - - gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (tree_model), &iter, - COLUMN_DISPLAY_NAME, _("None"), - COLUMN_UID, "none", -1); - - /* The "autogenerated" UID has special meaning. */ - - gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (tree_model), &iter, - COLUMN_DISPLAY_NAME, _("Autogenerated"), - COLUMN_UID, E_MAIL_SIGNATURE_AUTOGENERATED_UID, -1); - - /* Followed by the other mail signatures, alphabetized. */ - - for (link = list; link != NULL; link = g_list_next (link)) { - GtkTreeIter iter; - const gchar *display_name; - const gchar *uid; - - source = E_SOURCE (link->data); - display_name = e_source_get_display_name (source); - uid = e_source_get_uid (source); - - gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (tree_model), &iter, - COLUMN_DISPLAY_NAME, display_name, - COLUMN_UID, uid, -1); - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - /* Try and restore the previous selected source, or else "None". */ - - if (saved_uid != NULL) - gtk_combo_box_set_active_id (gtk_combo_box, saved_uid); - - if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL) - gtk_combo_box_set_active (gtk_combo_box, 0); -} - -ESourceRegistry * -e_mail_signature_combo_box_get_registry (EMailSignatureComboBox *combo_box) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL); - - return combo_box->priv->registry; -} - -const gchar * -e_mail_signature_combo_box_get_identity_uid (EMailSignatureComboBox *combo_box) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL); - - return combo_box->priv->identity_uid; -} - -void -e_mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box, - const gchar *identity_uid) -{ - const gchar *active_id; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box)); - - if (g_strcmp0 (combo_box->priv->identity_uid, identity_uid) == 0) - return; - - g_free (combo_box->priv->identity_uid); - combo_box->priv->identity_uid = g_strdup (identity_uid); - - g_object_notify (G_OBJECT (combo_box), "identity-uid"); - - /* If "Autogenerated" is selected, emit a "changed" signal as - * a hint to whomever is listening to reload the signature. */ - active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)); - if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0) - g_signal_emit_by_name (combo_box, "changed"); -} - -/**************** e_mail_signature_combo_box_load_selected() *****************/ - -typedef struct _LoadContext LoadContext; - -struct _LoadContext { - gchar *contents; - gsize length; - gboolean is_html; -}; - -static void -load_context_free (LoadContext *context) -{ - g_free (context->contents); - g_slice_free (LoadContext, context); -} - -static void -mail_signature_combo_box_autogenerate (EMailSignatureComboBox *combo_box, - LoadContext *context) -{ - ESourceMailIdentity *extension; - ESourceRegistry *registry; - ESource *source; - GString *buffer; - const gchar *extension_name; - const gchar *identity_uid; - const gchar *text; - gchar *escaped; - - identity_uid = e_mail_signature_combo_box_get_identity_uid (combo_box); - - /* If we have no mail identity UID, handle it as though - * "None" were selected. No need to report an error. */ - if (identity_uid == NULL) - return; - - registry = e_mail_signature_combo_box_get_registry (combo_box); - source = e_source_registry_ref_source (registry, identity_uid); - - /* If the mail identity lookup fails, handle it as though - * "None" were selected. No need to report an error. */ - if (source == NULL) - return; - - /* If the source is not actually a mail identity, handle it as - * though "None" were selected. No need to report an error. */ - extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - if (!e_source_has_extension (source, extension_name)) { - g_object_unref (source); - return; - } - - extension = e_source_get_extension (source, extension_name); - - /* The autogenerated signature format is: - * - * <NAME> <ADDRESS> - * <ORGANIZATION> - * - * The <ADDRESS> is a mailto link and - * the <ORGANIZATION> line is optional. - */ - - buffer = g_string_sized_new (512); - - text = e_source_mail_identity_get_name (extension); - escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL; - if (escaped != NULL && *escaped != '\0') - g_string_append (buffer, escaped); - g_free (escaped); - - text = e_source_mail_identity_get_address (extension); - escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL; - if (escaped != NULL && *escaped != '\0') - g_string_append_printf ( - buffer, " <<a href=\"mailto:%s\">%s</a>>", - escaped, escaped); - g_free (escaped); - - text = e_source_mail_identity_get_organization (extension); - escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL; - if (escaped != NULL && *escaped != '\0') - g_string_append_printf (buffer, "<br>%s", escaped); - g_free (escaped); - - context->length = buffer->len; - context->contents = g_string_free (buffer, FALSE); - context->is_html = TRUE; - - g_object_unref (source); -} - -static void -mail_signature_combo_box_load_cb (ESource *source, - GAsyncResult *result, - GSimpleAsyncResult *simple) -{ - ESourceMailSignature *extension; - LoadContext *context; - const gchar *extension_name; - const gchar *mime_type; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_source_mail_signature_load_finish ( - source, result, &context->contents, &context->length, &error); - - if (error != NULL) { - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); - g_error_free (error); - return; - } - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - mime_type = e_source_mail_signature_get_mime_type (extension); - context->is_html = (g_strcmp0 (mime_type, "text/html") == 0); - - g_simple_async_result_complete (simple); - - g_object_unref (simple); -} - -void -e_mail_signature_combo_box_load_selected (EMailSignatureComboBox *combo_box, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - ESourceRegistry *registry; - LoadContext *context; - ESource *source; - const gchar *active_id; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box)); - - context = g_slice_new0 (LoadContext); - - simple = g_simple_async_result_new ( - G_OBJECT (combo_box), callback, user_data, - e_mail_signature_combo_box_load_selected); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) load_context_free); - - active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)); - - if (active_id == NULL) { - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0) { - mail_signature_combo_box_autogenerate (combo_box, context); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - registry = e_mail_signature_combo_box_get_registry (combo_box); - source = e_source_registry_ref_source (registry, active_id); - - /* If for some reason the ESource lookup fails, handle it as - * though "None" were selected. No need to report an error. */ - if (source == NULL) { - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - e_source_mail_signature_load ( - source, io_priority, cancellable, (GAsyncReadyCallback) - mail_signature_combo_box_load_cb, simple); - - g_object_unref (source); -} - -gboolean -e_mail_signature_combo_box_load_selected_finish (EMailSignatureComboBox *combo_box, - GAsyncResult *result, - gchar **contents, - gsize *length, - gboolean *is_html, - GError **error) -{ - GSimpleAsyncResult *simple; - LoadContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (combo_box), - e_mail_signature_combo_box_load_selected), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return FALSE; - - if (contents != NULL) { - *contents = context->contents; - context->contents = NULL; - } - - if (length != NULL) - *length = context->length; - - if (is_html != NULL) - *is_html = context->is_html; - - return TRUE; -} diff --git a/widgets/misc/e-mail-signature-combo-box.h b/widgets/misc/e-mail-signature-combo-box.h deleted file mode 100644 index d3ddaa9694..0000000000 --- a/widgets/misc/e-mail-signature-combo-box.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * e-mail-signature-combo-box.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_COMBO_BOX_H -#define E_MAIL_SIGNATURE_COMBO_BOX_H - -#include <gtk/gtk.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_COMBO_BOX \ - (e_mail_signature_combo_box_get_type ()) -#define E_MAIL_SIGNATURE_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_COMBO_BOX, EMailSignatureComboBox)) -#define E_MAIL_SIGNATURE_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_COMBO_BOX, EMailSignatureComboBoxClass)) -#define E_IS_MAIL_SIGNATURE_COMBO_BOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_COMBO_BOX)) -#define E_IS_MAIL_SIGNATURE_COMBO_BOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_COMBO_BOX)) -#define E_MAIL_SIGNATURE_COMBO_BOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_COMBO_BOX, EMailSignatureComboBoxClass)) - -#define E_MAIL_SIGNATURE_AUTOGENERATED_UID "autogenerated" - -G_BEGIN_DECLS - -typedef struct _EMailSignatureComboBox EMailSignatureComboBox; -typedef struct _EMailSignatureComboBoxClass EMailSignatureComboBoxClass; -typedef struct _EMailSignatureComboBoxPrivate EMailSignatureComboBoxPrivate; - -struct _EMailSignatureComboBox { - GtkComboBox parent; - EMailSignatureComboBoxPrivate *priv; -}; - -struct _EMailSignatureComboBoxClass { - GtkComboBoxClass parent_class; -}; - -GType e_mail_signature_combo_box_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_combo_box_new - (ESourceRegistry *registry); -void e_mail_signature_combo_box_refresh - (EMailSignatureComboBox *combo_box); -ESourceRegistry * - e_mail_signature_combo_box_get_registry - (EMailSignatureComboBox *combo_box); -const gchar * e_mail_signature_combo_box_get_identity_uid - (EMailSignatureComboBox *combo_box); -void e_mail_signature_combo_box_set_identity_uid - (EMailSignatureComboBox *combo_box, - const gchar *identity_uid); -void e_mail_signature_combo_box_load_selected - (EMailSignatureComboBox *combo_box, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_signature_combo_box_load_selected_finish - (EMailSignatureComboBox *combo_box, - GAsyncResult *result, - gchar **contents, - gsize *length, - gboolean *is_html, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_SIGNATURE_COMBO_BOX_H */ diff --git a/widgets/misc/e-mail-signature-editor.c b/widgets/misc/e-mail-signature-editor.c deleted file mode 100644 index 5e5910b013..0000000000 --- a/widgets/misc/e-mail-signature-editor.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * e-mail-signature-editor.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-editor.h" - -#include <string.h> -#include <glib/gi18n.h> - -#include <libevolution-utils/e-alert-dialog.h> -#include <libevolution-utils/e-alert-sink.h> -#include <misc/e-alert-bar.h> -#include <misc/e-web-view-gtkhtml.h> - -#define E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_EDITOR, EMailSignatureEditorPrivate)) - -typedef struct _AsyncContext AsyncContext; - -struct _EMailSignatureEditorPrivate { - GtkActionGroup *action_group; - EFocusTracker *focus_tracker; - GCancellable *cancellable; - ESourceRegistry *registry; - ESource *source; - gchar *original_name; - - GtkWidget *entry; /* not referenced */ - GtkWidget *alert_bar; /* not referenced */ -}; - -struct _AsyncContext { - ESource *source; - GCancellable *cancellable; - gchar *contents; - gsize length; -}; - -enum { - PROP_0, - PROP_FOCUS_TRACKER, - PROP_REGISTRY, - PROP_SOURCE -}; - -static const gchar *ui = -"<ui>\n" -" <menubar name='main-menu'>\n" -" <placeholder name='pre-edit-menu'>\n" -" <menu action='file-menu'>\n" -" <menuitem action='save-and-close'/>\n" -" <separator/>" -" <menuitem action='close'/>\n" -" </menu>\n" -" </placeholder>\n" -" </menubar>\n" -" <toolbar name='main-toolbar'>\n" -" <placeholder name='pre-main-toolbar'>\n" -" <toolitem action='save-and-close'/>\n" -" </placeholder>\n" -" </toolbar>\n" -"</ui>"; - -/* Forward Declarations */ -static void e_mail_signature_editor_alert_sink_init - (EAlertSinkInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EMailSignatureEditor, - e_mail_signature_editor, - GTKHTML_TYPE_EDITOR, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_mail_signature_editor_alert_sink_init)) - -static void -async_context_free (AsyncContext *async_context) -{ - if (async_context->source != NULL) - g_object_unref (async_context->source); - - if (async_context->cancellable != NULL) - g_object_unref (async_context->cancellable); - - g_free (async_context->contents); - - g_slice_free (AsyncContext, async_context); -} - -static void -mail_signature_editor_loaded_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - ESource *source; - EMailSignatureEditor *editor; - ESourceMailSignature *extension; - const gchar *extension_name; - const gchar *mime_type; - gchar *contents = NULL; - gboolean is_html; - GError *error = NULL; - - source = E_SOURCE (object); - editor = E_MAIL_SIGNATURE_EDITOR (user_data); - - e_source_mail_signature_load_finish ( - source, result, &contents, NULL, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (contents == NULL); - g_object_unref (editor); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (contents == NULL); - e_alert_submit ( - E_ALERT_SINK (editor), - "widgets:no-load-signature", - error->message, NULL); - g_object_unref (editor); - g_error_free (error); - return; - } - - g_return_if_fail (contents != NULL); - - /* The load operation should have set the MIME type. */ - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - mime_type = e_source_mail_signature_get_mime_type (extension); - is_html = (g_strcmp0 (mime_type, "text/html") == 0); - - gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), is_html); - - if (is_html) { - gtkhtml_editor_insert_html ( - GTKHTML_EDITOR (editor), contents); - } else { - gtkhtml_editor_insert_text ( - GTKHTML_EDITOR (editor), contents); - - gtkhtml_editor_run_command (GTKHTML_EDITOR (editor), "cursor-position-save"); - gtkhtml_editor_run_command (GTKHTML_EDITOR (editor), "select-all"); - gtkhtml_editor_run_command (GTKHTML_EDITOR (editor), "style-pre"); - gtkhtml_editor_run_command (GTKHTML_EDITOR (editor), "unselect-all"); - gtkhtml_editor_run_command (GTKHTML_EDITOR (editor), "cursor-position-restore"); - } - - g_free (contents); - - g_object_unref (editor); -} - -static gboolean -mail_signature_editor_delete_event_cb (EMailSignatureEditor *editor, - GdkEvent *event) -{ - GtkActionGroup *action_group; - GtkAction *action; - - action_group = editor->priv->action_group; - action = gtk_action_group_get_action (action_group, "close"); - gtk_action_activate (action); - - return TRUE; -} - -static void -action_close_cb (GtkAction *action, - EMailSignatureEditor *editor) -{ - gboolean something_changed = FALSE; - const gchar *original_name; - const gchar *signature_name; - - original_name = editor->priv->original_name; - signature_name = gtk_entry_get_text (GTK_ENTRY (editor->priv->entry)); - - something_changed |= gtkhtml_editor_has_undo (GTKHTML_EDITOR (editor)); - something_changed |= (strcmp (signature_name, original_name) != 0); - - if (something_changed) { - gint response; - - response = e_alert_run_dialog_for_args ( - GTK_WINDOW (editor), - "widgets:ask-signature-changed", NULL); - if (response == GTK_RESPONSE_YES) { - GtkActionGroup *action_group; - - action_group = editor->priv->action_group; - action = gtk_action_group_get_action ( - action_group, "save-and-close"); - gtk_action_activate (action); - return; - } else if (response == GTK_RESPONSE_CANCEL) - return; - } - - gtk_widget_destroy (GTK_WIDGET (editor)); -} - -static void -action_save_and_close_cb (GtkAction *action, - EMailSignatureEditor *editor) -{ - GtkEntry *entry; - EAsyncClosure *closure; - GAsyncResult *result; - ESource *source; - gchar *display_name; - GError *error = NULL; - - entry = GTK_ENTRY (editor->priv->entry); - source = e_mail_signature_editor_get_source (editor); - - display_name = g_strstrip (g_strdup (gtk_entry_get_text (entry))); - - /* Make sure the signature name is not blank. */ - if (*display_name == '\0') { - e_alert_submit ( - E_ALERT_SINK (editor), - "widgets:blank-signature", NULL); - gtk_widget_grab_focus (GTK_WIDGET (entry)); - g_free (display_name); - return; - } - - e_source_set_display_name (source, display_name); - - g_free (display_name); - - /* Cancel any ongoing load or save operations. */ - if (editor->priv->cancellable != NULL) { - g_cancellable_cancel (editor->priv->cancellable); - g_object_unref (editor->priv->cancellable); - } - - editor->priv->cancellable = g_cancellable_new (); - - closure = e_async_closure_new (); - - e_mail_signature_editor_commit ( - editor, editor->priv->cancellable, - e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - e_mail_signature_editor_commit_finish (editor, result, &error); - - e_async_closure_free (closure); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - - } else if (error != NULL) { - e_alert_submit ( - E_ALERT_SINK (editor), - "widgets:no-save-signature", - error->message, NULL); - g_error_free (error); - - /* Only destroy the editor if the save was successful. */ - } else { - gtk_widget_destroy (GTK_WIDGET (editor)); - } -} - -static GtkActionEntry entries[] = { - - { "close", - GTK_STOCK_CLOSE, - N_("_Close"), - "<Control>w", - N_("Close"), - G_CALLBACK (action_close_cb) }, - - { "save-and-close", - GTK_STOCK_SAVE, - N_("_Save and Close"), - "<Control>Return", - N_("Save and Close"), - G_CALLBACK (action_save_and_close_cb) }, - - { "file-menu", - NULL, - N_("_File"), - NULL, - NULL, - NULL } -}; - -static void -mail_signature_editor_set_registry (EMailSignatureEditor *editor, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (editor->priv->registry == NULL); - - editor->priv->registry = g_object_ref (registry); -} - -static void -mail_signature_editor_set_source (EMailSignatureEditor *editor, - ESource *source) -{ - GDBusObject *dbus_object = NULL; - const gchar *extension_name; - GError *error = NULL; - - g_return_if_fail (source == NULL || E_IS_SOURCE (source)); - g_return_if_fail (editor->priv->source == NULL); - - if (source != NULL) - dbus_object = e_source_ref_dbus_object (source); - - /* Clone the source so we can make changes to it freely. */ - editor->priv->source = e_source_new (dbus_object, NULL, &error); - - if (dbus_object != NULL) - g_object_unref (dbus_object); - - /* This should rarely fail. If the file was loaded successfully - * once then it should load successfully here as well, unless an - * I/O error occurs. */ - if (error != NULL) { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - - /* Make sure the source has a mail signature extension. */ - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - e_source_get_extension (editor->priv->source, extension_name); -} - -static void -mail_signature_editor_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - mail_signature_editor_set_registry ( - E_MAIL_SIGNATURE_EDITOR (object), - g_value_get_object (value)); - return; - - case PROP_SOURCE: - mail_signature_editor_set_source ( - E_MAIL_SIGNATURE_EDITOR (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_editor_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_FOCUS_TRACKER: - g_value_set_object ( - value, - e_mail_signature_editor_get_focus_tracker ( - E_MAIL_SIGNATURE_EDITOR (object))); - return; - - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_editor_get_registry ( - E_MAIL_SIGNATURE_EDITOR (object))); - return; - - case PROP_SOURCE: - g_value_set_object ( - value, - e_mail_signature_editor_get_source ( - E_MAIL_SIGNATURE_EDITOR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_editor_dispose (GObject *object) -{ - EMailSignatureEditorPrivate *priv; - - priv = E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE (object); - - if (priv->action_group != NULL) { - g_object_unref (priv->action_group); - priv->action_group = NULL; - } - - if (priv->focus_tracker != NULL) { - g_object_unref (priv->focus_tracker); - priv->focus_tracker = NULL; - } - - if (priv->cancellable != NULL) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - if (priv->registry != NULL) { - g_object_unref (priv->registry); - priv->registry = NULL; - } - - if (priv->source != NULL) { - g_object_unref (priv->source); - priv->source = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_editor_parent_class)-> - dispose (object); -} - -static void -mail_signature_editor_finalize (GObject *object) -{ - EMailSignatureEditorPrivate *priv; - - priv = E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE (object); - - g_free (priv->original_name); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_mail_signature_editor_parent_class)-> - finalize (object); -} - -static void -mail_signature_editor_constructed (GObject *object) -{ - EMailSignatureEditor *editor; - GtkActionGroup *action_group; - EFocusTracker *focus_tracker; - GtkhtmlEditor *gtkhtml_editor; - GtkUIManager *ui_manager; - GDBusObject *dbus_object; - ESource *source; - GtkAction *action; - GtkWidget *container; - GtkWidget *widget; - const gchar *display_name; - GError *error = NULL; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_signature_editor_parent_class)-> - constructed (object); - - editor = E_MAIL_SIGNATURE_EDITOR (object); - - gtkhtml_editor = GTKHTML_EDITOR (editor); - ui_manager = gtkhtml_editor_get_ui_manager (gtkhtml_editor); - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here implies a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); - - action_group = gtk_action_group_new ("signature"); - gtk_action_group_set_translation_domain ( - action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions ( - action_group, entries, - G_N_ELEMENTS (entries), editor); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - editor->priv->action_group = g_object_ref (action_group); - - /* Hide page properties because it is not inherited in the mail. */ - action = gtkhtml_editor_get_action (gtkhtml_editor, "properties-page"); - gtk_action_set_visible (action, FALSE); - - action = gtkhtml_editor_get_action ( - gtkhtml_editor, "context-properties-page"); - gtk_action_set_visible (action, FALSE); - - gtk_ui_manager_ensure_update (ui_manager); - - gtk_window_set_title (GTK_WINDOW (editor), _("Edit Signature")); - - /* Construct the signature name entry. */ - - container = gtkhtml_editor->vbox; - - widget = gtk_hbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (widget), 6); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - /* Position 2 should be between the main and style toolbars. */ - gtk_box_reorder_child (GTK_BOX (container), widget, 2); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_entry_new (); - gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0); - editor->priv->entry = widget; /* not referenced */ - gtk_widget_show (widget); - - widget = gtk_label_new_with_mnemonic (_("_Signature Name:")); - gtk_label_set_mnemonic_widget (GTK_LABEL (widget), editor->priv->entry); - gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_signal_connect ( - editor, "delete-event", - G_CALLBACK (mail_signature_editor_delete_event_cb), NULL); - - /* Construct the alert bar for errors. */ - - container = gtkhtml_editor->vbox; - - widget = e_alert_bar_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - /* Position 5 should be between the style toolbar and editing area. */ - gtk_box_reorder_child (GTK_BOX (container), widget, 5); - editor->priv->alert_bar = widget; /* not referenced */ - /* EAlertBar controls its own visibility. */ - - /* Configure an EFocusTracker to manage selection actions. - * - * XXX GtkhtmlEditor does not manage its own selection actions, - * which is technically a bug but works in our favor here - * because it won't cause any conflicts with EFocusTracker. */ - - focus_tracker = e_focus_tracker_new (GTK_WINDOW (editor)); - - action = gtkhtml_editor_get_action (gtkhtml_editor, "cut"); - e_focus_tracker_set_cut_clipboard_action (focus_tracker, action); - - action = gtkhtml_editor_get_action (gtkhtml_editor, "copy"); - e_focus_tracker_set_copy_clipboard_action (focus_tracker, action); - - action = gtkhtml_editor_get_action (gtkhtml_editor, "paste"); - e_focus_tracker_set_paste_clipboard_action (focus_tracker, action); - - action = gtkhtml_editor_get_action (gtkhtml_editor, "select-all"); - e_focus_tracker_set_select_all_action (focus_tracker, action); - - editor->priv->focus_tracker = focus_tracker; - - source = e_mail_signature_editor_get_source (editor); - - display_name = e_source_get_display_name (source); - if (display_name == NULL || *display_name == '\0') - display_name = _("Unnamed"); - - /* Set the entry text before we grab focus. */ - g_free (editor->priv->original_name); - editor->priv->original_name = g_strdup (display_name); - gtk_entry_set_text (GTK_ENTRY (editor->priv->entry), display_name); - - /* Set the focus appropriately. If this is a new signature, draw - * the user's attention to the signature name entry. Otherwise go - * straight to the editing area. */ - if (source == NULL) - gtk_widget_grab_focus (editor->priv->entry); - else { - GtkHTML *html; - - html = gtkhtml_editor_get_html (gtkhtml_editor); - gtk_widget_grab_focus (GTK_WIDGET (html)); - } - - /* Load file content only for an existing signature. - * (A new signature will not yet have a GDBusObject.) */ - dbus_object = e_source_ref_dbus_object (source); - if (dbus_object != NULL) { - GCancellable *cancellable; - - cancellable = g_cancellable_new (); - - e_source_mail_signature_load ( - source, - G_PRIORITY_DEFAULT, - cancellable, - mail_signature_editor_loaded_cb, - g_object_ref (editor)); - - g_warn_if_fail (editor->priv->cancellable == NULL); - editor->priv->cancellable = cancellable; - - g_object_unref (dbus_object); - } -} - -static void -mail_signature_editor_cut_clipboard (GtkhtmlEditor *editor) -{ - /* Do nothing. EFocusTracker handles this. */ -} - -static void -mail_signature_editor_copy_clipboard (GtkhtmlEditor *editor) -{ - /* Do nothing. EFocusTracker handles this. */ -} - -static void -mail_signature_editor_paste_clipboard (GtkhtmlEditor *editor) -{ - /* Do nothing. EFocusTracker handles this. */ -} - -static void -mail_signature_editor_select_all (GtkhtmlEditor *editor) -{ - /* Do nothing. EFocusTracker handles this. */ -} - -static void -mail_signature_editor_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - EMailSignatureEditorPrivate *priv; - EAlertBar *alert_bar; - GtkWidget *dialog; - GtkWindow *parent; - - priv = E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE (alert_sink); - - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - case GTK_MESSAGE_WARNING: - case GTK_MESSAGE_ERROR: - alert_bar = E_ALERT_BAR (priv->alert_bar); - e_alert_bar_add_alert (alert_bar, alert); - break; - - default: - parent = GTK_WINDOW (alert_sink); - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - break; - } -} - -static void -e_mail_signature_editor_class_init (EMailSignatureEditorClass *class) -{ - GObjectClass *object_class; - GtkhtmlEditorClass *editor_class; - - g_type_class_add_private (class, sizeof (EMailSignatureEditorPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_editor_set_property; - object_class->get_property = mail_signature_editor_get_property; - object_class->dispose = mail_signature_editor_dispose; - object_class->finalize = mail_signature_editor_finalize; - object_class->constructed = mail_signature_editor_constructed; - - editor_class = GTKHTML_EDITOR_CLASS (class); - editor_class->cut_clipboard = mail_signature_editor_cut_clipboard; - editor_class->copy_clipboard = mail_signature_editor_copy_clipboard; - editor_class->paste_clipboard = mail_signature_editor_paste_clipboard; - editor_class->select_all = mail_signature_editor_select_all; - - g_object_class_install_property ( - object_class, - PROP_FOCUS_TRACKER, - g_param_spec_object ( - "focus-tracker", - NULL, - NULL, - E_TYPE_FOCUS_TRACKER, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - "Data source registry", - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_SOURCE, - g_param_spec_object ( - "source", - NULL, - NULL, - E_TYPE_SOURCE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_mail_signature_editor_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = mail_signature_editor_submit_alert; -} - -static void -e_mail_signature_editor_init (EMailSignatureEditor *editor) -{ - editor->priv = E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE (editor); -} - -GtkWidget * -e_mail_signature_editor_new (ESourceRegistry *registry, - ESource *source) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - if (source != NULL) - g_return_val_if_fail (E_IS_SOURCE (source), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_EDITOR, - "html", e_web_view_gtkhtml_new (), - "registry", registry, - "source", source, NULL); -} - -EFocusTracker * -e_mail_signature_editor_get_focus_tracker (EMailSignatureEditor *editor) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor), NULL); - - return editor->priv->focus_tracker; -} - -ESourceRegistry * -e_mail_signature_editor_get_registry (EMailSignatureEditor *editor) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor), NULL); - - return editor->priv->registry; -} - -ESource * -e_mail_signature_editor_get_source (EMailSignatureEditor *editor) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor), NULL); - - return editor->priv->source; -} - -/********************** e_mail_signature_editor_commit() *********************/ - -static void -mail_signature_editor_replace_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - GError *error = NULL; - - simple = G_SIMPLE_ASYNC_RESULT (user_data); - - e_source_mail_signature_replace_finish ( - E_SOURCE (object), result, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - - g_object_unref (simple); -} - -static void -mail_signature_editor_commit_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *async_context; - GError *error = NULL; - - simple = G_SIMPLE_ASYNC_RESULT (user_data); - async_context = g_simple_async_result_get_op_res_gpointer (simple); - - e_source_registry_commit_source_finish ( - E_SOURCE_REGISTRY (object), result, &error); - - if (error != NULL) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); - return; - } - - /* We can call this on our scratch source because only its UID is - * really needed, which even a new scratch source already knows. */ - e_source_mail_signature_replace ( - async_context->source, - async_context->contents, - async_context->length, - G_PRIORITY_DEFAULT, - async_context->cancellable, - mail_signature_editor_replace_cb, - simple); -} - -void -e_mail_signature_editor_commit (EMailSignatureEditor *editor, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *async_context; - ESourceMailSignature *extension; - ESourceRegistry *registry; - ESource *source; - const gchar *extension_name; - const gchar *mime_type; - gchar *contents; - gboolean is_html; - gsize length; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor)); - - registry = e_mail_signature_editor_get_registry (editor); - source = e_mail_signature_editor_get_source (editor); - is_html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor)); - - if (is_html) { - mime_type = "text/html"; - contents = gtkhtml_editor_get_text_html ( - GTKHTML_EDITOR (editor), &length); - } else { - mime_type = "text/plain"; - contents = gtkhtml_editor_get_text_plain ( - GTKHTML_EDITOR (editor), &length); - } - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - e_source_mail_signature_set_mime_type (extension, mime_type); - - async_context = g_slice_new0 (AsyncContext); - async_context->source = g_object_ref (source); - async_context->contents = contents; /* takes ownership */ - async_context->length = length; - - if (G_IS_CANCELLABLE (cancellable)) - async_context->cancellable = g_object_ref (cancellable); - - simple = g_simple_async_result_new ( - G_OBJECT (editor), callback, user_data, - e_mail_signature_editor_commit); - - g_simple_async_result_set_op_res_gpointer ( - simple, async_context, (GDestroyNotify) async_context_free); - - e_source_registry_commit_source ( - registry, source, - async_context->cancellable, - mail_signature_editor_commit_cb, - simple); -} - -gboolean -e_mail_signature_editor_commit_finish (EMailSignatureEditor *editor, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (editor), - e_mail_signature_editor_commit), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - diff --git a/widgets/misc/e-mail-signature-editor.h b/widgets/misc/e-mail-signature-editor.h deleted file mode 100644 index 8f1be2dd0f..0000000000 --- a/widgets/misc/e-mail-signature-editor.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * e-mail-signature-editor.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_EDITOR_H -#define E_MAIL_SIGNATURE_EDITOR_H - -#include <gtkhtml-editor.h> -#include <misc/e-focus-tracker.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_EDITOR \ - (e_mail_signature_editor_get_type ()) -#define E_MAIL_SIGNATURE_EDITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_EDITOR, EMailSignatureEditor)) -#define E_MAIL_SIGNATURE_EDITOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_EDITOR, EMailSignatureEditorClass)) -#define E_IS_MAIL_SIGNATURE_EDITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_EDITOR)) -#define E_IS_MAIL_SIGNATURE_EDITOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_EDITOR)) -#define E_MAIL_SIGNATURE_EDITOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_EDITOR, EMailSignatureEditorClass)) - -G_BEGIN_DECLS - -typedef struct _EMailSignatureEditor EMailSignatureEditor; -typedef struct _EMailSignatureEditorClass EMailSignatureEditorClass; -typedef struct _EMailSignatureEditorPrivate EMailSignatureEditorPrivate; - -struct _EMailSignatureEditor { - GtkhtmlEditor parent; - EMailSignatureEditorPrivate *priv; -}; - -struct _EMailSignatureEditorClass { - GtkhtmlEditorClass parent_class; -}; - -GType e_mail_signature_editor_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_editor_new (ESourceRegistry *registry, - ESource *source); -EFocusTracker * e_mail_signature_editor_get_focus_tracker - (EMailSignatureEditor *editor); -ESourceRegistry * - e_mail_signature_editor_get_registry - (EMailSignatureEditor *editor); -ESource * e_mail_signature_editor_get_source - (EMailSignatureEditor *editor); -void e_mail_signature_editor_commit (EMailSignatureEditor *editor, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_signature_editor_commit_finish - (EMailSignatureEditor *editor, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_SIGNATURE_EDITOR_H */ diff --git a/widgets/misc/e-mail-signature-manager.c b/widgets/misc/e-mail-signature-manager.c deleted file mode 100644 index 66463336ea..0000000000 --- a/widgets/misc/e-mail-signature-manager.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * e-mail-signature-manager.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-manager.h" - -#include <glib/gi18n.h> -#include <glib/gstdio.h> -#include <gdk/gdkkeysyms.h> - -#include <libedataserver/libedataserver.h> - -#include "e-mail-signature-preview.h" -#include "e-mail-signature-tree-view.h" -#include "e-mail-signature-script-dialog.h" - -#define E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_MANAGER, EMailSignatureManagerPrivate)) - -#define PREVIEW_HEIGHT 200 - -struct _EMailSignatureManagerPrivate { - ESourceRegistry *registry; - - GtkWidget *tree_view; /* not referenced */ - GtkWidget *add_button; /* not referenced */ - GtkWidget *add_script_button; /* not referenced */ - GtkWidget *edit_button; /* not referenced */ - GtkWidget *remove_button; /* not referenced */ - GtkWidget *preview; /* not referenced */ - - gboolean prefer_html; -}; - -enum { - PROP_0, - PROP_PREFER_HTML, - PROP_REGISTRY -}; - -enum { - ADD_SIGNATURE, - ADD_SIGNATURE_SCRIPT, - EDITOR_CREATED, - EDIT_SIGNATURE, - REMOVE_SIGNATURE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE ( - EMailSignatureManager, - e_mail_signature_manager, - GTK_TYPE_PANED) - -static void -mail_signature_manager_emit_editor_created (EMailSignatureManager *manager, - GtkWidget *editor) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor)); - - g_signal_emit (manager, signals[EDITOR_CREATED], 0, editor); -} - -static gboolean -mail_signature_manager_key_press_event_cb (EMailSignatureManager *manager, - GdkEventKey *event) -{ - if (event->keyval == GDK_KEY_Delete) { - e_mail_signature_manager_remove_signature (manager); - return TRUE; - } - - return FALSE; -} - -static void -mail_signature_manager_run_script_dialog (EMailSignatureManager *manager, - ESource *source, - const gchar *title) -{ - ESourceRegistry *registry; - GtkWidget *dialog; - gpointer parent; - - registry = e_mail_signature_manager_get_registry (manager); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (manager)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - dialog = e_mail_signature_script_dialog_new (registry, parent, source); - gtk_window_set_title (GTK_WINDOW (dialog), title); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - EAsyncClosure *closure; - GAsyncResult *result; - GError *error = NULL; - - closure = e_async_closure_new (); - - /* FIXME Make this cancellable. */ - e_mail_signature_script_dialog_commit ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL, - e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - e_mail_signature_script_dialog_commit_finish ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), - result, &error); - - e_async_closure_free (closure); - - /* FIXME Make this into an EAlert. */ - if (error != NULL) { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - } - - gtk_widget_destroy (dialog); -} - -static void -mail_signature_manager_selection_changed_cb (EMailSignatureManager *manager, - GtkTreeSelection *selection) -{ - EMailSignaturePreview *preview; - EMailSignatureTreeView *tree_view; - ESource *source; - GtkWidget *edit_button; - GtkWidget *remove_button; - gboolean sensitive; - const gchar *uid = NULL; - - edit_button = manager->priv->edit_button; - remove_button = manager->priv->remove_button; - - tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); - source = e_mail_signature_tree_view_ref_selected_source (tree_view); - - if (source != NULL) - uid = e_source_get_uid (source); - - preview = E_MAIL_SIGNATURE_PREVIEW (manager->priv->preview); - e_mail_signature_preview_set_source_uid (preview, uid); - - sensitive = (source != NULL); - gtk_widget_set_sensitive (edit_button, sensitive); - gtk_widget_set_sensitive (remove_button, sensitive); - - if (source != NULL) - g_object_unref (source); -} - -static void -mail_signature_manager_set_registry (EMailSignatureManager *manager, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (manager->priv->registry == NULL); - - manager->priv->registry = g_object_ref (registry); -} - -static void -mail_signature_manager_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PREFER_HTML: - e_mail_signature_manager_set_prefer_html ( - E_MAIL_SIGNATURE_MANAGER (object), - g_value_get_boolean (value)); - return; - - case PROP_REGISTRY: - mail_signature_manager_set_registry ( - E_MAIL_SIGNATURE_MANAGER (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_manager_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PREFER_HTML: - g_value_set_boolean ( - value, - e_mail_signature_manager_get_prefer_html ( - E_MAIL_SIGNATURE_MANAGER (object))); - return; - - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_manager_get_registry ( - E_MAIL_SIGNATURE_MANAGER (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_manager_dispose (GObject *object) -{ - EMailSignatureManagerPrivate *priv; - - priv = E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE (object); - - if (priv->registry != NULL) { - g_object_unref (priv->registry); - priv->registry = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_manager_parent_class)-> - dispose (object); -} - -static void -mail_signature_manager_constructed (GObject *object) -{ - EMailSignatureManager *manager; - GtkTreeSelection *selection; - ESourceRegistry *registry; - GSettings *settings; - GtkWidget *container; - GtkWidget *widget; - GtkWidget *hbox; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_signature_manager_parent_class)-> - constructed (object); - - manager = E_MAIL_SIGNATURE_MANAGER (object); - registry = e_mail_signature_manager_get_registry (manager); - - gtk_orientable_set_orientation ( - GTK_ORIENTABLE (manager), GTK_ORIENTATION_VERTICAL); - - container = GTK_WIDGET (manager); - - widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 12, 0, 0); - gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_hbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = hbox = 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_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = e_mail_signature_tree_view_new (registry); - gtk_container_add (GTK_CONTAINER (container), widget); - manager->priv->tree_view = widget; /* not referenced */ - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "key-press-event", - G_CALLBACK (mail_signature_manager_key_press_event_cb), - manager); - - g_signal_connect_swapped ( - widget, "row-activated", - G_CALLBACK (e_mail_signature_manager_edit_signature), - manager); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); - - g_signal_connect_swapped ( - selection, "changed", - G_CALLBACK (mail_signature_manager_selection_changed_cb), - manager); - - container = hbox; - - widget = gtk_vbutton_box_new (); - gtk_button_box_set_layout ( - GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START); - gtk_box_set_spacing (GTK_BOX (widget), 6); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_button_new_from_stock (GTK_STOCK_ADD); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - manager->priv->add_button = widget; /* not referenced */ - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (e_mail_signature_manager_add_signature), - manager); - - widget = gtk_button_new_with_mnemonic (_("Add _Script")); - gtk_button_set_image ( - GTK_BUTTON (widget), gtk_image_new_from_stock ( - GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON)); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - manager->priv->add_script_button = widget; /* not referenced */ - gtk_widget_show (widget); - - settings = g_settings_new ("org.gnome.desktop.lockdown"); - - g_settings_bind ( - settings, "disable-command-line", - widget, "visible", - G_SETTINGS_BIND_GET | - G_SETTINGS_BIND_INVERT_BOOLEAN); - - g_object_unref (settings); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (e_mail_signature_manager_add_signature_script), - manager); - - widget = gtk_button_new_from_stock (GTK_STOCK_EDIT); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - manager->priv->edit_button = widget; /* not referenced */ - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (e_mail_signature_manager_edit_signature), - manager); - - widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - manager->priv->remove_button = widget; /* not referenced */ - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (e_mail_signature_manager_remove_signature), - manager); - - container = GTK_WIDGET (manager); - - 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_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE); - gtk_widget_show (widget); - - container = widget; - - widget = e_mail_signature_preview_new (registry); - gtk_container_add (GTK_CONTAINER (container), widget); - manager->priv->preview = widget; /* not referenced */ - gtk_widget_show (widget); - - gtk_paned_set_position (GTK_PANED (manager), PREVIEW_HEIGHT); -} - -static void -mail_signature_manager_add_signature (EMailSignatureManager *manager) -{ - ESourceRegistry *registry; - GtkWidget *editor; - - registry = e_mail_signature_manager_get_registry (manager); - - editor = e_mail_signature_editor_new (registry, NULL); - gtkhtml_editor_set_html_mode ( - GTKHTML_EDITOR (editor), manager->priv->prefer_html); - mail_signature_manager_emit_editor_created (manager, editor); - - gtk_widget_grab_focus (manager->priv->tree_view); -} - -static void -mail_signature_manager_add_signature_script (EMailSignatureManager *manager) -{ - const gchar *title; - - title = _("Add Signature Script"); - mail_signature_manager_run_script_dialog (manager, NULL, title); - - gtk_widget_grab_focus (manager->priv->tree_view); -} - -static void -mail_signature_manager_editor_created (EMailSignatureManager *manager, - EMailSignatureEditor *editor) -{ - GtkWindowPosition position; - gpointer parent; - - position = GTK_WIN_POS_CENTER_ON_PARENT; - parent = gtk_widget_get_toplevel (GTK_WIDGET (manager)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - gtk_window_set_transient_for (GTK_WINDOW (editor), parent); - gtk_window_set_position (GTK_WINDOW (editor), position); - gtk_widget_show (GTK_WIDGET (editor)); -} - -static void -mail_signature_manager_edit_signature (EMailSignatureManager *manager) -{ - EMailSignatureTreeView *tree_view; - ESourceMailSignature *extension; - ESourceRegistry *registry; - GtkWidget *editor; - ESource *source; - GFileInfo *file_info; - GFile *file; - const gchar *attribute; - const gchar *extension_name; - const gchar *title; - GError *error = NULL; - - registry = e_mail_signature_manager_get_registry (manager); - tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); - source = e_mail_signature_tree_view_ref_selected_source (tree_view); - g_return_if_fail (source != NULL); - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - file = e_source_mail_signature_get_file (extension); - - attribute = G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE; - - /* XXX This blocks but it should just be a local file. */ - file_info = g_file_query_info ( - file, attribute, G_FILE_QUERY_INFO_NONE, NULL, &error); - - /* FIXME Make this into an EAlert. */ - if (error != NULL) { - g_warn_if_fail (file_info == NULL); - g_warning ("%s: %s", G_STRFUNC, error->message); - g_object_unref (source); - g_error_free (error); - return; - } - - if (g_file_info_get_attribute_boolean (file_info, attribute)) - goto script; - - editor = e_mail_signature_editor_new (registry, source); - mail_signature_manager_emit_editor_created (manager, editor); - - goto exit; - -script: - title = _("Edit Signature Script"); - mail_signature_manager_run_script_dialog (manager, source, title); - -exit: - gtk_widget_grab_focus (GTK_WIDGET (tree_view)); - - g_object_unref (file_info); - g_object_unref (source); -} - -static void -mail_signature_manager_remove_signature (EMailSignatureManager *manager) -{ - EMailSignatureTreeView *tree_view; - ESourceMailSignature *extension; - ESource *source; - GFile *file; - const gchar *extension_name; - GError *error = NULL; - - tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); - source = e_mail_signature_tree_view_ref_selected_source (tree_view); - - if (source == NULL) - return; - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - - file = e_source_mail_signature_get_file (extension); - - /* XXX This blocks but it should just be a local file. */ - if (!g_file_delete (file, NULL, &error)) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - /* Remove the mail signature data source asynchronously. - * XXX No callback function because there's not much we can do - * if this fails. We should probably implement EAlertSink. */ - e_source_remove (source, NULL, NULL, NULL); - - gtk_widget_grab_focus (GTK_WIDGET (tree_view)); - - g_object_unref (source); -} - -static void -e_mail_signature_manager_class_init (EMailSignatureManagerClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private ( - class, sizeof (EMailSignatureManagerPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_manager_set_property; - object_class->get_property = mail_signature_manager_get_property; - object_class->dispose = mail_signature_manager_dispose; - object_class->constructed = mail_signature_manager_constructed; - - class->add_signature = mail_signature_manager_add_signature; - class->add_signature_script = - mail_signature_manager_add_signature_script; - class->editor_created = mail_signature_manager_editor_created; - class->edit_signature = mail_signature_manager_edit_signature; - class->remove_signature = mail_signature_manager_remove_signature; - - g_object_class_install_property ( - object_class, - PROP_PREFER_HTML, - g_param_spec_boolean ( - "prefer-html", - "Prefer HTML", - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - NULL, - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - signals[ADD_SIGNATURE] = g_signal_new ( - "add-signature", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EMailSignatureManagerClass, add_signature), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[ADD_SIGNATURE_SCRIPT] = g_signal_new ( - "add-signature-script", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET ( - EMailSignatureManagerClass, add_signature_script), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[EDITOR_CREATED] = g_signal_new ( - "editor-created", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EMailSignatureManagerClass, editor_created), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_MAIL_SIGNATURE_EDITOR); - - signals[EDIT_SIGNATURE] = g_signal_new ( - "edit-signature", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EMailSignatureManagerClass, edit_signature), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[REMOVE_SIGNATURE] = g_signal_new ( - "remove-signature", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EMailSignatureManagerClass, remove_signature), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_mail_signature_manager_init (EMailSignatureManager *manager) -{ - manager->priv = E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE (manager); -} - -GtkWidget * -e_mail_signature_manager_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_MANAGER, - "registry", registry, NULL); -} - -void -e_mail_signature_manager_add_signature (EMailSignatureManager *manager) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); - - g_signal_emit (manager, signals[ADD_SIGNATURE], 0); -} - -void -e_mail_signature_manager_add_signature_script (EMailSignatureManager *manager) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); - - g_signal_emit (manager, signals[ADD_SIGNATURE_SCRIPT], 0); -} - -void -e_mail_signature_manager_edit_signature (EMailSignatureManager *manager) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); - - g_signal_emit (manager, signals[EDIT_SIGNATURE], 0); -} - -void -e_mail_signature_manager_remove_signature (EMailSignatureManager *manager) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); - - g_signal_emit (manager, signals[REMOVE_SIGNATURE], 0); -} - -gboolean -e_mail_signature_manager_get_prefer_html (EMailSignatureManager *manager) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager), FALSE); - - return manager->priv->prefer_html; -} - -void -e_mail_signature_manager_set_prefer_html (EMailSignatureManager *manager, - gboolean prefer_html) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); - - if (manager->priv->prefer_html == prefer_html) - return; - - manager->priv->prefer_html = prefer_html; - - g_object_notify (G_OBJECT (manager), "prefer-html"); -} - -ESourceRegistry * -e_mail_signature_manager_get_registry (EMailSignatureManager *manager) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager), NULL); - - return manager->priv->registry; -} diff --git a/widgets/misc/e-mail-signature-manager.h b/widgets/misc/e-mail-signature-manager.h deleted file mode 100644 index a627bd57fa..0000000000 --- a/widgets/misc/e-mail-signature-manager.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * e-mail-signature-manager.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_MANAGER_H -#define E_MAIL_SIGNATURE_MANAGER_H - -#include <gtk/gtk.h> -#include <misc/e-mail-signature-editor.h> -#include <misc/e-mail-signature-tree-view.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_MANAGER \ - (e_mail_signature_manager_get_type ()) -#define E_MAIL_SIGNATURE_MANAGER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_MANAGER, EMailSignatureManager)) -#define E_MAIL_SIGNATURE_MANAGER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_MANAGER, EMailSignatureManagerClass)) -#define E_IS_MAIL_SIGNATURE_MANAGER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_MANAGER)) -#define E_IS_MAIL_SIGNATURE_MANAGER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_MANAGER)) -#define E_MAIL_SIGNATURE_MANAGER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_MANAGER, EMailSignatureManagerClass)) - -G_BEGIN_DECLS - -typedef struct _EMailSignatureManager EMailSignatureManager; -typedef struct _EMailSignatureManagerClass EMailSignatureManagerClass; -typedef struct _EMailSignatureManagerPrivate EMailSignatureManagerPrivate; - -struct _EMailSignatureManager { - GtkPaned parent; - EMailSignatureManagerPrivate *priv; -}; - -struct _EMailSignatureManagerClass { - GtkPanedClass parent_class; - - void (*add_signature) (EMailSignatureManager *manager); - void (*add_signature_script) (EMailSignatureManager *manager); - void (*editor_created) (EMailSignatureManager *manager, - EMailSignatureEditor *editor); - void (*edit_signature) (EMailSignatureManager *manager); - void (*remove_signature) (EMailSignatureManager *manager); -}; - -GType e_mail_signature_manager_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_manager_new - (ESourceRegistry *registry); -void e_mail_signature_manager_add_signature - (EMailSignatureManager *manager); -void e_mail_signature_manager_add_signature_script - (EMailSignatureManager *manager); -void e_mail_signature_manager_edit_signature - (EMailSignatureManager *manager); -void e_mail_signature_manager_remove_signature - (EMailSignatureManager *manager); -gboolean e_mail_signature_manager_get_prefer_html - (EMailSignatureManager *manager); -void e_mail_signature_manager_set_prefer_html - (EMailSignatureManager *manager, - gboolean prefer_html); -ESourceRegistry * - e_mail_signature_manager_get_registry - (EMailSignatureManager *manager); - -#endif /* E_MAIL_SIGNATURE_MANAGER_H */ diff --git a/widgets/misc/e-mail-signature-preview.c b/widgets/misc/e-mail-signature-preview.c deleted file mode 100644 index 0e7500c5ae..0000000000 --- a/widgets/misc/e-mail-signature-preview.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * e-mail-signature-preview.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-preview.h" - -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <glib/gstdio.h> - -#include <libevolution-utils/e-alert-sink.h> - -#define E_MAIL_SIGNATURE_PREVIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_PREVIEW, EMailSignaturePreviewPrivate)) - -#define SOURCE_IS_MAIL_SIGNATURE(source) \ - (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_SIGNATURE)) - -struct _EMailSignaturePreviewPrivate { - ESourceRegistry *registry; - GCancellable *cancellable; - gchar *source_uid; -}; - -enum { - PROP_0, - PROP_REGISTRY, - PROP_SOURCE_UID -}; - -enum { - REFRESH, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE ( - EMailSignaturePreview, - e_mail_signature_preview, - E_TYPE_WEB_VIEW) - -static void -mail_signature_preview_load_cb (ESource *source, - GAsyncResult *result, - EMailSignaturePreview *preview) -{ - ESourceMailSignature *extension; - const gchar *extension_name; - const gchar *mime_type; - gchar *contents = NULL; - GError *error = NULL; - - e_source_mail_signature_load_finish ( - source, result, &contents, NULL, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (contents == NULL); - g_object_unref (preview); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (contents == NULL); - e_alert_submit ( - E_ALERT_SINK (preview), - "widgets:no-load-signature", - error->message, NULL); - g_object_unref (preview); - g_error_free (error); - return; - } - - g_return_if_fail (contents != NULL); - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - mime_type = e_source_mail_signature_get_mime_type (extension); - - if (g_strcmp0 (mime_type, "text/html") == 0) - e_web_view_load_string (E_WEB_VIEW (preview), contents); - else { - gchar *string; - - string = g_markup_printf_escaped ("<pre>%s</pre>", contents); - e_web_view_load_string (E_WEB_VIEW (preview), string); - g_free (string); - } - - g_free (contents); - - g_object_unref (preview); -} - -static void -mail_signature_preview_set_registry (EMailSignaturePreview *preview, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (preview->priv->registry == NULL); - - preview->priv->registry = g_object_ref (registry); -} - -static void -mail_signature_preview_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - mail_signature_preview_set_registry ( - E_MAIL_SIGNATURE_PREVIEW (object), - g_value_get_object (value)); - return; - - case PROP_SOURCE_UID: - e_mail_signature_preview_set_source_uid ( - E_MAIL_SIGNATURE_PREVIEW (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_preview_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_preview_get_registry ( - E_MAIL_SIGNATURE_PREVIEW (object))); - return; - - case PROP_SOURCE_UID: - g_value_set_string ( - value, - e_mail_signature_preview_get_source_uid ( - E_MAIL_SIGNATURE_PREVIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_preview_dispose (GObject *object) -{ - EMailSignaturePreviewPrivate *priv; - - priv = E_MAIL_SIGNATURE_PREVIEW_GET_PRIVATE (object); - - if (priv->registry != NULL) { - g_object_unref (priv->registry); - priv->registry = NULL; - } - - if (priv->cancellable != NULL) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_preview_parent_class)-> - dispose (object); -} - -static void -mail_signature_preview_finalize (GObject *object) -{ - EMailSignaturePreviewPrivate *priv; - - priv = E_MAIL_SIGNATURE_PREVIEW_GET_PRIVATE (object); - - g_free (priv->source_uid); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_mail_signature_preview_parent_class)-> - finalize (object); -} - -static void -mail_signature_preview_refresh (EMailSignaturePreview *preview) -{ - ESourceRegistry *registry; - ESource *source; - const gchar *extension_name; - const gchar *source_uid; - - /* Cancel any unfinished refreshes. */ - if (preview->priv->cancellable != NULL) { - g_cancellable_cancel (preview->priv->cancellable); - g_object_unref (preview->priv->cancellable); - preview->priv->cancellable = NULL; - } - - source_uid = e_mail_signature_preview_get_source_uid (preview); - - if (source_uid == NULL) - goto fail; - - registry = e_mail_signature_preview_get_registry (preview); - source = e_source_registry_ref_source (registry, source_uid); - - if (source == NULL) - goto fail; - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - if (!e_source_has_extension (source, extension_name)) { - g_object_unref (source); - goto fail; - } - - preview->priv->cancellable = g_cancellable_new (); - - e_source_mail_signature_load ( - source, G_PRIORITY_DEFAULT, - preview->priv->cancellable, (GAsyncReadyCallback) - mail_signature_preview_load_cb, g_object_ref (preview)); - - g_object_unref (source); - - return; - -fail: - e_web_view_clear (E_WEB_VIEW (preview)); -} - -static void -e_mail_signature_preview_class_init (EMailSignaturePreviewClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EMailSignaturePreviewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_preview_set_property; - object_class->get_property = mail_signature_preview_get_property; - object_class->dispose = mail_signature_preview_dispose; - object_class->finalize = mail_signature_preview_finalize; - - class->refresh = mail_signature_preview_refresh; - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - NULL, - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_SOURCE_UID, - g_param_spec_string ( - "source-uid", - "Source UID", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - signals[REFRESH] = g_signal_new ( - "refresh", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EMailSignaturePreviewClass, refresh), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_mail_signature_preview_init (EMailSignaturePreview *preview) -{ - preview->priv = E_MAIL_SIGNATURE_PREVIEW_GET_PRIVATE (preview); -} - -GtkWidget * -e_mail_signature_preview_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_PREVIEW, - "registry", registry, NULL); -} - -void -e_mail_signature_preview_refresh (EMailSignaturePreview *preview) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_PREVIEW (preview)); - - g_signal_emit (preview, signals[REFRESH], 0); -} - -ESourceRegistry * -e_mail_signature_preview_get_registry (EMailSignaturePreview *preview) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_PREVIEW (preview), NULL); - - return preview->priv->registry; -} - -const gchar * -e_mail_signature_preview_get_source_uid (EMailSignaturePreview *preview) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_PREVIEW (preview), NULL); - - return preview->priv->source_uid; -} - -void -e_mail_signature_preview_set_source_uid (EMailSignaturePreview *preview, - const gchar *source_uid) -{ - g_return_if_fail (E_IS_MAIL_SIGNATURE_PREVIEW (preview)); - - /* Avoid repeatedly loading the same signature file. */ - if (g_strcmp0 (source_uid, preview->priv->source_uid) == 0) - return; - - g_free (preview->priv->source_uid); - preview->priv->source_uid = g_strdup (source_uid); - - g_object_notify (G_OBJECT (preview), "source-uid"); - - e_mail_signature_preview_refresh (preview); -} diff --git a/widgets/misc/e-mail-signature-preview.h b/widgets/misc/e-mail-signature-preview.h deleted file mode 100644 index fff4c64d3d..0000000000 --- a/widgets/misc/e-mail-signature-preview.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * e-mail-signature-preview.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_PREVIEW_H -#define E_MAIL_SIGNATURE_PREVIEW_H - -#include <misc/e-web-view.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_PREVIEW \ - (e_mail_signature_preview_get_type ()) -#define E_MAIL_SIGNATURE_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_PREVIEW, EMailSignaturePreview)) -#define E_MAIL_SIGNATURE_PREVIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_PREVIEW, EMailSignaturePreviewClass)) -#define E_IS_MAIL_SIGNATURE_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_PREVIEW)) -#define E_IS_MAIL_SIGNATURE_PREVIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_PREVIEW)) -#define E_MAIL_SIGNATURE_PREVIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_PREVIEW, EMailSignaturePreview)) - -G_BEGIN_DECLS - -typedef struct _EMailSignaturePreview EMailSignaturePreview; -typedef struct _EMailSignaturePreviewClass EMailSignaturePreviewClass; -typedef struct _EMailSignaturePreviewPrivate EMailSignaturePreviewPrivate; - -struct _EMailSignaturePreview { - EWebView parent; - EMailSignaturePreviewPrivate *priv; -}; - -struct _EMailSignaturePreviewClass { - EWebViewClass parent_class; - - /* Signals */ - void (*refresh) (EMailSignaturePreview *preview); -}; - -GType e_mail_signature_preview_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_preview_new - (ESourceRegistry *registry); -void e_mail_signature_preview_refresh - (EMailSignaturePreview *preview); -ESourceRegistry * - e_mail_signature_preview_get_registry - (EMailSignaturePreview *preview); -const gchar * e_mail_signature_preview_get_source_uid - (EMailSignaturePreview *preview); -void e_mail_signature_preview_set_source_uid - (EMailSignaturePreview *preview, - const gchar *source_uid); - -G_END_DECLS - -#endif /* E_MAIL_SIGNATURE_PREVIEW_H */ diff --git a/widgets/misc/e-mail-signature-script-dialog.c b/widgets/misc/e-mail-signature-script-dialog.c deleted file mode 100644 index 58e8c43157..0000000000 --- a/widgets/misc/e-mail-signature-script-dialog.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * e-mail-signature-script-dialog.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-script-dialog.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#define E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, \ - EMailSignatureScriptDialogPrivate)) - -typedef struct _AsyncContext AsyncContext; - -struct _EMailSignatureScriptDialogPrivate { - ESourceRegistry *registry; - ESource *source; - - GtkWidget *entry; /* not referenced */ - GtkWidget *file_chooser; /* not referenced */ - GtkWidget *alert; /* not referenced */ - - gchar *symlink_target; -}; - -struct _AsyncContext { - ESource *source; - GCancellable *cancellable; - gchar *symlink_target; -}; - -enum { - PROP_0, - PROP_REGISTRY, - PROP_SOURCE, - PROP_SYMLINK_TARGET -}; - -G_DEFINE_TYPE ( - EMailSignatureScriptDialog, - e_mail_signature_script_dialog, - GTK_TYPE_DIALOG) - -static void -async_context_free (AsyncContext *async_context) -{ - if (async_context->source != NULL) - g_object_unref (async_context->source); - - if (async_context->cancellable != NULL) - g_object_unref (async_context->cancellable); - - g_free (async_context->symlink_target); - - g_slice_free (AsyncContext, async_context); -} - -static gboolean -mail_signature_script_dialog_filter_cb (const GtkFileFilterInfo *filter_info) -{ - return g_file_test (filter_info->filename, G_FILE_TEST_IS_EXECUTABLE); -} - -static void -mail_signature_script_dialog_update_status (EMailSignatureScriptDialog *dialog) -{ - ESource *source; - const gchar *display_name; - const gchar *symlink_target; - gboolean show_alert; - gboolean sensitive; - - source = e_mail_signature_script_dialog_get_source (dialog); - - display_name = e_source_get_display_name (source); - sensitive = (display_name != NULL && *display_name != '\0'); - - symlink_target = - e_mail_signature_script_dialog_get_symlink_target (dialog); - - if (symlink_target != NULL) { - gboolean executable; - - executable = g_file_test ( - symlink_target, G_FILE_TEST_IS_EXECUTABLE); - - show_alert = !executable; - sensitive &= executable; - } else { - sensitive = FALSE; - show_alert = FALSE; - } - - if (show_alert) - gtk_widget_show (dialog->priv->alert); - else - gtk_widget_hide (dialog->priv->alert); - - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); -} - -static void -mail_signature_script_dialog_file_set_cb (GtkFileChooserButton *button, - EMailSignatureScriptDialog *dialog) -{ - ESource *source; - ESourceMailSignature *extension; - GtkFileChooser *file_chooser; - const gchar *extension_name; - gchar *filename; - - file_chooser = GTK_FILE_CHOOSER (button); - filename = gtk_file_chooser_get_filename (file_chooser); - - g_free (dialog->priv->symlink_target); - dialog->priv->symlink_target = filename; /* takes ownership */ - - /* Invalidate the saved MIME type. */ - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - source = e_mail_signature_script_dialog_get_source (dialog); - extension = e_source_get_extension (source, extension_name); - e_source_mail_signature_set_mime_type (extension, NULL); - - g_object_notify (G_OBJECT (dialog), "symlink-target"); - - mail_signature_script_dialog_update_status (dialog); -} - -static void -mail_signature_script_dialog_query_cb (GFile *file, - GAsyncResult *result, - EMailSignatureScriptDialog *dialog) -{ - GFileInfo *file_info; - const gchar *symlink_target; - GError *error = NULL; - - file_info = g_file_query_info_finish (file, result, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (file_info == NULL); - g_object_unref (dialog); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (file_info == NULL); - g_warning ("%s", error->message); - g_object_unref (dialog); - g_error_free (error); - return; - } - - g_return_if_fail (G_IS_FILE_INFO (file_info)); - - symlink_target = g_file_info_get_symlink_target (file_info); - - e_mail_signature_script_dialog_set_symlink_target ( - dialog, symlink_target); - - g_object_unref (file_info); - g_object_unref (dialog); -} - -static void -mail_signature_script_dialog_set_registry (EMailSignatureScriptDialog *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 -mail_signature_script_dialog_set_source (EMailSignatureScriptDialog *dialog, - ESource *source) -{ - GDBusObject *dbus_object = NULL; - const gchar *extension_name; - GError *error = NULL; - - g_return_if_fail (source == NULL || E_IS_SOURCE (source)); - g_return_if_fail (dialog->priv->source == NULL); - - if (source != NULL) - dbus_object = e_source_ref_dbus_object (source); - - /* Clone the source so we can make changes to it freely. */ - dialog->priv->source = e_source_new (dbus_object, NULL, &error); - - /* This should rarely fail. If the file was loaded successfully - * once then it should load successfully here as well, unless an - * I/O error occurs. */ - if (error != NULL) { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - - /* Make sure the source has a mail signature extension. */ - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - e_source_get_extension (dialog->priv->source, extension_name); - - /* If we're editing an existing signature, query the symbolic - * link target of the signature file so we can initialize the - * file chooser button. Note: The asynchronous callback will - * run after the dialog initialization is complete. */ - if (dbus_object != NULL) { - ESourceMailSignature *extension; - const gchar *extension_name; - GFile *file; - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - extension = e_source_get_extension (source, extension_name); - file = e_source_mail_signature_get_file (extension); - - g_file_query_info_async ( - file, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, - G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, - NULL, (GAsyncReadyCallback) - mail_signature_script_dialog_query_cb, - g_object_ref (dialog)); - - g_object_unref (dbus_object); - } -} - -static void -mail_signature_script_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - mail_signature_script_dialog_set_registry ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object), - g_value_get_object (value)); - return; - - case PROP_SOURCE: - mail_signature_script_dialog_set_source ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object), - g_value_get_object (value)); - return; - - case PROP_SYMLINK_TARGET: - e_mail_signature_script_dialog_set_symlink_target ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_script_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_script_dialog_get_registry ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object))); - return; - - case PROP_SOURCE: - g_value_set_object ( - value, - e_mail_signature_script_dialog_get_source ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object))); - return; - - case PROP_SYMLINK_TARGET: - g_value_set_string ( - value, - e_mail_signature_script_dialog_get_symlink_target ( - E_MAIL_SIGNATURE_SCRIPT_DIALOG (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_script_dialog_dispose (GObject *object) -{ - EMailSignatureScriptDialogPrivate *priv; - - priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object); - - if (priv->registry != NULL) { - g_object_unref (priv->registry); - priv->registry = NULL; - } - - if (priv->source != NULL) { - g_object_unref (priv->source); - priv->source = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)-> - dispose (object); -} - -static void -mail_signature_script_dialog_finalize (GObject *object) -{ - EMailSignatureScriptDialogPrivate *priv; - - priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object); - - g_free (priv->symlink_target); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)-> - finalize (object); -} - -static void -mail_signature_script_dialog_constructed (GObject *object) -{ - EMailSignatureScriptDialog *dialog; - GtkFileFilter *filter; - GtkWidget *container; - GtkWidget *widget; - ESource *source; - const gchar *display_name; - gchar *markup; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)-> - constructed (object); - - dialog = E_MAIL_SIGNATURE_SCRIPT_DIALOG (object); - - source = e_mail_signature_script_dialog_get_source (dialog); - display_name = e_source_get_display_name (source); - - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - - gtk_dialog_add_button ( - GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - - gtk_dialog_add_button ( - GTK_DIALOG (dialog), - GTK_STOCK_SAVE, GTK_RESPONSE_OK); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - - container = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - - widget = gtk_table_new (4, 2, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (widget), 6); - gtk_table_set_row_spacings (GTK_TABLE (widget), 6); - gtk_table_set_row_spacing (GTK_TABLE (widget), 0, 12); - gtk_container_set_border_width (GTK_CONTAINER (widget), 5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new_from_stock ( - GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 0, 1, 0, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_label_new (_( - "The output of this script will be used as your\n" - "signature. The name you specify will be used\n" - "for display purposes only.")); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (widget), display_name); - gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->entry = widget; /* not referenced */ - gtk_widget_show (widget); - - g_object_bind_property ( - widget, "text", - source, "display-name", - G_BINDING_DEFAULT); - - widget = gtk_label_new_with_mnemonic (_("_Name:")); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), dialog->priv->entry); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_file_chooser_button_new ( - NULL, GTK_FILE_CHOOSER_ACTION_OPEN); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->file_chooser = widget; /* not referenced */ - gtk_widget_show (widget); - - /* Restrict file selection to executable files. */ - filter = gtk_file_filter_new (); - gtk_file_filter_add_custom ( - filter, GTK_FILE_FILTER_FILENAME, - (GtkFileFilterFunc) mail_signature_script_dialog_filter_cb, - NULL, NULL); - gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter); - - /* We create symbolic links to script files from the "signatures" - * directory, so restrict the selection to local files only. */ - gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); - - widget = gtk_label_new_with_mnemonic (_("S_cript:")); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), dialog->priv->file_chooser); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - /* This is just a placeholder. */ - widget = gtk_label_new (NULL); - gtk_table_attach ( - GTK_TABLE (container), widget, - 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - widget = gtk_hbox_new (FALSE, 6); - gtk_table_attach ( - GTK_TABLE (container), widget, - 1, 2, 3, 4, 0, 0, 0, 0); - dialog->priv->alert = widget; /* not referenced */ - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new_from_stock ( - GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - markup = g_markup_printf_escaped ( - "<small>%s</small>", - _("Script file must be executable.")); - widget = gtk_label_new (markup); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - g_free (markup); - - g_signal_connect ( - dialog->priv->file_chooser, "file-set", - G_CALLBACK (mail_signature_script_dialog_file_set_cb), dialog); - - g_signal_connect_swapped ( - dialog->priv->entry, "changed", - G_CALLBACK (mail_signature_script_dialog_update_status), dialog); - - mail_signature_script_dialog_update_status (dialog); -} - -static void -e_mail_signature_script_dialog_class_init (EMailSignatureScriptDialogClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private ( - class, sizeof (EMailSignatureScriptDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_script_dialog_set_property; - object_class->get_property = mail_signature_script_dialog_get_property; - object_class->dispose = mail_signature_script_dialog_dispose; - object_class->finalize = mail_signature_script_dialog_finalize; - object_class->constructed = mail_signature_script_dialog_constructed; - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - "Data source registry", - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_SOURCE, - g_param_spec_object ( - "source", - "Source", - NULL, - E_TYPE_SOURCE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_SYMLINK_TARGET, - g_param_spec_string ( - "symlink-target", - "Symlink Target", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_mail_signature_script_dialog_init (EMailSignatureScriptDialog *dialog) -{ - dialog->priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog); -} - -GtkWidget * -e_mail_signature_script_dialog_new (ESourceRegistry *registry, - GtkWindow *parent, - ESource *source) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - if (source != NULL) - g_return_val_if_fail (E_IS_SOURCE (source), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, - "registry", registry, - "transient-for", parent, - "source", source, NULL); -} - -ESourceRegistry * -e_mail_signature_script_dialog_get_registry (EMailSignatureScriptDialog *dialog) -{ - g_return_val_if_fail ( - E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL); - - return dialog->priv->registry; -} - -ESource * -e_mail_signature_script_dialog_get_source (EMailSignatureScriptDialog *dialog) -{ - g_return_val_if_fail ( - E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL); - - return dialog->priv->source; -} - -const gchar * -e_mail_signature_script_dialog_get_symlink_target (EMailSignatureScriptDialog *dialog) -{ - g_return_val_if_fail ( - E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL); - - return dialog->priv->symlink_target; -} - -void -e_mail_signature_script_dialog_set_symlink_target (EMailSignatureScriptDialog *dialog, - const gchar *symlink_target) -{ - GtkFileChooser *file_chooser; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog)); - g_return_if_fail (symlink_target != NULL); - - g_free (dialog->priv->symlink_target); - dialog->priv->symlink_target = g_strdup (symlink_target); - - file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser); - gtk_file_chooser_set_filename (file_chooser, symlink_target); - - g_object_notify (G_OBJECT (dialog), "symlink-target"); - - mail_signature_script_dialog_update_status (dialog); -} - -/****************** e_mail_signature_script_dialog_commit() ******************/ - -static void -mail_signature_script_dialog_symlink_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - GError *error = NULL; - - simple = G_SIMPLE_ASYNC_RESULT (user_data); - - e_source_mail_signature_symlink_finish ( - E_SOURCE (object), result, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - - g_object_unref (simple); -} - -static void -mail_signature_script_dialog_commit_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *async_context; - GError *error = NULL; - - simple = G_SIMPLE_ASYNC_RESULT (user_data); - async_context = g_simple_async_result_get_op_res_gpointer (simple); - - e_source_registry_commit_source_finish ( - E_SOURCE_REGISTRY (object), result, &error); - - if (error != NULL) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); - return; - } - - /* We can call this on our scratch source because only its UID is - * really needed, which even a new scratch source already knows. */ - e_source_mail_signature_symlink ( - async_context->source, - async_context->symlink_target, - G_PRIORITY_DEFAULT, - async_context->cancellable, - mail_signature_script_dialog_symlink_cb, - simple); -} - -void -e_mail_signature_script_dialog_commit (EMailSignatureScriptDialog *dialog, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *async_context; - ESourceRegistry *registry; - ESource *source; - const gchar *symlink_target; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog)); - - registry = e_mail_signature_script_dialog_get_registry (dialog); - source = e_mail_signature_script_dialog_get_source (dialog); - - symlink_target = - e_mail_signature_script_dialog_get_symlink_target (dialog); - - async_context = g_slice_new0 (AsyncContext); - async_context->source = g_object_ref (source); - async_context->symlink_target = g_strdup (symlink_target); - - if (G_IS_CANCELLABLE (cancellable)) - async_context->cancellable = g_object_ref (cancellable); - - simple = g_simple_async_result_new ( - G_OBJECT (dialog), callback, user_data, - e_mail_signature_script_dialog_commit); - - g_simple_async_result_set_op_res_gpointer ( - simple, async_context, (GDestroyNotify) async_context_free); - - e_source_registry_commit_source ( - registry, source, - async_context->cancellable, - mail_signature_script_dialog_commit_cb, - simple); -} - -gboolean -e_mail_signature_script_dialog_commit_finish (EMailSignatureScriptDialog *dialog, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (dialog), - e_mail_signature_script_dialog_commit), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - diff --git a/widgets/misc/e-mail-signature-script-dialog.h b/widgets/misc/e-mail-signature-script-dialog.h deleted file mode 100644 index b28521e488..0000000000 --- a/widgets/misc/e-mail-signature-script-dialog.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * e-mail-signature-script-dialog.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_SCRIPT_DIALOG_H -#define E_MAIL_SIGNATURE_SCRIPT_DIALOG_H - -#include <gtk/gtk.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG \ - (e_mail_signature_script_dialog_get_type ()) -#define E_MAIL_SIGNATURE_SCRIPT_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, \ - EMailSignatureScriptDialog)) -#define E_MAIL_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, \ - EMailSignatureScriptDialogClass)) -#define E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG)) -#define E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG)) -#define E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, \ - EMailSignatureScriptDialogClass)) - -G_BEGIN_DECLS - -typedef struct _EMailSignatureScriptDialog EMailSignatureScriptDialog; -typedef struct _EMailSignatureScriptDialogClass EMailSignatureScriptDialogClass; -typedef struct _EMailSignatureScriptDialogPrivate EMailSignatureScriptDialogPrivate; - -struct _EMailSignatureScriptDialog { - GtkDialog parent; - EMailSignatureScriptDialogPrivate *priv; -}; - -struct _EMailSignatureScriptDialogClass { - GtkDialogClass parent_class; -}; - -GType e_mail_signature_script_dialog_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_script_dialog_new - (ESourceRegistry *registry, - GtkWindow *parent, - ESource *source); -ESourceRegistry * - e_mail_signature_script_dialog_get_registry - (EMailSignatureScriptDialog *dialog); -ESource * e_mail_signature_script_dialog_get_source - (EMailSignatureScriptDialog *dialog); -const gchar * e_mail_signature_script_dialog_get_symlink_target - (EMailSignatureScriptDialog *dialog); -void e_mail_signature_script_dialog_set_symlink_target - (EMailSignatureScriptDialog *dialog, - const gchar *symlink_target); -void e_mail_signature_script_dialog_commit - (EMailSignatureScriptDialog *dialog, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_signature_script_dialog_commit_finish - (EMailSignatureScriptDialog *dialog, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_SIGNATURE_SCRIPT_DIALOG_H */ diff --git a/widgets/misc/e-mail-signature-tree-view.c b/widgets/misc/e-mail-signature-tree-view.c deleted file mode 100644 index 05a2580d78..0000000000 --- a/widgets/misc/e-mail-signature-tree-view.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * e-mail-signature-tree-view.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-signature-tree-view.h" - -#define E_MAIL_SIGNATURE_TREE_VIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SIGNATURE_TREE_VIEW, EMailSignatureTreeViewPrivate)) - -#define SOURCE_IS_MAIL_SIGNATURE(source) \ - (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_SIGNATURE)) - -struct _EMailSignatureTreeViewPrivate { - ESourceRegistry *registry; - guint refresh_idle_id; -}; - -enum { - PROP_0, - PROP_REGISTRY -}; - -enum { - COLUMN_DISPLAY_NAME, - COLUMN_UID, - NUM_COLUMNS -}; - -G_DEFINE_TYPE ( - EMailSignatureTreeView, - e_mail_signature_tree_view, - GTK_TYPE_TREE_VIEW) - -static gboolean -mail_signature_tree_view_refresh_idle_cb (EMailSignatureTreeView *tree_view) -{ - /* The refresh function will clear the idle ID. */ - e_mail_signature_tree_view_refresh (tree_view); - - return FALSE; -} - -static void -mail_signature_tree_view_registry_changed (ESourceRegistry *registry, - ESource *source, - EMailSignatureTreeView *tree_view) -{ - /* If the ESource in question has a "Mail Signature" extension, - * schedule a refresh of the tree model. Otherwise ignore it. - * We use an idle callback to limit how frequently we refresh - * the tree model, in case the registry is emitting lots of - * signals at once. */ - - if (!SOURCE_IS_MAIL_SIGNATURE (source)) - return; - - if (tree_view->priv->refresh_idle_id > 0) - return; - - tree_view->priv->refresh_idle_id = g_idle_add ( - (GSourceFunc) mail_signature_tree_view_refresh_idle_cb, - tree_view); -} - -static void -mail_signature_tree_view_set_registry (EMailSignatureTreeView *tree_view, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (tree_view->priv->registry == NULL); - - tree_view->priv->registry = g_object_ref (registry); - - g_signal_connect ( - registry, "source-added", - G_CALLBACK (mail_signature_tree_view_registry_changed), - tree_view); - - g_signal_connect ( - registry, "source-changed", - G_CALLBACK (mail_signature_tree_view_registry_changed), - tree_view); - - g_signal_connect ( - registry, "source-removed", - G_CALLBACK (mail_signature_tree_view_registry_changed), - tree_view); -} - -static void -mail_signature_tree_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - mail_signature_tree_view_set_registry ( - E_MAIL_SIGNATURE_TREE_VIEW (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_tree_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_REGISTRY: - g_value_set_object ( - value, - e_mail_signature_tree_view_get_registry ( - E_MAIL_SIGNATURE_TREE_VIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_signature_tree_view_dispose (GObject *object) -{ - EMailSignatureTreeViewPrivate *priv; - - priv = E_MAIL_SIGNATURE_TREE_VIEW_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; - } - - if (priv->refresh_idle_id > 0) { - g_source_remove (priv->refresh_idle_id); - priv->refresh_idle_id = 0; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_signature_tree_view_parent_class)-> - dispose (object); -} - -static void -mail_signature_tree_view_constructed (GObject *object) -{ - GtkTreeView *tree_view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell_renderer; - GtkListStore *list_store; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_signature_tree_view_parent_class)-> - constructed (object); - - list_store = gtk_list_store_new ( - NUM_COLUMNS, - G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */ - G_TYPE_STRING); /* COLUMN_UID */ - - tree_view = GTK_TREE_VIEW (object); - gtk_tree_view_set_headers_visible (tree_view, FALSE); - gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store)); - - g_object_unref (list_store); - - /* Column: Signature Name */ - - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_expand (column, TRUE); - - cell_renderer = gtk_cell_renderer_text_new (); - g_object_set (cell_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_tree_view_column_pack_start (column, cell_renderer, TRUE); - - gtk_tree_view_column_add_attribute ( - column, cell_renderer, "text", COLUMN_DISPLAY_NAME); - - gtk_tree_view_append_column (tree_view, column); - - e_mail_signature_tree_view_refresh ( - E_MAIL_SIGNATURE_TREE_VIEW (object)); -} - -static void -e_mail_signature_tree_view_class_init (EMailSignatureTreeViewClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private ( - class, sizeof (EMailSignatureTreeViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_signature_tree_view_set_property; - object_class->get_property = mail_signature_tree_view_get_property; - object_class->dispose = mail_signature_tree_view_dispose; - object_class->constructed = mail_signature_tree_view_constructed; - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - NULL, - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_mail_signature_tree_view_init (EMailSignatureTreeView *tree_view) -{ - tree_view->priv = E_MAIL_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view); -} - -GtkWidget * -e_mail_signature_tree_view_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_MAIL_SIGNATURE_TREE_VIEW, - "registry", registry, NULL); -} - -void -e_mail_signature_tree_view_refresh (EMailSignatureTreeView *tree_view) -{ - ESourceRegistry *registry; - GtkTreeModel *tree_model; - GtkTreeSelection *selection; - ESource *source; - GList *list, *link; - const gchar *extension_name; - gchar *saved_uid = NULL; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view)); - - if (tree_view->priv->refresh_idle_id > 0) { - g_source_remove (tree_view->priv->refresh_idle_id); - tree_view->priv->refresh_idle_id = 0; - } - - registry = e_mail_signature_tree_view_get_registry (tree_view); - tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - - source = e_mail_signature_tree_view_ref_selected_source (tree_view); - if (source != NULL) { - saved_uid = e_source_dup_uid (source); - g_object_unref (source); - } - - gtk_list_store_clear (GTK_LIST_STORE (tree_model)); - - extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; - list = e_source_registry_list_sources (registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - GtkTreeIter iter; - const gchar *display_name; - const gchar *uid; - - source = E_SOURCE (link->data); - display_name = e_source_get_display_name (source); - uid = e_source_get_uid (source); - - gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (tree_model), &iter, - COLUMN_DISPLAY_NAME, display_name, - COLUMN_UID, uid, -1); - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - /* Try and restore the previous selected source. */ - - source = NULL; - - if (saved_uid != NULL) { - source = e_source_registry_ref_source (registry, saved_uid); - g_free (saved_uid); - } - - if (source != NULL) { - e_mail_signature_tree_view_set_selected_source ( - tree_view, source); - g_object_unref (source); - } - - /* Hint to refresh a signature preview. */ - g_signal_emit_by_name (selection, "changed"); -} - -ESourceRegistry * -e_mail_signature_tree_view_get_registry (EMailSignatureTreeView *tree_view) -{ - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view), NULL); - - return tree_view->priv->registry; -} - -ESource * -e_mail_signature_tree_view_ref_selected_source (EMailSignatureTreeView *tree_view) -{ - ESourceRegistry *registry; - GtkTreeSelection *selection; - GtkTreeModel *tree_model; - GtkTreeIter iter; - ESource *source; - gchar *uid; - - g_return_val_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view), NULL); - - registry = e_mail_signature_tree_view_get_registry (tree_view); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - - if (!gtk_tree_selection_get_selected (selection, &tree_model, &iter)) - return NULL; - - gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1); - source = e_source_registry_ref_source (registry, uid); - g_free (uid); - - return source; -} - -void -e_mail_signature_tree_view_set_selected_source (EMailSignatureTreeView *tree_view, - ESource *source) -{ - ESourceRegistry *registry; - GtkTreeSelection *selection; - GtkTreeModel *tree_model; - GtkTreeIter iter; - gboolean valid; - - g_return_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view)); - g_return_if_fail (E_IS_SOURCE (source)); - - /* It is a programming error to pass an ESource that has no - * "Mail Signature" extension. */ - g_return_if_fail (SOURCE_IS_MAIL_SIGNATURE (source)); - - registry = e_mail_signature_tree_view_get_registry (tree_view); - tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - - while (valid) { - ESource *candidate; - gchar *uid; - - gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1); - candidate = e_source_registry_ref_source (registry, uid); - g_free (uid); - - if (candidate != NULL && e_source_equal (source, candidate)) { - gtk_tree_selection_select_iter (selection, &iter); - g_object_unref (candidate); - break; - } - - if (candidate != NULL) - g_object_unref (candidate); - - valid = gtk_tree_model_iter_next (tree_model, &iter); - } -} diff --git a/widgets/misc/e-mail-signature-tree-view.h b/widgets/misc/e-mail-signature-tree-view.h deleted file mode 100644 index ba2615f6d8..0000000000 --- a/widgets/misc/e-mail-signature-tree-view.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * e-mail-signature-tree-view.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SIGNATURE_TREE_VIEW_H -#define E_MAIL_SIGNATURE_TREE_VIEW_H - -#include <gtk/gtk.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SIGNATURE_TREE_VIEW \ - (e_mail_signature_tree_view_get_type ()) -#define E_MAIL_SIGNATURE_TREE_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SIGNATURE_TREE_VIEW, EMailSignatureTreeView)) -#define E_MAIL_SIGNATURE_TREE_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SIGNATURE_TREE_VIEW, EMailSignatureTreeViewClass)) -#define E_IS_MAIL_SIGNATURE_TREE_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SIGNATURE_TREE_VIEW)) -#define E_IS_MAIL_SIGNATURE_TREE_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SIGNATURE_TREE_VIEW)) -#define E_MAIL_SIGNATURE_TREE_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SIGNATURE_TREE_VIEW, EMailSignatureTreeViewClass)) - -G_BEGIN_DECLS - -typedef struct _EMailSignatureTreeView EMailSignatureTreeView; -typedef struct _EMailSignatureTreeViewClass EMailSignatureTreeViewClass; -typedef struct _EMailSignatureTreeViewPrivate EMailSignatureTreeViewPrivate; - -struct _EMailSignatureTreeView { - GtkTreeView parent; - EMailSignatureTreeViewPrivate *priv; -}; - -struct _EMailSignatureTreeViewClass { - GtkTreeViewClass parent_class; -}; - -GType e_mail_signature_tree_view_get_type - (void) G_GNUC_CONST; -GtkWidget * e_mail_signature_tree_view_new - (ESourceRegistry *registry); -void e_mail_signature_tree_view_refresh - (EMailSignatureTreeView *tree_view); -ESourceRegistry * - e_mail_signature_tree_view_get_registry - (EMailSignatureTreeView *tree_view); -ESource * e_mail_signature_tree_view_ref_selected_source - (EMailSignatureTreeView *tree_view); -void e_mail_signature_tree_view_set_selected_source - (EMailSignatureTreeView *tree_view, - ESource *selected_source); - -G_END_DECLS - -#endif /* E_MAIL_SIGNATURE_TREE_VIEW_H */ diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c deleted file mode 100644 index b9f83d811d..0000000000 --- a/widgets/misc/e-map.c +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * Map widget. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Hans Petter Jansson <hpj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <stdlib.h> -#include <gdk/gdkkeysyms.h> -#include <glib/gi18n.h> - -#include "e-util/e-util-private.h" -#include "e-util/e-util.h" - -#include "e-map.h" - -#define E_MAP_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAP, EMapPrivate)) - -#define E_MAP_TWEEN_TIMEOUT_MSECS 25 -#define E_MAP_TWEEN_DURATION_MSECS 150 - -/* Scroll step increment */ - -#define SCROLL_STEP_SIZE 32 - -/* */ - -#define E_MAP_GET_WIDTH(map) gtk_adjustment_get_upper((map)->priv->hadjustment) -#define E_MAP_GET_HEIGHT(map) gtk_adjustment_get_upper((map)->priv->vadjustment) - -/* Zoom state - keeps track of animation hacks */ - -typedef enum -{ - E_MAP_ZOOMED_IN, - E_MAP_ZOOMED_OUT, - E_MAP_ZOOMING_IN, - E_MAP_ZOOMING_OUT -} -EMapZoomState; - -/* The Tween struct used for zooming */ - -typedef struct _EMapTween EMapTween; - -struct _EMapTween { - guint start_time; - guint end_time; - gdouble longitude_offset; - gdouble latitude_offset; - gdouble zoom_factor; -}; - -/* Private part of the EMap structure */ - -struct _EMapPrivate { - /* Pointer to map image */ - GdkPixbuf *map_pixbuf; - cairo_surface_t *map_render_surface; - - /* Settings */ - gboolean frozen, smooth_zoom; - - /* Adjustments for scrolling */ - GtkAdjustment *hadjustment; - GtkAdjustment *vadjustment; - - /* GtkScrollablePolicy needs to be checked when - * driving the scrollable adjustment values */ - guint hscroll_policy : 1; - guint vscroll_policy : 1; - - /* Current scrolling offsets */ - gint xofs, yofs; - - /* Realtime zoom data */ - EMapZoomState zoom_state; - gdouble zoom_target_long, zoom_target_lat; - - /* Dots */ - GPtrArray *points; - - /* Tweens */ - GSList *tweens; - GTimer *timer; - guint timer_current_ms; - guint tween_id; -}; - -/* Properties */ - -enum { - PROP_0, - - /* For scrollable interface */ - PROP_HADJUSTMENT, - PROP_VADJUSTMENT, - PROP_HSCROLL_POLICY, - PROP_VSCROLL_POLICY -}; - -/* Internal prototypes */ - -static void update_render_surface (EMap *map, gboolean render_overlays); -static void set_scroll_area (EMap *map, gint width, gint height); -static void center_at (EMap *map, gdouble longitude, gdouble latitude); -static void scroll_to (EMap *map, gint x, gint y); -static gint load_map_background (EMap *map, gchar *name); -static void update_and_paint (EMap *map); -static void update_render_point (EMap *map, EMapPoint *point); -static void repaint_point (EMap *map, EMapPoint *point); - -/* ------ * - * Tweens * - * ------ */ - -static gboolean -e_map_is_tweening (EMap *map) -{ - return map->priv->timer != NULL; -} - -static void -e_map_stop_tweening (EMap *map) -{ - g_assert (map->priv->tweens == NULL); - - if (!e_map_is_tweening (map)) - return; - - g_timer_destroy (map->priv->timer); - map->priv->timer = NULL; - g_source_remove (map->priv->tween_id); - map->priv->tween_id = 0; -} - -static void -e_map_tween_destroy (EMap *map, - EMapTween *tween) -{ - map->priv->tweens = g_slist_remove (map->priv->tweens, tween); - g_slice_free (EMapTween, tween); - - if (map->priv->tweens == NULL) - e_map_stop_tweening (map); -} - -static gboolean -e_map_do_tween_cb (gpointer data) -{ - EMap *map = data; - GSList *walk; - - map->priv->timer_current_ms = - g_timer_elapsed (map->priv->timer, NULL) * 1000; - gtk_widget_queue_draw (GTK_WIDGET (map)); - - /* Can't use for loop here, because we need to advance - * the list before deleting. - */ - walk = map->priv->tweens; - while (walk) - { - EMapTween *tween = walk->data; - - walk = walk->next; - - if (tween->end_time <= map->priv->timer_current_ms) - e_map_tween_destroy (map, tween); - } - - return TRUE; -} - -static void -e_map_start_tweening (EMap *map) -{ - if (e_map_is_tweening (map)) - return; - - map->priv->timer = g_timer_new (); - map->priv->timer_current_ms = 0; - map->priv->tween_id = g_timeout_add ( - E_MAP_TWEEN_TIMEOUT_MSECS, e_map_do_tween_cb, map); - g_timer_start (map->priv->timer); -} - -static void -e_map_tween_new (EMap *map, - guint msecs, - gdouble longitude_offset, - gdouble latitude_offset, - gdouble zoom_factor) -{ - EMapTween *tween; - - if (!map->priv->smooth_zoom) - return; - - e_map_start_tweening (map); - - tween = g_slice_new (EMapTween); - - tween->start_time = map->priv->timer_current_ms; - tween->end_time = tween->start_time + msecs; - tween->longitude_offset = longitude_offset; - tween->latitude_offset = latitude_offset; - tween->zoom_factor = zoom_factor; - - map->priv->tweens = g_slist_prepend (map->priv->tweens, tween); - - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -G_DEFINE_TYPE_WITH_CODE ( - EMap, - e_map, - GTK_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) - -static void -e_map_get_current_location (EMap *map, - gdouble *longitude, - gdouble *latitude) -{ - GtkAllocation allocation; - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - e_map_window_to_world ( - map, allocation.width / 2.0, - allocation.height / 2.0, - longitude, latitude); -} - -static void -e_map_world_to_render_surface (EMap *map, - gdouble world_longitude, - gdouble world_latitude, - gdouble *win_x, - gdouble *win_y) -{ - gint width, height; - - width = E_MAP_GET_WIDTH (map); - height = E_MAP_GET_HEIGHT (map); - - *win_x = (width / 2.0 + (width / 2.0) * world_longitude / 180.0); - *win_y = (height / 2.0 - (height / 2.0) * world_latitude / 90.0); -} - -static void -e_map_tween_new_from (EMap *map, - guint msecs, - gdouble longitude, - gdouble latitude, - gdouble zoom) -{ - gdouble current_longitude, current_latitude; - - e_map_get_current_location ( - map, ¤t_longitude, ¤t_latitude); - - e_map_tween_new ( - map, msecs, - longitude - current_longitude, - latitude - current_latitude, - zoom / e_map_get_magnification (map)); -} - -static gdouble -e_map_get_tween_effect (EMap *map, - EMapTween *tween) -{ - gdouble elapsed; - - elapsed = (gdouble) - (map->priv->timer_current_ms - tween->start_time) / - tween->end_time; - - return MAX (0.0, 1.0 - elapsed); -} - -static void -e_map_apply_tween (EMapTween *tween, - gdouble effect, - gdouble *longitude, - gdouble *latitude, - gdouble *zoom) -{ - *zoom *= pow (tween->zoom_factor, effect); - *longitude += tween->longitude_offset * effect; - *latitude += tween->latitude_offset * effect; -} - -static void -e_map_tweens_compute_matrix (EMap *map, - cairo_matrix_t *matrix) -{ - GSList *walk; - gdouble zoom, x, y, latitude, longitude, effect; - GtkAllocation allocation; - - if (!e_map_is_tweening (map)) { - cairo_matrix_init_translate ( - matrix, -map->priv->xofs, -map->priv->yofs); - return; - } - - e_map_get_current_location (map, &longitude, &latitude); - zoom = 1.0; - - for (walk = map->priv->tweens; walk; walk = walk->next) { - EMapTween *tween = walk->data; - - effect = e_map_get_tween_effect (map, tween); - e_map_apply_tween (tween, effect, &longitude, &latitude, &zoom); - } - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - cairo_matrix_init_translate ( - matrix, - allocation.width / 2.0, - allocation.height / 2.0); - - e_map_world_to_render_surface (map, longitude, latitude, &x, &y); - cairo_matrix_scale (matrix, zoom, zoom); - cairo_matrix_translate (matrix, -x, -y); -} - -/* GtkScrollable implementation */ - -static void -e_map_adjustment_changed (GtkAdjustment *adjustment, - EMap *map) -{ - EMapPrivate *priv = map->priv; - - if (gtk_widget_get_realized (GTK_WIDGET (map))) { - gint hadj_value; - gint vadj_value; - - hadj_value = gtk_adjustment_get_value (priv->hadjustment); - vadj_value = gtk_adjustment_get_value (priv->vadjustment); - - scroll_to (map, hadj_value, vadj_value); - } -} - -static void -e_map_set_hadjustment_values (EMap *map) -{ - GtkAllocation allocation; - EMapPrivate *priv = map->priv; - GtkAdjustment *adj = priv->hadjustment; - gdouble old_value; - gdouble new_value; - gdouble new_upper; - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - old_value = gtk_adjustment_get_value (adj); - new_upper = MAX (allocation.width, gdk_pixbuf_get_width (priv->map_pixbuf)); - - g_object_set ( - adj, - "lower", 0.0, - "upper", new_upper, - "page-size", (gdouble) allocation.height, - "step-increment", allocation.height * 0.1, - "page-increment", allocation.height * 0.9, - NULL); - - new_value = CLAMP (old_value, 0, new_upper - allocation.width); - if (new_value != old_value) - gtk_adjustment_set_value (adj, new_value); -} - -static void -e_map_set_vadjustment_values (EMap *map) -{ - GtkAllocation allocation; - EMapPrivate *priv = map->priv; - GtkAdjustment *adj = priv->vadjustment; - gdouble old_value; - gdouble new_value; - gdouble new_upper; - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - old_value = gtk_adjustment_get_value (adj); - new_upper = MAX (allocation.height, gdk_pixbuf_get_height (priv->map_pixbuf)); - - g_object_set ( - adj, - "lower", 0.0, - "upper", new_upper, - "page-size", (gdouble) allocation.height, - "step-increment", allocation.height * 0.1, - "page-increment", allocation.height * 0.9, - NULL); - - new_value = CLAMP (old_value, 0, new_upper - allocation.height); - if (new_value != old_value) - gtk_adjustment_set_value (adj, new_value); -} - -static void -e_map_set_hadjustment (EMap *map, - GtkAdjustment *adjustment) -{ - EMapPrivate *priv = map->priv; - - if (adjustment && priv->hadjustment == adjustment) - return; - - if (priv->hadjustment != NULL) { - g_signal_handlers_disconnect_matched ( - priv->hadjustment, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, map); - g_object_unref (priv->hadjustment); - } - - if (!adjustment) - adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - - g_signal_connect ( - adjustment, "value-changed", - G_CALLBACK (e_map_adjustment_changed), map); - priv->hadjustment = g_object_ref_sink (adjustment); - e_map_set_hadjustment_values (map); - - g_object_notify (G_OBJECT (map), "hadjustment"); -} - -static void -e_map_set_vadjustment (EMap *map, - GtkAdjustment *adjustment) -{ - EMapPrivate *priv = map->priv; - - if (adjustment && priv->vadjustment == adjustment) - return; - - if (priv->vadjustment != NULL) { - g_signal_handlers_disconnect_matched ( - priv->vadjustment, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, map); - g_object_unref (priv->vadjustment); - } - - if (!adjustment) - adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - - g_signal_connect ( - adjustment, "value-changed", - G_CALLBACK (e_map_adjustment_changed), map); - priv->vadjustment = g_object_ref_sink (adjustment); - e_map_set_vadjustment_values (map); - - g_object_notify (G_OBJECT (map), "vadjustment"); -} - -/* ----------------- * - * Widget management * - * ----------------- */ - -static void -e_map_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - EMap *map; - - map = E_MAP (object); - - switch (property_id) { - case PROP_HADJUSTMENT: - e_map_set_hadjustment (map, g_value_get_object (value)); - break; - case PROP_VADJUSTMENT: - e_map_set_vadjustment (map, g_value_get_object (value)); - break; - case PROP_HSCROLL_POLICY: - map->priv->hscroll_policy = g_value_get_enum (value); - gtk_widget_queue_resize (GTK_WIDGET (map)); - break; - case PROP_VSCROLL_POLICY: - map->priv->vscroll_policy = g_value_get_enum (value); - gtk_widget_queue_resize (GTK_WIDGET (map)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_map_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EMap *map; - - map = E_MAP (object); - - switch (property_id) { - case PROP_HADJUSTMENT: - g_value_set_object (value, map->priv->hadjustment); - break; - case PROP_VADJUSTMENT: - g_value_set_object (value, map->priv->vadjustment); - break; - case PROP_HSCROLL_POLICY: - g_value_set_enum (value, map->priv->hscroll_policy); - break; - case PROP_VSCROLL_POLICY: - g_value_set_enum (value, map->priv->vscroll_policy); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_map_finalize (GObject *object) -{ - EMap *map; - - map = E_MAP (object); - - while (map->priv->tweens) - e_map_tween_destroy (map, map->priv->tweens->data); - e_map_stop_tweening (map); - - if (map->priv->map_pixbuf) { - g_object_unref (map->priv->map_pixbuf); - map->priv->map_pixbuf = NULL; - } - - /* gone in unrealize */ - g_assert (map->priv->map_render_surface == NULL); - - G_OBJECT_CLASS (e_map_parent_class)->finalize (object); -} - -static void -e_map_realize (GtkWidget *widget) -{ - GtkAllocation allocation; - GdkWindowAttr attr; - GdkWindow *window; - gint attr_mask; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_MAP (widget)); - - gtk_widget_set_realized (widget, TRUE); - - gtk_widget_get_allocation (widget, &allocation); - - attr.window_type = GDK_WINDOW_CHILD; - attr.x = allocation.x; - attr.y = allocation.y; - attr.width = allocation.width; - attr.height = allocation.height; - attr.wclass = GDK_INPUT_OUTPUT; - attr.visual = gtk_widget_get_visual (widget); - attr.event_mask = gtk_widget_get_events (widget) | - GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | - GDK_POINTER_MOTION_MASK; - - attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - window = gdk_window_new ( - gtk_widget_get_parent_window (widget), &attr, attr_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, widget); - - update_render_surface (E_MAP (widget), TRUE); -} - -static void -e_map_unrealize (GtkWidget *widget) -{ - EMap *map = E_MAP (widget); - - cairo_surface_destroy (map->priv->map_render_surface); - map->priv->map_render_surface = NULL; - - if (GTK_WIDGET_CLASS (e_map_parent_class)->unrealize) - (*GTK_WIDGET_CLASS (e_map_parent_class)->unrealize) (widget); -} - -static void -e_map_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - EMap *map; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_MAP (widget)); - - map = E_MAP (widget); - - /* TODO: Put real sizes here. */ - - *minimum = *natural = gdk_pixbuf_get_width (map->priv->map_pixbuf); -} - -static void -e_map_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - EMap *view; - EMapPrivate *priv; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_MAP (widget)); - - view = E_MAP (widget); - priv = view->priv; - - /* TODO: Put real sizes here. */ - - *minimum = *natural = gdk_pixbuf_get_height (priv->map_pixbuf); -} - -static void -e_map_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EMap *map; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_MAP (widget)); - g_return_if_fail (allocation != NULL); - - map = E_MAP (widget); - - /* Resize the window */ - - gtk_widget_set_allocation (widget, allocation); - - if (gtk_widget_get_realized (widget)) { - GdkWindow *window; - - window = gtk_widget_get_window (widget); - - gdk_window_move_resize ( - window, allocation->x, allocation->y, - allocation->width, allocation->height); - - gtk_widget_queue_draw (widget); - } - - update_render_surface (map, TRUE); -} - -static gboolean -e_map_draw (GtkWidget *widget, - cairo_t *cr) -{ - EMap *map; - cairo_matrix_t matrix; - - if (!gtk_widget_is_drawable (widget)) - return FALSE; - - map = E_MAP (widget); - - cairo_save (cr); - - e_map_tweens_compute_matrix (map, &matrix); - cairo_transform (cr, &matrix); - - cairo_set_source_surface (cr, map->priv->map_render_surface, 0, 0); - cairo_paint (cr); - - cairo_restore (cr); - - return FALSE; -} - -static gint -e_map_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - if (!gtk_widget_has_focus (widget)) - gtk_widget_grab_focus (widget); - - return TRUE; -} - -static gint -e_map_button_release (GtkWidget *widget, - GdkEventButton *event) -{ - if (event->button != 1) - return FALSE; - - gdk_device_ungrab (event->device, event->time); - return TRUE; -} - -static gint -e_map_motion (GtkWidget *widget, - GdkEventMotion *event) -{ - return FALSE; -} - -static gint -e_map_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - EMap *map; - gboolean do_scroll; - gint xofs, yofs; - - map = E_MAP (widget); - - switch (event->keyval) - { - case GDK_KEY_Up: - do_scroll = TRUE; - xofs = 0; - yofs = -SCROLL_STEP_SIZE; - break; - - case GDK_KEY_Down: - do_scroll = TRUE; - xofs = 0; - yofs = SCROLL_STEP_SIZE; - break; - - case GDK_KEY_Left: - do_scroll = TRUE; - xofs = -SCROLL_STEP_SIZE; - yofs = 0; - break; - - case GDK_KEY_Right: - do_scroll = TRUE; - xofs = SCROLL_STEP_SIZE; - yofs = 0; - break; - - default: - return FALSE; - } - - if (do_scroll) { - gint page_size; - gint upper; - gint x, y; - - page_size = gtk_adjustment_get_page_size (map->priv->hadjustment); - upper = gtk_adjustment_get_upper (map->priv->hadjustment); - x = CLAMP (map->priv->xofs + xofs, 0, upper - page_size); - - page_size = gtk_adjustment_get_page_size (map->priv->vadjustment); - upper = gtk_adjustment_get_upper (map->priv->vadjustment); - y = CLAMP (map->priv->yofs + yofs, 0, upper - page_size); - - scroll_to (map, x, y); - - gtk_adjustment_set_value (map->priv->hadjustment, x); - gtk_adjustment_set_value (map->priv->vadjustment, y); - } - - return TRUE; -} - -static void -e_map_class_init (EMapClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EMapPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = e_map_set_property; - object_class->get_property = e_map_get_property; - object_class->finalize = e_map_finalize; - - /* Scrollable interface properties */ - g_object_class_override_property ( - object_class, PROP_HADJUSTMENT, "hadjustment"); - g_object_class_override_property ( - object_class, PROP_VADJUSTMENT, "vadjustment"); - g_object_class_override_property ( - object_class, PROP_HSCROLL_POLICY, "hscroll-policy"); - g_object_class_override_property ( - object_class, PROP_VSCROLL_POLICY, "vscroll-policy"); - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = e_map_realize; - widget_class->unrealize = e_map_unrealize; - widget_class->get_preferred_height = e_map_get_preferred_height; - widget_class->get_preferred_width = e_map_get_preferred_width; - widget_class->size_allocate = e_map_size_allocate; - widget_class->draw = e_map_draw; - widget_class->button_press_event = e_map_button_press; - widget_class->button_release_event = e_map_button_release; - widget_class->motion_notify_event = e_map_motion; - widget_class->key_press_event = e_map_key_press; -} - -static void -e_map_init (EMap *map) -{ - GtkWidget *widget; - gchar *map_file_name; - - map_file_name = g_build_filename ( - EVOLUTION_IMAGESDIR, "world_map-960.png", NULL); - - widget = GTK_WIDGET (map); - - map->priv = E_MAP_GET_PRIVATE (map); - - load_map_background (map, map_file_name); - g_free (map_file_name); - map->priv->frozen = FALSE; - map->priv->smooth_zoom = TRUE; - map->priv->zoom_state = E_MAP_ZOOMED_OUT; - map->priv->points = g_ptr_array_new (); - - gtk_widget_set_can_focus (widget, TRUE); - gtk_widget_set_has_window (widget, TRUE); -} - -/* ---------------- * - * Widget interface * - * ---------------- */ - -/** - * e_map_new: - * @void: - * - * Creates a new empty map widget. - * - * Return value: A newly-created map widget. - **/ - -EMap * -e_map_new (void) -{ - GtkWidget *widget; - AtkObject *a11y; - - widget = g_object_new (E_TYPE_MAP, NULL); - a11y = gtk_widget_get_accessible (widget); - atk_object_set_name (a11y, _("World Map")); - atk_object_set_role (a11y, ATK_ROLE_IMAGE); - atk_object_set_description ( - a11y, _("Mouse-based interactive map widget for selecting " - "timezone. Keyboard users should instead select the timezone " - "from the drop-down combination box below.")); - return (E_MAP (widget)); -} - -/* --- Coordinate translation --- */ - -/* These functions translate coordinates between longitude/latitude and - * the image x/y offsets, using the equidistant cylindrical projection. - * - * Longitude E <-180, 180] - * Latitude E <-90, 90] */ - -void -e_map_window_to_world (EMap *map, - gdouble win_x, - gdouble win_y, - gdouble *world_longitude, - gdouble *world_latitude) -{ - gint width, height; - - g_return_if_fail (map); - - g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (map))); - - width = E_MAP_GET_WIDTH (map); - height = E_MAP_GET_HEIGHT (map); - - *world_longitude = (win_x + map->priv->xofs - (gdouble) width / 2.0) / - ((gdouble) width / 2.0) * 180.0; - *world_latitude = ((gdouble) height / 2.0 - win_y - map->priv->yofs) / - ((gdouble) height / 2.0) * 90.0; -} - -void -e_map_world_to_window (EMap *map, - gdouble world_longitude, - gdouble world_latitude, - gdouble *win_x, - gdouble *win_y) -{ - g_return_if_fail (E_IS_MAP (map)); - g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (map))); - g_return_if_fail (world_longitude >= -180.0 && world_longitude <= 180.0); - g_return_if_fail (world_latitude >= -90.0 && world_latitude <= 90.0); - - e_map_world_to_render_surface ( - map, world_longitude, world_latitude, win_x, win_y); - - *win_x -= map->priv->xofs; - *win_y -= map->priv->yofs; -} - -/* --- Zoom --- */ - -gdouble -e_map_get_magnification (EMap *map) -{ - if (map->priv->zoom_state == E_MAP_ZOOMED_IN) return 2.0; - else return 1.0; -} - -static void -e_map_set_zoom (EMap *map, - EMapZoomState zoom) -{ - if (map->priv->zoom_state == zoom) - return; - - map->priv->zoom_state = zoom; - update_render_surface (map, TRUE); - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -void -e_map_zoom_to_location (EMap *map, - gdouble longitude, - gdouble latitude) -{ - gdouble prevlong, prevlat; - gdouble prevzoom; - - g_return_if_fail (map); - g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (map))); - - e_map_get_current_location (map, &prevlong, &prevlat); - prevzoom = e_map_get_magnification (map); - - e_map_set_zoom (map, E_MAP_ZOOMED_IN); - center_at (map, longitude, latitude); - - e_map_tween_new_from ( - map, E_MAP_TWEEN_DURATION_MSECS, - prevlong, prevlat, prevzoom); -} - -void -e_map_zoom_out (EMap *map) -{ - gdouble longitude, latitude; - gdouble prevzoom; - - g_return_if_fail (map); - g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (map))); - - e_map_get_current_location (map, &longitude, &latitude); - prevzoom = e_map_get_magnification (map); - e_map_set_zoom (map, E_MAP_ZOOMED_OUT); - center_at (map, longitude, latitude); - - e_map_tween_new_from ( - map, E_MAP_TWEEN_DURATION_MSECS, - longitude, latitude, prevzoom); -} - -void -e_map_set_smooth_zoom (EMap *map, - gboolean state) -{ - ((EMapPrivate *) map->priv)->smooth_zoom = state; -} - -gboolean -e_map_get_smooth_zoom (EMap *map) -{ - return (((EMapPrivate *) map->priv)->smooth_zoom); -} - -void -e_map_freeze (EMap *map) -{ - ((EMapPrivate *) map->priv)->frozen = TRUE; -} - -void -e_map_thaw (EMap *map) -{ - ((EMapPrivate *) map->priv)->frozen = FALSE; - update_and_paint (map); -} - -/* --- Point manipulation --- */ - -EMapPoint * -e_map_add_point (EMap *map, - gchar *name, - gdouble longitude, - gdouble latitude, - guint32 color_rgba) -{ - EMapPoint *point; - - point = g_new0 (EMapPoint, 1); - - point->name = name; /* Can be NULL */ - point->longitude = longitude; - point->latitude = latitude; - point->rgba = color_rgba; - - g_ptr_array_add (map->priv->points, (gpointer) point); - - if (!map->priv->frozen) - { - update_render_point (map, point); - repaint_point (map, point); - } - - return point; -} - -void -e_map_remove_point (EMap *map, - EMapPoint *point) -{ - g_ptr_array_remove (map->priv->points, point); - - if (!((EMapPrivate *) map->priv)->frozen) - { - /* FIXME: Re-scaling the whole pixbuf is more than a little - * overkill when just one point is removed */ - - update_render_surface (map, TRUE); - repaint_point (map, point); - } - - g_free (point); -} - -void -e_map_point_get_location (EMapPoint *point, - gdouble *longitude, - gdouble *latitude) -{ - *longitude = point->longitude; - *latitude = point->latitude; -} - -gchar * -e_map_point_get_name (EMapPoint *point) -{ - return point->name; -} - -guint32 -e_map_point_get_color_rgba (EMapPoint *point) -{ - return point->rgba; -} - -void -e_map_point_set_color_rgba (EMap *map, - EMapPoint *point, - guint32 color_rgba) -{ - point->rgba = color_rgba; - - if (!((EMapPrivate *) map->priv)->frozen) - { - /* TODO: Redraw area around point only */ - - update_render_point (map, point); - repaint_point (map, point); - } -} - -void -e_map_point_set_data (EMapPoint *point, - gpointer data) -{ - point->user_data = data; -} - -gpointer -e_map_point_get_data (EMapPoint *point) -{ - return point->user_data; -} - -gboolean -e_map_point_is_in_view (EMap *map, - EMapPoint *point) -{ - GtkAllocation allocation; - gdouble x, y; - - if (!map->priv->map_render_surface) return FALSE; - - e_map_world_to_window (map, point->longitude, point->latitude, &x, &y); - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - if (x >= 0 && x < allocation.width && - y >= 0 && y < allocation.height) - return TRUE; - - return FALSE; -} - -EMapPoint * -e_map_get_closest_point (EMap *map, - gdouble longitude, - gdouble latitude, - gboolean in_view) -{ - EMapPoint *point_chosen = NULL, *point; - gdouble min_dist = 0.0, dist; - gdouble dx, dy; - gint i; - - for (i = 0; i < map->priv->points->len; i++) - { - point = g_ptr_array_index (map->priv->points, i); - if (in_view && !e_map_point_is_in_view (map, point)) continue; - - dx = point->longitude - longitude; - dy = point->latitude - latitude; - dist = dx * dx + dy * dy; - - if (!point_chosen || dist < min_dist) - { - min_dist = dist; - point_chosen = point; - } - } - - return point_chosen; -} - -/* ------------------ * - * Internal functions * - * ------------------ */ - -static void -update_and_paint (EMap *map) -{ - update_render_surface (map, TRUE); - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -static gint -load_map_background (EMap *map, - gchar *name) -{ - GdkPixbuf *pb0; - - pb0 = gdk_pixbuf_new_from_file (name, NULL); - if (!pb0) - return FALSE; - - if (map->priv->map_pixbuf) g_object_unref (map->priv->map_pixbuf); - map->priv->map_pixbuf = pb0; - update_render_surface (map, TRUE); - - return TRUE; -} - -static void -update_render_surface (EMap *map, - gboolean render_overlays) -{ - EMapPoint *point; - GtkAllocation allocation; - gint width, height, orig_width, orig_height; - gdouble zoom; - gint i; - - if (!gtk_widget_get_realized (GTK_WIDGET (map))) - return; - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - /* Set up value shortcuts */ - - width = allocation.width; - height = allocation.height; - orig_width = gdk_pixbuf_get_width (map->priv->map_pixbuf); - orig_height = gdk_pixbuf_get_height (map->priv->map_pixbuf); - - /* Compute scaled width and height based on the extreme dimension */ - - if ((gdouble) width / orig_width > (gdouble) height / orig_height) - zoom = (gdouble) width / (gdouble) orig_width; - else - zoom = (gdouble) height / (gdouble) orig_height; - - if (map->priv->zoom_state == E_MAP_ZOOMED_IN) - zoom *= 2.0; - height = (orig_height * zoom) + 0.5; - width = (orig_width * zoom) + 0.5; - - /* Reallocate the pixbuf */ - - if (map->priv->map_render_surface) - cairo_surface_destroy (map->priv->map_render_surface); - map->priv->map_render_surface = gdk_window_create_similar_surface ( - gtk_widget_get_window (GTK_WIDGET (map)), - CAIRO_CONTENT_COLOR, width, height); - - /* Scale the original map into the rendering pixbuf */ - - if (width > 1 && height > 1) { - cairo_t *cr = cairo_create (map->priv->map_render_surface); - cairo_scale ( - cr, - (gdouble) width / orig_width, - (gdouble) height / orig_height); - gdk_cairo_set_source_pixbuf (cr, map->priv->map_pixbuf, 0, 0); - cairo_paint (cr); - cairo_destroy (cr); - } - - /* Compute image offsets with respect to window */ - - set_scroll_area (map, width, height); - - if (render_overlays) { - /* Add points */ - - for (i = 0; i < map->priv->points->len; i++) { - point = g_ptr_array_index (map->priv->points, i); - update_render_point (map, point); - } - } -} - -/* Redraw point in client surface */ - -static void -update_render_point (EMap *map, - EMapPoint *point) -{ - cairo_t *cr; - gdouble px, py; - static guchar mask1[] = { 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static guchar mask2[] = { 0x00, 0xff, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x00, - 0x00, 0xff, 0x00, 0x00 }; - cairo_surface_t *mask; - - if (map->priv->map_render_surface == NULL) - return; - - cr = cairo_create (map->priv->map_render_surface); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - - e_map_world_to_window (map, point->longitude, point->latitude, &px, &py); - px = floor (px + map->priv->xofs); - py = floor (py + map->priv->yofs); - - cairo_set_source_rgb (cr, 0, 0, 0); - mask = cairo_image_surface_create_for_data (mask1, CAIRO_FORMAT_A8, 5, 5, 8); - cairo_mask_surface (cr, mask, px - 2, py - 2); - cairo_surface_destroy (mask); - - cairo_set_source_rgba ( - cr, - ((point->rgba >> 24) & 0xff) / 255.0, - ((point->rgba >> 16) & 0xff) / 255.0, - ((point->rgba >> 8) & 0xff) / 255.0, - ( point->rgba & 0xff) / 255.0); - mask = cairo_image_surface_create_for_data (mask2, CAIRO_FORMAT_A8, 3, 3, 4); - cairo_mask_surface (cr, mask, px - 1, py - 1); - cairo_surface_destroy (mask); - - cairo_destroy (cr); -} - -/* Repaint point on X server */ - -static void -repaint_point (EMap *map, - EMapPoint *point) -{ - gdouble px, py; - - if (!gtk_widget_is_drawable (GTK_WIDGET (map))) - return; - - e_map_world_to_window (map, point->longitude, point->latitude, &px, &py); - - gtk_widget_queue_draw_area ( - GTK_WIDGET (map), - (gint) px - 2, (gint) py - 2, - 5, 5); -} - -static void -center_at (EMap *map, - gdouble longitude, - gdouble latitude) -{ - GtkAllocation allocation; - gint pb_width, pb_height; - gdouble x, y; - - e_map_world_to_render_surface (map, longitude, latitude, &x, &y); - - pb_width = E_MAP_GET_WIDTH (map); - pb_height = E_MAP_GET_HEIGHT (map); - - gtk_widget_get_allocation (GTK_WIDGET (map), &allocation); - - x = CLAMP (x - (allocation.width / 2), 0, pb_width - allocation.width); - y = CLAMP (y - (allocation.height / 2), 0, pb_height - allocation.height); - - gtk_adjustment_set_value (map->priv->hadjustment, x); - gtk_adjustment_set_value (map->priv->vadjustment, y); - - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -/* Scrolls the view to the specified offsets. Does not perform range checking! */ - -static void -scroll_to (EMap *map, - gint x, - gint y) -{ - gint xofs, yofs; - - /* Compute offsets and check bounds */ - - xofs = x - map->priv->xofs; - yofs = y - map->priv->yofs; - - if (xofs == 0 && yofs == 0) - return; - - map->priv->xofs = x; - map->priv->yofs = y; - - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -static void -set_scroll_area (EMap *view, - gint width, - gint height) -{ - EMapPrivate *priv; - GtkAllocation allocation; - - priv = view->priv; - - if (!gtk_widget_get_realized (GTK_WIDGET (view))) - return; - - if (!priv->hadjustment || !priv->vadjustment) - return; - - g_object_freeze_notify (G_OBJECT (priv->hadjustment)); - g_object_freeze_notify (G_OBJECT (priv->vadjustment)); - - gtk_widget_get_allocation (GTK_WIDGET (view), &allocation); - - priv->xofs = CLAMP (priv->xofs, 0, width - allocation.width); - priv->yofs = CLAMP (priv->yofs, 0, height - allocation.height); - - gtk_adjustment_configure ( - priv->hadjustment, - priv->xofs, - 0, width, - SCROLL_STEP_SIZE, - allocation.width / 2, - allocation.width); - gtk_adjustment_configure ( - priv->vadjustment, - priv->yofs, - 0, height, - SCROLL_STEP_SIZE, - allocation.height / 2, - allocation.height); - - g_object_thaw_notify (G_OBJECT (priv->hadjustment)); - g_object_thaw_notify (G_OBJECT (priv->vadjustment)); -} diff --git a/widgets/misc/e-map.h b/widgets/misc/e-map.h deleted file mode 100644 index 059da7c2a5..0000000000 --- a/widgets/misc/e-map.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Hans Petter Jansson <hpj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_MAP_H -#define E_MAP_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_MAP \ - (e_map_get_type ()) -#define E_MAP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAP, EMap)) -#define E_MAP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAP, EMapClass)) -#define E_IS_MAP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAP)) -#define E_IS_MAP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAP)) -#define E_MAP_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAP, EMapClass)) - -G_BEGIN_DECLS - -typedef struct _EMap EMap; -typedef struct _EMapClass EMapClass; -typedef struct _EMapPrivate EMapPrivate; -typedef struct _EMapPoint EMapPoint; - -struct _EMap { - GtkWidget widget; - EMapPrivate *priv; -}; - -struct _EMapClass { - GtkWidgetClass parent_class; - - /* Notification signals */ - void (*zoom_fit) (EMap * view); - - /* GTK+ scrolling interface */ - void (*set_scroll_adjustments) (GtkWidget * widget, - GtkAdjustment * hadj, - GtkAdjustment * vadj); -}; - -/* The definition of Dot */ - -struct _EMapPoint { - gchar *name; /* Can be NULL */ - gdouble longitude, latitude; - guint32 rgba; - gpointer user_data; -}; - -/* --- Widget --- */ - -GType e_map_get_type (void); - -EMap *e_map_new (void); - -/* Stop doing redraws when map data changes (e.g. by modifying points) */ -void e_map_freeze (EMap *map); - -/* Do an immediate repaint, and start doing realtime repaints again */ -void e_map_thaw (EMap *map); - -/* --- Coordinate translation --- */ - -/* Translates window-relative coords to lat/long */ -void e_map_window_to_world (EMap *map, - gdouble win_x, gdouble win_y, - gdouble *world_longitude, gdouble *world_latitude); - -/* Translates lat/long to window-relative coordinates. Note that the - * returned coordinates can be negative or greater than the current size - * of the allocation area */ -void e_map_world_to_window (EMap *map, - gdouble world_longitude, gdouble world_latitude, - gdouble *win_x, gdouble *win_y); - -/* --- Zoom --- */ - -gdouble e_map_get_magnification (EMap *map); - -/* Pass TRUE if we want the smooth zoom hack */ -void e_map_set_smooth_zoom (EMap *map, gboolean state); - -/* TRUE if smooth zoom hack will be employed */ -gboolean e_map_get_smooth_zoom (EMap *map); - -/* NB: Function definition will change shortly */ -void e_map_zoom_to_location (EMap *map, gdouble longitude, gdouble latitude); - -/* Zoom to mag factor 1.0 */ -void e_map_zoom_out (EMap *map); - -/* --- Points --- */ - -EMapPoint *e_map_add_point (EMap *map, gchar *name, - gdouble longitude, gdouble latitude, - guint32 color_rgba); - -void e_map_remove_point (EMap *map, EMapPoint *point); - -void e_map_point_get_location (EMapPoint *point, - gdouble *longitude, gdouble *latitude); - -gchar *e_map_point_get_name (EMapPoint *point); - -guint32 e_map_point_get_color_rgba (EMapPoint *point); - -void e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba); - -void e_map_point_set_data (EMapPoint *point, gpointer data); - -gpointer e_map_point_get_data (EMapPoint *point); - -gboolean e_map_point_is_in_view (EMap *map, EMapPoint *point); - -EMapPoint *e_map_get_closest_point (EMap *map, gdouble longitude, gdouble latitude, - gboolean in_view); - -G_END_DECLS - -#endif diff --git a/widgets/misc/e-menu-tool-action.c b/widgets/misc/e-menu-tool-action.c deleted file mode 100644 index 3ed37cb008..0000000000 --- a/widgets/misc/e-menu-tool-action.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * e-menu-tool-action.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-menu-tool-action.h" - -G_DEFINE_TYPE ( - EMenuToolAction, - e_menu_tool_action, - GTK_TYPE_ACTION) - -static void -e_menu_tool_action_class_init (EMenuToolActionClass *class) -{ - GtkActionClass *action_class; - - action_class = GTK_ACTION_CLASS (class); - action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; -} - -static void -e_menu_tool_action_init (EMenuToolAction *action) -{ -} - -EMenuToolAction * -e_menu_tool_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *stock_id) -{ - g_return_val_if_fail (name != NULL, NULL); - - return g_object_new ( - E_TYPE_MENU_TOOL_ACTION, - "name", name, "label", label, "tooltip", - tooltip, "stock-id", stock_id, NULL); -} diff --git a/widgets/misc/e-menu-tool-action.h b/widgets/misc/e-menu-tool-action.h deleted file mode 100644 index e642edf958..0000000000 --- a/widgets/misc/e-menu-tool-action.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * e-menu-tool-action.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* This is a trivial GtkAction subclass that sets the toolbar - * item type to GtkMenuToolButton instead of GtkToolButton. */ - -#ifndef E_MENU_TOOL_ACTION_H -#define E_MENU_TOOL_ACTION_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_MENU_TOOL_ACTION \ - (e_menu_tool_action_get_type ()) -#define E_MENU_TOOL_ACTION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MENU_TOOL_ACTION, EMenuToolAction)) -#define E_MENU_TOOL_ACTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MENU_TOOL_ACTION, EMenuToolActionClass)) -#define E_IS_MENU_TOOL_ACTION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MENU_TOOL_ACTION)) -#define E_IS_MENU_TOOL_ACTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MENU_TOOL_ACTION)) -#define E_MENU_TOOL_ACTION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MENU_TOOL_ACTION, EMenuToolActionClass)) - -G_BEGIN_DECLS - -typedef struct _EMenuToolAction EMenuToolAction; -typedef struct _EMenuToolActionClass EMenuToolActionClass; - -struct _EMenuToolAction { - GtkAction parent; -}; - -struct _EMenuToolActionClass { - GtkActionClass parent_class; -}; - -GType e_menu_tool_action_get_type (void); -EMenuToolAction * - e_menu_tool_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *stock_id); - -G_END_DECLS - -#endif /* E_MENU_TOOL_ACTION_H */ diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c deleted file mode 100644 index c2a68d0c05..0000000000 --- a/widgets/misc/e-menu-tool-button.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * e-menu-tool-button.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-menu-tool-button.h" - -#define E_MENU_TOOL_BUTTON_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonPrivate)) - -struct _EMenuToolButtonPrivate { - gchar *prefer_item; -}; - -enum { - PROP_0, - PROP_PREFER_ITEM -}; - -G_DEFINE_TYPE ( - EMenuToolButton, - e_menu_tool_button, - GTK_TYPE_MENU_TOOL_BUTTON) - -static GtkWidget * -menu_tool_button_clone_image (GtkWidget *source) -{ - GtkIconSize size; - GtkImageType image_type; - const gchar *icon_name; - - /* XXX This isn't general purpose because it requires that the - * source image be using a named icon. Somewhat surprised - * GTK+ doesn't offer something like this. */ - image_type = gtk_image_get_storage_type (GTK_IMAGE (source)); - g_return_val_if_fail (image_type == GTK_IMAGE_ICON_NAME, NULL); - gtk_image_get_icon_name (GTK_IMAGE (source), &icon_name, &size); - - return gtk_image_new_from_icon_name (icon_name, size); -} - -static GtkMenuItem * -menu_tool_button_get_prefer_menu_item (GtkMenuToolButton *menu_tool_button) -{ - GtkWidget *menu; - GtkMenuItem *item = NULL; - GList *children; - const gchar *prefer_item; - - menu = gtk_menu_tool_button_get_menu (menu_tool_button); - if (!GTK_IS_MENU (menu)) - return NULL; - - children = gtk_container_get_children (GTK_CONTAINER (menu)); - if (children == NULL) - return NULL; - - prefer_item = e_menu_tool_button_get_prefer_item ( - E_MENU_TOOL_BUTTON (menu_tool_button)); - if (prefer_item != NULL && *prefer_item != '\0') { - GtkAction *action; - GList *iter; - - for (iter = children; iter != NULL; iter = iter->next) { - item = GTK_MENU_ITEM (iter->data); - - if (!item) - continue; - - action = gtk_activatable_get_related_action ( - GTK_ACTIVATABLE (item)); - if (action && g_strcmp0 (gtk_action_get_name (action), prefer_item) == 0) - break; - else if (!action && g_strcmp0 (gtk_widget_get_name (GTK_WIDGET (item)), prefer_item) == 0) - break; - - item = NULL; - } - } - - if (!item) - item = GTK_MENU_ITEM (children->data); - - g_list_free (children); - - return item; -} - -static void -menu_tool_button_update_button (GtkToolButton *tool_button) -{ - GtkMenuItem *menu_item; - GtkMenuToolButton *menu_tool_button; - GtkImageMenuItem *image_menu_item; - GtkAction *action; - GtkWidget *image; - gchar *tooltip = NULL; - - menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button); - menu_item = menu_tool_button_get_prefer_menu_item (menu_tool_button); - if (!GTK_IS_IMAGE_MENU_ITEM (menu_item)) - return; - - image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item); - image = gtk_image_menu_item_get_image (image_menu_item); - if (!GTK_IS_IMAGE (image)) - return; - - image = menu_tool_button_clone_image (image); - gtk_tool_button_set_icon_widget (tool_button, image); - gtk_widget_show (image); - - /* If the menu item is a proxy for a GtkAction, extract - * the action's tooltip and use it as our own tooltip. */ - action = gtk_activatable_get_related_action ( - GTK_ACTIVATABLE (menu_item)); - if (action != NULL) - g_object_get (action, "tooltip", &tooltip, NULL); - gtk_widget_set_tooltip_text (GTK_WIDGET (tool_button), tooltip); - g_free (tooltip); -} - -static void -menu_tool_button_clicked (GtkToolButton *tool_button) -{ - GtkMenuItem *menu_item; - GtkMenuToolButton *menu_tool_button; - - menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button); - menu_item = menu_tool_button_get_prefer_menu_item (menu_tool_button); - - if (GTK_IS_MENU_ITEM (menu_item)) - gtk_menu_item_activate (menu_item); -} - -static void -menu_tool_button_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PREFER_ITEM: - e_menu_tool_button_set_prefer_item ( - E_MENU_TOOL_BUTTON (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -menu_tool_button_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PREFER_ITEM: - g_value_set_string ( - value, e_menu_tool_button_get_prefer_item ( - E_MENU_TOOL_BUTTON (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -menu_tool_button_dispose (GObject *object) -{ - EMenuToolButtonPrivate *priv = E_MENU_TOOL_BUTTON (object)->priv; - - if (priv->prefer_item) { - g_free (priv->prefer_item); - priv->prefer_item = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_menu_tool_button_parent_class)->dispose (object); -} - -static void -e_menu_tool_button_class_init (EMenuToolButtonClass *class) -{ - GObjectClass *object_class; - GtkToolButtonClass *tool_button_class; - - g_type_class_add_private (class, sizeof (EMenuToolButtonPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = menu_tool_button_set_property; - object_class->get_property = menu_tool_button_get_property; - object_class->dispose = menu_tool_button_dispose; - - tool_button_class = GTK_TOOL_BUTTON_CLASS (class); - tool_button_class->clicked = menu_tool_button_clicked; - - g_object_class_install_property ( - object_class, - PROP_PREFER_ITEM, - g_param_spec_string ( - "prefer-item", - "Prefer Item", - "Name of an item to show instead of the first", - NULL, - G_PARAM_READWRITE)); -} - -static void -e_menu_tool_button_init (EMenuToolButton *button) -{ - button->priv = E_MENU_TOOL_BUTTON_GET_PRIVATE (button); - - button->priv->prefer_item = NULL; - - g_signal_connect ( - button, "notify::menu", - G_CALLBACK (menu_tool_button_update_button), NULL); -} - -GtkToolItem * -e_menu_tool_button_new (const gchar *label) -{ - return g_object_new (E_TYPE_MENU_TOOL_BUTTON, "label", label, NULL); -} - -void -e_menu_tool_button_set_prefer_item (EMenuToolButton *button, - const gchar *prefer_item) -{ - g_return_if_fail (button != NULL); - g_return_if_fail (E_IS_MENU_TOOL_BUTTON (button)); - - if (g_strcmp0 (button->priv->prefer_item, prefer_item) == 0) - return; - - g_free (button->priv->prefer_item); - button->priv->prefer_item = g_strdup (prefer_item); - - g_object_notify (G_OBJECT (button), "prefer-item"); -} - -const gchar * -e_menu_tool_button_get_prefer_item (EMenuToolButton *button) -{ - g_return_val_if_fail (button != NULL, NULL); - g_return_val_if_fail (E_IS_MENU_TOOL_BUTTON (button), NULL); - - return button->priv->prefer_item; -} diff --git a/widgets/misc/e-menu-tool-button.h b/widgets/misc/e-menu-tool-button.h deleted file mode 100644 index 803ec8ff58..0000000000 --- a/widgets/misc/e-menu-tool-button.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * e-menu-tool-button.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* EMenuToolButton is a variation of GtkMenuToolButton where the - * button icon always reflects the first menu item, and clicking - * the button activates the first menu item. */ - -#ifndef E_MENU_TOOL_BUTTON_H -#define E_MENU_TOOL_BUTTON_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_MENU_TOOL_BUTTON \ - (e_menu_tool_button_get_type ()) -#define E_MENU_TOOL_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButton)) -#define E_MENU_TOOL_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass)) -#define E_IS_MENU_TOOL_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MENU_TOOL_BUTTON)) -#define E_IS_MENU_TOOL_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MENU_TOOL_BUTTON)) -#define E_MENU_TOOL_BUTTON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass)) - -G_BEGIN_DECLS - -typedef struct _EMenuToolButton EMenuToolButton; -typedef struct _EMenuToolButtonPrivate EMenuToolButtonPrivate; -typedef struct _EMenuToolButtonClass EMenuToolButtonClass; - -struct _EMenuToolButton { - GtkMenuToolButton parent; - EMenuToolButtonPrivate *priv; -}; - -struct _EMenuToolButtonClass { - GtkMenuToolButtonClass parent_class; -}; - -GType e_menu_tool_button_get_type (void); -GtkToolItem * e_menu_tool_button_new (const gchar *label); -void e_menu_tool_button_set_prefer_item (EMenuToolButton *button, - const gchar *prefer_item); -const gchar * e_menu_tool_button_get_prefer_item (EMenuToolButton *button); - -G_END_DECLS - -#endif /* E_MENU_TOOL_BUTTON_H */ diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c deleted file mode 100644 index a3921a779f..0000000000 --- a/widgets/misc/e-online-button.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-online-button.h" - -#include <glib/gi18n.h> - -#define E_ONLINE_BUTTON_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate)) - -#define ONLINE_TOOLTIP \ - _("Evolution is currently online. Click this button to work offline.") - -#define OFFLINE_TOOLTIP \ - _("Evolution is currently offline. Click this button to work online.") - -#define NETWORK_UNAVAILABLE_TOOLTIP \ - _("Evolution is currently offline because the network is unavailable.") - -struct _EOnlineButtonPrivate { - GtkWidget *image; - gboolean online; -}; - -enum { - PROP_0, - PROP_ONLINE -}; - -G_DEFINE_TYPE ( - EOnlineButton, - e_online_button, - GTK_TYPE_BUTTON) - -static void -online_button_update_tooltip (EOnlineButton *button) -{ - const gchar *tooltip; - - if (e_online_button_get_online (button)) - tooltip = ONLINE_TOOLTIP; - else if (gtk_widget_get_sensitive (GTK_WIDGET (button))) - tooltip = OFFLINE_TOOLTIP; - else - tooltip = NETWORK_UNAVAILABLE_TOOLTIP; - - gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip); -} - -static void -online_button_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ONLINE: - e_online_button_set_online ( - E_ONLINE_BUTTON (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -online_button_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ONLINE: - g_value_set_boolean ( - value, e_online_button_get_online ( - E_ONLINE_BUTTON (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -online_button_dispose (GObject *object) -{ - EOnlineButtonPrivate *priv; - - priv = E_ONLINE_BUTTON_GET_PRIVATE (object); - - if (priv->image != NULL) { - g_object_unref (priv->image); - priv->image = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_online_button_parent_class)->dispose (object); -} - -static void -e_online_button_class_init (EOnlineButtonClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EOnlineButtonPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = online_button_set_property; - object_class->get_property = online_button_get_property; - object_class->dispose = online_button_dispose; - - g_object_class_install_property ( - object_class, - PROP_ONLINE, - g_param_spec_boolean ( - "online", - "Online", - "The button state is online", - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -e_online_button_init (EOnlineButton *button) -{ - GtkWidget *widget; - - button->priv = E_ONLINE_BUTTON_GET_PRIVATE (button); - - gtk_widget_set_can_focus (GTK_WIDGET (button), FALSE); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - - widget = gtk_image_new (); - gtk_container_add (GTK_CONTAINER (button), widget); - button->priv->image = g_object_ref (widget); - gtk_widget_show (widget); - - g_signal_connect ( - button, "notify::online", - G_CALLBACK (online_button_update_tooltip), NULL); - - g_signal_connect ( - button, "notify::sensitive", - G_CALLBACK (online_button_update_tooltip), NULL); -} - -GtkWidget * -e_online_button_new (void) -{ - return g_object_new (E_TYPE_ONLINE_BUTTON, NULL); -} - -gboolean -e_online_button_get_online (EOnlineButton *button) -{ - g_return_val_if_fail (E_IS_ONLINE_BUTTON (button), FALSE); - - return button->priv->online; -} - -void -e_online_button_set_online (EOnlineButton *button, - gboolean online) -{ - GtkImage *image; - GtkIconInfo *icon_info; - GtkIconTheme *icon_theme; - const gchar *filename; - const gchar *icon_name; - - g_return_if_fail (E_IS_ONLINE_BUTTON (button)); - - if (button->priv->online == online) - return; - - button->priv->online = online; - - image = GTK_IMAGE (button->priv->image); - icon_name = online ? "online" : "offline"; - icon_theme = gtk_icon_theme_get_default (); - - /* Prevent GTK+ from scaling these rectangular icons. */ - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, icon_name, GTK_ICON_SIZE_BUTTON, 0); - filename = gtk_icon_info_get_filename (icon_info); - gtk_image_set_from_file (image, filename); - gtk_icon_info_free (icon_info); - - g_object_notify (G_OBJECT (button), "online"); -} diff --git a/widgets/misc/e-online-button.h b/widgets/misc/e-online-button.h deleted file mode 100644 index 03f676d75c..0000000000 --- a/widgets/misc/e-online-button.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifndef E_ONLINE_BUTTON_H -#define E_ONLINE_BUTTON_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_ONLINE_BUTTON \ - (e_online_button_get_type ()) -#define E_ONLINE_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButton)) -#define E_ONLINE_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ONLINE_BUTTON, EOnlineButtonClass)) -#define E_IS_ONLINE_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ONLINE_BUTTON)) -#define E_IS_ONLINE_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ONLINE_BUTTON)) -#define E_ONLINE_BUTTON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonClass)) - -G_BEGIN_DECLS - -typedef struct _EOnlineButton EOnlineButton; -typedef struct _EOnlineButtonClass EOnlineButtonClass; -typedef struct _EOnlineButtonPrivate EOnlineButtonPrivate; - -struct _EOnlineButton { - GtkButton parent; - EOnlineButtonPrivate *priv; -}; - -struct _EOnlineButtonClass { - GtkButtonClass parent_class; -}; - -GType e_online_button_get_type (void); -GtkWidget * e_online_button_new (void); -gboolean e_online_button_get_online (EOnlineButton *button); -void e_online_button_set_online (EOnlineButton *button, - gboolean online); - -G_END_DECLS - -#endif /* E_ONLINE_BUTTON_H */ diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c deleted file mode 100644 index 3b8f16bbec..0000000000 --- a/widgets/misc/e-paned.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * e-paned.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-paned.h" - -#include <glib/gi18n-lib.h> - -#define E_PANED_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_PANED, EPanedPrivate)) - -#define SYNC_REQUEST_NONE 0 -#define SYNC_REQUEST_POSITION 1 -#define SYNC_REQUEST_PROPORTION 2 - -struct _EPanedPrivate { - gint hposition; - gint vposition; - gdouble proportion; - - gulong wse_handler_id; - - guint fixed_resize : 1; - guint sync_request : 2; - guint toplevel_ready : 1; -}; - -enum { - PROP_0, - PROP_HPOSITION, - PROP_VPOSITION, - PROP_PROPORTION, - PROP_FIXED_RESIZE -}; - -G_DEFINE_TYPE ( - EPaned, - e_paned, - GTK_TYPE_PANED) - -static gboolean -paned_queue_resize_on_idle (GtkWidget *paned) -{ - gtk_widget_queue_resize_no_redraw (paned); - - return FALSE; -} - -static gboolean -paned_window_state_event_cb (EPaned *paned, - GdkEventWindowState *event, - GtkWidget *toplevel) -{ - /* Wait for WITHDRAWN to change from 1 to 0. */ - if (!(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN)) - return FALSE; - - /* The whole point of this hack is to trap a point where if - * the window were to be maximized initially, the maximized - * allocation would already be negotiated. We're there now. - * Set a flag so we know it's safe to set GtkPaned position. */ - paned->priv->toplevel_ready = TRUE; - - if (paned->priv->sync_request != SYNC_REQUEST_NONE) - gtk_widget_queue_resize (GTK_WIDGET (paned)); - - /* We don't need to listen for window state events anymore. */ - g_signal_handler_disconnect (toplevel, paned->priv->wse_handler_id); - paned->priv->wse_handler_id = 0; - - return FALSE; -} - -static void -paned_notify_orientation_cb (EPaned *paned) -{ - /* Ignore the next "notify::position" emission. */ - if (e_paned_get_fixed_resize (paned)) - paned->priv->sync_request = SYNC_REQUEST_POSITION; - else - paned->priv->sync_request = SYNC_REQUEST_PROPORTION; - gtk_widget_queue_resize (GTK_WIDGET (paned)); -} - -static void -paned_notify_position_cb (EPaned *paned) -{ - GtkAllocation allocation; - GtkOrientable *orientable; - GtkOrientation orientation; - gdouble proportion; - gint position; - - /* If a sync has already been requested, do nothing. */ - if (paned->priv->sync_request != SYNC_REQUEST_NONE) - return; - - orientable = GTK_ORIENTABLE (paned); - orientation = gtk_orientable_get_orientation (orientable); - - gtk_widget_get_allocation (GTK_WIDGET (paned), &allocation); - position = gtk_paned_get_position (GTK_PANED (paned)); - - g_object_freeze_notify (G_OBJECT (paned)); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - position = MAX (0, allocation.width - position); - proportion = (gdouble) position / allocation.width; - - paned->priv->hposition = position; - g_object_notify (G_OBJECT (paned), "hposition"); - } else { - position = MAX (0, allocation.height - position); - proportion = (gdouble) position / allocation.height; - - paned->priv->vposition = position; - g_object_notify (G_OBJECT (paned), "vposition"); - } - - paned->priv->proportion = proportion; - g_object_notify (G_OBJECT (paned), "proportion"); - - if (e_paned_get_fixed_resize (paned)) - paned->priv->sync_request = SYNC_REQUEST_POSITION; - else - paned->priv->sync_request = SYNC_REQUEST_PROPORTION; - - g_object_thaw_notify (G_OBJECT (paned)); -} - -static void -paned_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_HPOSITION: - e_paned_set_hposition ( - E_PANED (object), - g_value_get_int (value)); - return; - - case PROP_VPOSITION: - e_paned_set_vposition ( - E_PANED (object), - g_value_get_int (value)); - return; - - case PROP_PROPORTION: - e_paned_set_proportion ( - E_PANED (object), - g_value_get_double (value)); - return; - - case PROP_FIXED_RESIZE: - e_paned_set_fixed_resize ( - E_PANED (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -paned_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_HPOSITION: - g_value_set_int ( - value, e_paned_get_hposition ( - E_PANED (object))); - return; - - case PROP_VPOSITION: - g_value_set_int ( - value, e_paned_get_vposition ( - E_PANED (object))); - return; - - case PROP_PROPORTION: - g_value_set_double ( - value, e_paned_get_proportion ( - E_PANED (object))); - return; - - case PROP_FIXED_RESIZE: - g_value_set_boolean ( - value, e_paned_get_fixed_resize ( - E_PANED (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -paned_realize (GtkWidget *widget) -{ - EPanedPrivate *priv; - GtkWidget *toplevel; - GdkWindowState state; - GdkWindow *window; - - priv = E_PANED_GET_PRIVATE (widget); - - /* Chain up to parent's realize() method. */ - GTK_WIDGET_CLASS (e_paned_parent_class)->realize (widget); - - /* XXX This would be easier if we could be notified of - * window state events directly, but I can't seem - * to make that happen. */ - - toplevel = gtk_widget_get_toplevel (widget); - window = gtk_widget_get_window (toplevel); - state = gdk_window_get_state (window); - - /* If the window is withdrawn, wait for it to be shown before - * setting the pane position. If the window is already shown, - * it's safe to set the pane position immediately. */ - if (state & GDK_WINDOW_STATE_WITHDRAWN) - priv->wse_handler_id = g_signal_connect_swapped ( - toplevel, "window-state-event", - G_CALLBACK (paned_window_state_event_cb), widget); - else - priv->toplevel_ready = TRUE; -} - -static void -paned_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EPaned *paned = E_PANED (widget); - GtkOrientable *orientable; - GtkOrientation orientation; - gdouble proportion; - gint allocated; - gint position; - - /* Chain up to parent's size_allocate() method. */ - GTK_WIDGET_CLASS (e_paned_parent_class)-> - size_allocate (widget, allocation); - - if (!paned->priv->toplevel_ready) - return; - - if (paned->priv->sync_request == SYNC_REQUEST_NONE) - return; - - orientable = GTK_ORIENTABLE (paned); - orientation = gtk_orientable_get_orientation (orientable); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - allocated = allocation->width; - position = e_paned_get_hposition (paned); - } else { - allocated = allocation->height; - position = e_paned_get_vposition (paned); - } - - proportion = e_paned_get_proportion (paned); - - if (paned->priv->sync_request == SYNC_REQUEST_POSITION) - position = MAX (0, allocated - position); - else - position = (1.0 - proportion) * allocated; - - gtk_paned_set_position (GTK_PANED (paned), position); - - paned->priv->sync_request = SYNC_REQUEST_NONE; - - /* gtk_paned_set_position() calls queue_resize, which cannot - * be called from size_allocate, so schedule it from an idle - * callback so the change takes effect. */ - g_idle_add_full ( - G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) paned_queue_resize_on_idle, - g_object_ref (paned), - (GDestroyNotify) g_object_unref); -} - -static void -e_paned_class_init (EPanedClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EPanedPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = paned_set_property; - object_class->get_property = paned_get_property; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = paned_realize; - widget_class->size_allocate = paned_size_allocate; - - g_object_class_install_property ( - object_class, - PROP_HPOSITION, - g_param_spec_int ( - "hposition", - "Horizontal Position", - "Pane position when oriented horizontally", - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_VPOSITION, - g_param_spec_int ( - "vposition", - "Vertical Position", - "Pane position when oriented vertically", - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_PROPORTION, - g_param_spec_double ( - "proportion", - "Proportion", - "Proportion of the 2nd pane size", - 0.0, - 1.0, - 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FIXED_RESIZE, - g_param_spec_boolean ( - "fixed-resize", - "Fixed Resize", - "Keep the 2nd pane fixed during resize", - TRUE, - G_PARAM_READWRITE)); -} - -static void -e_paned_init (EPaned *paned) -{ - paned->priv = E_PANED_GET_PRIVATE (paned); - - paned->priv->proportion = 0.5; - paned->priv->fixed_resize = TRUE; - - g_signal_connect ( - paned, "notify::orientation", - G_CALLBACK (paned_notify_orientation_cb), NULL); - - g_signal_connect ( - paned, "notify::position", - G_CALLBACK (paned_notify_position_cb), NULL); -} - -GtkWidget * -e_paned_new (GtkOrientation orientation) -{ - return g_object_new (E_TYPE_PANED, "orientation", orientation, NULL); -} - -gint -e_paned_get_hposition (EPaned *paned) -{ - g_return_val_if_fail (E_IS_PANED (paned), 0); - - return paned->priv->hposition; -} - -void -e_paned_set_hposition (EPaned *paned, - gint hposition) -{ - GtkOrientable *orientable; - GtkOrientation orientation; - - g_return_if_fail (E_IS_PANED (paned)); - - if (hposition == paned->priv->hposition) - return; - - paned->priv->hposition = hposition; - - g_object_notify (G_OBJECT (paned), "hposition"); - - orientable = GTK_ORIENTABLE (paned); - orientation = gtk_orientable_get_orientation (orientable); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - paned->priv->sync_request = SYNC_REQUEST_POSITION; - gtk_widget_queue_resize (GTK_WIDGET (paned)); - } -} - -gint -e_paned_get_vposition (EPaned *paned) -{ - g_return_val_if_fail (E_IS_PANED (paned), 0); - - return paned->priv->vposition; -} - -void -e_paned_set_vposition (EPaned *paned, - gint vposition) -{ - GtkOrientable *orientable; - GtkOrientation orientation; - - g_return_if_fail (E_IS_PANED (paned)); - - if (vposition == paned->priv->vposition) - return; - - paned->priv->vposition = vposition; - - g_object_notify (G_OBJECT (paned), "vposition"); - - orientable = GTK_ORIENTABLE (paned); - orientation = gtk_orientable_get_orientation (orientable); - - if (orientation == GTK_ORIENTATION_VERTICAL) { - paned->priv->sync_request = SYNC_REQUEST_POSITION; - gtk_widget_queue_resize (GTK_WIDGET (paned)); - } -} - -gdouble -e_paned_get_proportion (EPaned *paned) -{ - g_return_val_if_fail (E_IS_PANED (paned), 0.5); - - return paned->priv->proportion; -} - -void -e_paned_set_proportion (EPaned *paned, - gdouble proportion) -{ - g_return_if_fail (E_IS_PANED (paned)); - g_return_if_fail (CLAMP (proportion, 0.0, 1.0) == proportion); - - paned->priv->proportion = proportion; - - paned->priv->sync_request = SYNC_REQUEST_PROPORTION; - gtk_widget_queue_resize (GTK_WIDGET (paned)); - - g_object_notify (G_OBJECT (paned), "proportion"); -} - -gboolean -e_paned_get_fixed_resize (EPaned *paned) -{ - g_return_val_if_fail (E_IS_PANED (paned), FALSE); - - return paned->priv->fixed_resize; -} - -void -e_paned_set_fixed_resize (EPaned *paned, - gboolean fixed_resize) -{ - g_return_if_fail (E_IS_PANED (paned)); - - if (fixed_resize == paned->priv->fixed_resize) - return; - - paned->priv->fixed_resize = fixed_resize; - - g_object_notify (G_OBJECT (paned), "fixed-resize"); -} diff --git a/widgets/misc/e-paned.h b/widgets/misc/e-paned.h deleted file mode 100644 index 1867a0439e..0000000000 --- a/widgets/misc/e-paned.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * e-paned.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_PANED_H -#define E_PANED_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_PANED \ - (e_paned_get_type ()) -#define E_PANED(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_PANED, EPaned)) -#define E_PANED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_PANED, EPanedClass)) -#define E_IS_PANED(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_PANED)) -#define E_IS_PANED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_PANED)) -#define E_PANED_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_PANED, EPanedClass)) - -G_BEGIN_DECLS - -typedef struct _EPaned EPaned; -typedef struct _EPanedClass EPanedClass; -typedef struct _EPanedPrivate EPanedPrivate; - -struct _EPaned { - GtkPaned parent; - EPanedPrivate *priv; -}; - -struct _EPanedClass { - GtkPanedClass parent_class; -}; - -GType e_paned_get_type (void); -GtkWidget * e_paned_new (GtkOrientation orientation); -gint e_paned_get_hposition (EPaned *paned); -void e_paned_set_hposition (EPaned *paned, - gint hposition); -gint e_paned_get_vposition (EPaned *paned); -void e_paned_set_vposition (EPaned *paned, - gint vposition); -gdouble e_paned_get_proportion (EPaned *paned); -void e_paned_set_proportion (EPaned *paned, - gdouble proportion); -gboolean e_paned_get_fixed_resize (EPaned *paned); -void e_paned_set_fixed_resize (EPaned *paned, - gboolean fixed_resize); - -G_END_DECLS - -#endif /* E_PANED_H */ diff --git a/widgets/misc/e-picture-gallery.c b/widgets/misc/e-picture-gallery.c deleted file mode 100644 index 40e621b1ca..0000000000 --- a/widgets/misc/e-picture-gallery.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * e-picture-gallery.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-icon-factory.h" - -#include "e-picture-gallery.h" - -#define E_PICTURE_GALLERY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_PICTURE_GALLERY, EPictureGalleryPrivate)) - -struct _EPictureGalleryPrivate { - gboolean initialized; - gchar *path; - GFileMonitor *monitor; -}; - -enum { - PROP_0, - PROP_PATH -}; - -enum { - COL_PIXBUF = 0, - COL_URI, - COL_FILENAME_TEXT -}; - -G_DEFINE_TYPE (EPictureGallery, e_picture_gallery, GTK_TYPE_ICON_VIEW) - -static gboolean -update_file_iter (GtkListStore *list_store, - GtkTreeIter *iter, - GFile *file, - gboolean force_thumbnail_update) -{ - GFileInfo *file_info; - gchar *uri; - gboolean res = FALSE; - - g_return_val_if_fail (list_store != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (file != NULL, FALSE); - - uri = g_file_get_uri (file); - - file_info = g_file_query_info ( - file, - G_FILE_ATTRIBUTE_THUMBNAIL_PATH "," - G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "," - G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," - G_FILE_ATTRIBUTE_STANDARD_SIZE, - G_FILE_QUERY_INFO_NONE, - NULL, - NULL); - - if (file_info != NULL) { - const gchar *existing_thumb = g_file_info_get_attribute_byte_string (file_info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); - gchar *new_thumb = NULL; - - if (!existing_thumb || force_thumbnail_update) { - gchar *filename; - - filename = g_file_get_path (file); - if (filename) { - new_thumb = e_icon_factory_create_thumbnail (filename); - if (new_thumb) - existing_thumb = new_thumb; - g_free (filename); - } - } - - if (existing_thumb && !g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED)) { - GdkPixbuf * pixbuf; - - pixbuf = gdk_pixbuf_new_from_file (existing_thumb, NULL); - - if (pixbuf) { - const gchar *filename; - gchar *filename_text = NULL; - guint64 filesize; - - filename = g_file_info_get_attribute_string (file_info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); - if (filename) { - filesize = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_STANDARD_SIZE); - if (filesize) { - gchar *tmp = g_format_size ((goffset) filesize); - filename_text = g_strdup_printf ("%s (%s)", filename, tmp); - g_free (tmp); - } - - res = TRUE; - gtk_list_store_set ( - list_store, iter, - COL_PIXBUF, pixbuf, - COL_URI, uri, - COL_FILENAME_TEXT, filename_text ? filename_text : filename, - -1); - } - - g_object_unref (pixbuf); - g_free (filename_text); - } - } - - g_free (new_thumb); - } - - g_free (uri); - - return res; -} - -static void -add_file (GtkListStore *list_store, - GFile *file) -{ - GtkTreeIter iter; - - g_return_if_fail (list_store != NULL); - g_return_if_fail (file != NULL); - - gtk_list_store_append (list_store, &iter); - if (!update_file_iter (list_store, &iter, file, FALSE)) - gtk_list_store_remove (list_store, &iter); -} - -static gboolean -find_file_uri (GtkListStore *list_store, - const gchar *uri, - GtkTreeIter *iter) -{ - GtkTreeModel *model; - - g_return_val_if_fail (list_store != NULL, FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - model = GTK_TREE_MODEL (list_store); - g_return_val_if_fail (model != NULL, FALSE); - - if (!gtk_tree_model_get_iter_first (model, iter)) - return FALSE; - - do { - gchar *iter_uri = NULL; - - gtk_tree_model_get ( - model, iter, - COL_URI, &iter_uri, - -1); - - if (iter_uri && g_ascii_strcasecmp (uri, iter_uri) == 0) { - g_free (iter_uri); - return TRUE; - } - - g_free (iter_uri); - } while (gtk_tree_model_iter_next (model, iter)); - - return FALSE; -} - -static void -picture_gallery_dir_changed_cb (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - EPictureGallery *gallery) -{ - gchar *uri; - GtkListStore *list_store; - GtkTreeIter iter; - - g_return_if_fail (file != NULL); - - list_store = GTK_LIST_STORE (gtk_icon_view_get_model (GTK_ICON_VIEW (gallery))); - g_return_if_fail (list_store != NULL); - - uri = g_file_get_uri (file); - if (!uri) - return; - - switch (event_type) { - case G_FILE_MONITOR_EVENT_CREATED: - if (find_file_uri (list_store, uri, &iter)) { - if (!update_file_iter (list_store, &iter, file, TRUE)) - gtk_list_store_remove (list_store, &iter); - } else { - add_file (list_store, file); - } - break; - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - if (find_file_uri (list_store, uri, &iter)) { - if (!update_file_iter (list_store, &iter, file, TRUE)) - gtk_list_store_remove (list_store, &iter); - } - break; - case G_FILE_MONITOR_EVENT_DELETED: - if (find_file_uri (list_store, uri, &iter)) - gtk_list_store_remove (list_store, &iter); - break; - default: - break; - } - - g_free (uri); -} - -static gboolean -picture_gallery_start_loading_cb (EPictureGallery *gallery) -{ - GtkIconView *icon_view; - GtkListStore *list_store; - GDir *dir; - const gchar *dirname; - - icon_view = GTK_ICON_VIEW (gallery); - list_store = GTK_LIST_STORE (gtk_icon_view_get_model (icon_view)); - g_return_val_if_fail (list_store != NULL, FALSE); - - dirname = e_picture_gallery_get_path (gallery); - if (!dirname) - return FALSE; - - dir = g_dir_open (dirname, 0, NULL); - if (dir) { - GFile *file; - const gchar *basename; - - while ((basename = g_dir_read_name (dir)) != NULL) { - gchar *filename; - - filename = g_build_filename (dirname, basename, NULL); - file = g_file_new_for_path (filename); - - add_file (list_store, file); - - g_free (filename); - g_object_unref (file); - } - - g_dir_close (dir); - - file = g_file_new_for_path (dirname); - gallery->priv->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); - g_object_unref (file); - - if (gallery->priv->monitor) - g_signal_connect ( - gallery->priv->monitor, "changed", - G_CALLBACK (picture_gallery_dir_changed_cb), - gallery); - } - - g_object_unref (icon_view); - - return FALSE; -} - -const gchar * -e_picture_gallery_get_path (EPictureGallery *gallery) -{ - g_return_val_if_fail (gallery != NULL, NULL); - g_return_val_if_fail (E_IS_PICTURE_GALLERY (gallery), NULL); - g_return_val_if_fail (gallery->priv != NULL, NULL); - - return gallery->priv->path; -} - -static void -picture_gallery_set_path (EPictureGallery *gallery, - const gchar *path) -{ - g_return_if_fail (E_IS_PICTURE_GALLERY (gallery)); - g_return_if_fail (gallery->priv != NULL); - - g_free (gallery->priv->path); - - if (!path || !*path || !g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) - gallery->priv->path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)); - else - gallery->priv->path = g_strdup (path); -} - -static void -picture_gallery_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PATH: - g_value_set_string (value, e_picture_gallery_get_path (E_PICTURE_GALLERY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -picture_gallery_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PATH: - picture_gallery_set_path (E_PICTURE_GALLERY (object), g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -visible_cb (EPictureGallery *gallery) -{ - if (!gallery->priv->initialized && gtk_widget_get_visible (GTK_WIDGET (gallery))) { - gallery->priv->initialized = TRUE; - - g_idle_add ((GSourceFunc) picture_gallery_start_loading_cb, gallery); - } -} - -static void -picture_gallery_constructed (GObject *object) -{ - GtkIconView *icon_view; - GtkListStore *list_store; - GtkTargetEntry *targets; - GtkTargetList *list; - gint n_targets; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_picture_gallery_parent_class)->constructed (object); - - icon_view = GTK_ICON_VIEW (object); - - list_store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); - gtk_icon_view_set_model (icon_view, GTK_TREE_MODEL (list_store)); - g_object_unref (list_store); - - gtk_icon_view_set_pixbuf_column (icon_view, COL_PIXBUF); - gtk_icon_view_set_text_column (icon_view, COL_FILENAME_TEXT); - gtk_icon_view_set_tooltip_column (icon_view, -1); - - list = gtk_target_list_new (NULL, 0); - gtk_target_list_add_uri_targets (list, 0); - targets = gtk_target_table_new_from_list (list, &n_targets); - - gtk_icon_view_enable_model_drag_source ( - icon_view, GDK_BUTTON1_MASK, - targets, n_targets, GDK_ACTION_COPY); - - gtk_target_table_free (targets, n_targets); - gtk_target_list_unref (list); - - g_signal_connect (object, "notify::visible", G_CALLBACK (visible_cb), NULL); -} - -static void -picture_gallery_dispose (GObject *object) -{ - EPictureGallery *gallery; - - gallery = E_PICTURE_GALLERY (object); - - if (gallery->priv->monitor) { - g_object_unref (gallery->priv->monitor); - gallery->priv->monitor = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_picture_gallery_parent_class)->dispose (object); -} - -static void -e_picture_gallery_class_init (EPictureGalleryClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EPictureGalleryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->get_property = picture_gallery_get_property; - object_class->set_property = picture_gallery_set_property; - object_class->constructed = picture_gallery_constructed; - object_class->dispose = picture_gallery_dispose; - - g_object_class_install_property ( - object_class, - PROP_PATH, - g_param_spec_string ( - "path", - "Gallery path", - NULL, - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -} - -static void -e_picture_gallery_init (EPictureGallery *gallery) -{ - gallery->priv = E_PICTURE_GALLERY_GET_PRIVATE (gallery); - gallery->priv->initialized = FALSE; - gallery->priv->monitor = NULL; - picture_gallery_set_path (gallery, NULL); -} - -GtkWidget * -e_picture_gallery_new (const gchar *path) -{ - return g_object_new (E_TYPE_PICTURE_GALLERY, "path", path, NULL); -} diff --git a/widgets/misc/e-picture-gallery.h b/widgets/misc/e-picture-gallery.h deleted file mode 100644 index 6da23294c4..0000000000 --- a/widgets/misc/e-picture-gallery.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * e-picture-gallery.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_PICTURE_GALLERY_H -#define E_PICTURE_GALLERY_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_PICTURE_GALLERY \ - (e_picture_gallery_get_type ()) -#define E_PICTURE_GALLERY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_PICTURE_GALLERY, EPictureGallery)) -#define E_PICTURE_GALLERY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_PICTURE_GALLERY, EPictureGalleryClass)) -#define E_IS_PICTURE_GALLERY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_PICTURE_GALLERY)) -#define E_IS_PICTURE_GALLERY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_PICTURE_GALLERY)) -#define E_PICTURE_GALLERY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_PICTURE_GALLERY, EPictureGalleryClass)) - -G_BEGIN_DECLS - -typedef struct _EPictureGallery EPictureGallery; -typedef struct _EPictureGalleryClass EPictureGalleryClass; -typedef struct _EPictureGalleryPrivate EPictureGalleryPrivate; - -struct _EPictureGallery { - GtkIconView parent; - EPictureGalleryPrivate *priv; -}; - -struct _EPictureGalleryClass { - GtkIconViewClass parent_class; -}; - -GType e_picture_gallery_get_type (void); -GtkWidget * e_picture_gallery_new (const gchar *path); -const gchar * e_picture_gallery_get_path (EPictureGallery *gallery); - -G_END_DECLS - -#endif /* E_PICTURE_GALLERY_H */ diff --git a/widgets/misc/e-popup-action.c b/widgets/misc/e-popup-action.c deleted file mode 100644 index 27c90f67c3..0000000000 --- a/widgets/misc/e-popup-action.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * e-popup-action.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-popup-action.h" - -#include <glib/gi18n.h> - -#define E_POPUP_ACTION_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_POPUP_ACTION, EPopupActionPrivate)) - -enum { - PROP_0, - PROP_RELATED_ACTION, - PROP_USE_ACTION_APPEARANCE -}; - -struct _EPopupActionPrivate { - GtkAction *related_action; - gboolean use_action_appearance; - gulong activate_handler_id; - gulong notify_handler_id; -}; - -/* Forward Declarations */ -static void e_popup_action_activatable_init (GtkActivatableIface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EPopupAction, - e_popup_action, - GTK_TYPE_ACTION, - G_IMPLEMENT_INTERFACE ( - GTK_TYPE_ACTIVATABLE, - e_popup_action_activatable_init)) - -static void -popup_action_notify_cb (GtkAction *action, - GParamSpec *pspec, - GtkActivatable *activatable) -{ - GtkActivatableIface *iface; - - iface = GTK_ACTIVATABLE_GET_IFACE (activatable); - g_return_if_fail (iface->update != NULL); - - iface->update (activatable, action, pspec->name); -} - -static GtkAction * -popup_action_get_related_action (EPopupAction *popup_action) -{ - return popup_action->priv->related_action; -} - -static void -popup_action_set_related_action (EPopupAction *popup_action, - GtkAction *related_action) -{ - GtkActivatable *activatable; - - /* Do not call gtk_activatable_do_set_related_action() because - * it assumes the activatable object is a widget and tries to add - * it to the related actions's proxy list. Instead we'll just do - * the relevant steps manually. */ - - activatable = GTK_ACTIVATABLE (popup_action); - - if (related_action == popup_action->priv->related_action) - return; - - if (related_action != NULL) - g_object_ref (related_action); - - if (popup_action->priv->related_action != NULL) { - g_signal_handler_disconnect ( - popup_action, - popup_action->priv->activate_handler_id); - g_signal_handler_disconnect ( - popup_action->priv->related_action, - popup_action->priv->notify_handler_id); - popup_action->priv->activate_handler_id = 0; - popup_action->priv->notify_handler_id = 0; - g_object_unref (popup_action->priv->related_action); - } - - popup_action->priv->related_action = related_action; - - if (related_action != NULL) { - popup_action->priv->activate_handler_id = - g_signal_connect_swapped ( - popup_action, "activate", - G_CALLBACK (gtk_action_activate), - related_action); - popup_action->priv->notify_handler_id = - g_signal_connect ( - related_action, "notify", - G_CALLBACK (popup_action_notify_cb), - popup_action); - gtk_activatable_sync_action_properties ( - activatable, related_action); - } else - gtk_action_set_visible (GTK_ACTION (popup_action), FALSE); - - g_object_notify (G_OBJECT (popup_action), "related-action"); -} - -static gboolean -popup_action_get_use_action_appearance (EPopupAction *popup_action) -{ - return popup_action->priv->use_action_appearance; -} - -static void -popup_action_set_use_action_appearance (EPopupAction *popup_action, - gboolean use_action_appearance) -{ - GtkActivatable *activatable; - GtkAction *related_action; - - if (popup_action->priv->use_action_appearance == use_action_appearance) - return; - - popup_action->priv->use_action_appearance = use_action_appearance; - - g_object_notify (G_OBJECT (popup_action), "use-action-appearance"); - - activatable = GTK_ACTIVATABLE (popup_action); - related_action = popup_action_get_related_action (popup_action); - gtk_activatable_sync_action_properties (activatable, related_action); -} - -static void -popup_action_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_RELATED_ACTION: - popup_action_set_related_action ( - E_POPUP_ACTION (object), - g_value_get_object (value)); - return; - - case PROP_USE_ACTION_APPEARANCE: - popup_action_set_use_action_appearance ( - E_POPUP_ACTION (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -popup_action_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_RELATED_ACTION: - g_value_set_object ( - value, - popup_action_get_related_action ( - E_POPUP_ACTION (object))); - return; - - case PROP_USE_ACTION_APPEARANCE: - g_value_set_boolean ( - value, - popup_action_get_use_action_appearance ( - E_POPUP_ACTION (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -popup_action_dispose (GObject *object) -{ - EPopupActionPrivate *priv; - - priv = E_POPUP_ACTION_GET_PRIVATE (object); - - if (priv->related_action != NULL) { - g_signal_handler_disconnect ( - object, - priv->activate_handler_id); - g_signal_handler_disconnect ( - priv->related_action, - priv->notify_handler_id); - g_object_unref (priv->related_action); - priv->related_action = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_popup_action_parent_class)->dispose (object); -} - -static void -popup_action_update (GtkActivatable *activatable, - GtkAction *action, - const gchar *property_name) -{ - GObjectClass *class; - GParamSpec *pspec; - GValue *value; - - /* Ignore "action-group" changes" */ - if (strcmp (property_name, "action-group") == 0) - return; - - /* Ignore "visible" changes. */ - if (strcmp (property_name, "visible") == 0) - return; - - value = g_slice_new0 (GValue); - class = G_OBJECT_GET_CLASS (action); - pspec = g_object_class_find_property (class, property_name); - g_value_init (value, pspec->value_type); - - g_object_get_property (G_OBJECT (action), property_name, value); - - if (strcmp (property_name, "sensitive") == 0) - property_name = "visible"; - else if (!gtk_activatable_get_use_action_appearance (activatable)) - goto exit; - - g_object_set_property (G_OBJECT (activatable), property_name, value); - -exit: - g_value_unset (value); - g_slice_free (GValue, value); -} - -static void -popup_action_sync_action_properties (GtkActivatable *activatable, - GtkAction *action) -{ - if (action == NULL) - return; - - /* XXX GTK+ 2.18 is still missing accessor functions for - * "hide-if-empty" and "visible-overflown" properties. - * These are rarely used so we'll skip them for now. */ - - /* A popup action is never shown as insensitive. */ - gtk_action_set_sensitive (GTK_ACTION (activatable), TRUE); - - gtk_action_set_visible ( - GTK_ACTION (activatable), - gtk_action_get_sensitive (action)); - - gtk_action_set_visible_horizontal ( - GTK_ACTION (activatable), - gtk_action_get_visible_horizontal (action)); - - gtk_action_set_visible_vertical ( - GTK_ACTION (activatable), - gtk_action_get_visible_vertical (action)); - - gtk_action_set_is_important ( - GTK_ACTION (activatable), - gtk_action_get_is_important (action)); - - if (!gtk_activatable_get_use_action_appearance (activatable)) - return; - - gtk_action_set_label ( - GTK_ACTION (activatable), - gtk_action_get_label (action)); - - gtk_action_set_short_label ( - GTK_ACTION (activatable), - gtk_action_get_short_label (action)); - - gtk_action_set_tooltip ( - GTK_ACTION (activatable), - gtk_action_get_tooltip (action)); - - gtk_action_set_stock_id ( - GTK_ACTION (activatable), - gtk_action_get_stock_id (action)); - - gtk_action_set_gicon ( - GTK_ACTION (activatable), - gtk_action_get_gicon (action)); - - gtk_action_set_icon_name ( - GTK_ACTION (activatable), - gtk_action_get_icon_name (action)); -} - -static void -e_popup_action_class_init (EPopupActionClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EPopupActionPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = popup_action_set_property; - object_class->get_property = popup_action_get_property; - object_class->dispose = popup_action_dispose; - - g_object_class_override_property ( - object_class, - PROP_RELATED_ACTION, - "related-action"); - - g_object_class_override_property ( - object_class, - PROP_USE_ACTION_APPEARANCE, - "use-action-appearance"); -} - -static void -e_popup_action_init (EPopupAction *popup_action) -{ - popup_action->priv = E_POPUP_ACTION_GET_PRIVATE (popup_action); - popup_action->priv->use_action_appearance = TRUE; - - /* Remain invisible until we have a related action. */ - gtk_action_set_visible (GTK_ACTION (popup_action), FALSE); -} - -static void -e_popup_action_activatable_init (GtkActivatableIface *interface) -{ - interface->update = popup_action_update; - interface->sync_action_properties = popup_action_sync_action_properties; -} - -EPopupAction * -e_popup_action_new (const gchar *name) -{ - g_return_val_if_fail (name != NULL, NULL); - - return g_object_new (E_TYPE_POPUP_ACTION, "name", name, NULL); -} - -void -e_action_group_add_popup_actions (GtkActionGroup *action_group, - const EPopupActionEntry *entries, - guint n_entries) -{ - guint ii; - - g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); - - for (ii = 0; ii < n_entries; ii++) { - EPopupAction *popup_action; - GtkAction *related_action; - const gchar *label; - - label = gtk_action_group_translate_string ( - action_group, entries[ii].label); - - related_action = gtk_action_group_get_action ( - action_group, entries[ii].related); - - if (related_action == NULL) { - g_warning ( - "Related action '%s' not found in " - "action group '%s'", entries[ii].related, - gtk_action_group_get_name (action_group)); - continue; - } - - popup_action = e_popup_action_new (entries[ii].name); - - gtk_activatable_set_related_action ( - GTK_ACTIVATABLE (popup_action), related_action); - - if (label != NULL && *label != '\0') - gtk_action_set_label ( - GTK_ACTION (popup_action), label); - - gtk_action_group_add_action ( - action_group, GTK_ACTION (popup_action)); - - g_object_unref (popup_action); - } -} diff --git a/widgets/misc/e-popup-action.h b/widgets/misc/e-popup-action.h deleted file mode 100644 index 02469375d5..0000000000 --- a/widgets/misc/e-popup-action.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * e-popup-action.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* A popup action is an action that lives in a popup menu. It proxies an - * equivalent action in the main menu, with two differences: - * - * 1) If the main menu action is insensitive, the popup action is invisible. - * 2) The popup action may have a different label than the main menu action. - * - * To use: - * - * Create an array of EPopupActionEntry structs. Add the main menu actions - * that serve as related actions for the popup actions to an action group - * first. Then pass the same action group and the EPopupActionEntry array - * to e_action_group_add_popup_actions() to add popup actions. - */ - -#ifndef E_POPUP_ACTION_H -#define E_POPUP_ACTION_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_POPUP_ACTION \ - (e_popup_action_get_type ()) -#define E_POPUP_ACTION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_POPUP_ACTION, EPopupAction)) -#define E_POPUP_ACTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_POPUP_ACTION, EPopupActionClass)) -#define E_IS_POPUP_ACTION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_POPUP_ACTION)) -#define E_IS_POPUP_ACTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_POPUP_ACTION)) -#define E_POPUP_ACTION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_POPUP_ACTION, EPopupActionClass)) - -G_BEGIN_DECLS - -typedef struct _EPopupAction EPopupAction; -typedef struct _EPopupActionClass EPopupActionClass; -typedef struct _EPopupActionPrivate EPopupActionPrivate; -typedef struct _EPopupActionEntry EPopupActionEntry; - -struct _EPopupAction { - GtkAction parent; - EPopupActionPrivate *priv; -}; - -struct _EPopupActionClass { - GtkActionClass parent_class; -}; - -struct _EPopupActionEntry { - const gchar *name; - const gchar *label; /* optional: overrides the related action */ - const gchar *related; /* name of the related action */ -}; - -GType e_popup_action_get_type (void); -EPopupAction * e_popup_action_new (const gchar *name); - -void e_action_group_add_popup_actions - (GtkActionGroup *action_group, - const EPopupActionEntry *entries, - guint n_entries); - -G_END_DECLS - -#endif /* E_POPUP_ACTION_H */ diff --git a/widgets/misc/e-port-entry.c b/widgets/misc/e-port-entry.c deleted file mode 100644 index cf857b5d55..0000000000 --- a/widgets/misc/e-port-entry.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Authors: - * Dan Vratil <dvratil@redhat.com> - */ - -#include "e-port-entry.h" - -#include <config.h> -#include <errno.h> -#include <stddef.h> -#include <string.h> - -#define E_PORT_ENTRY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_PORT_ENTRY, EPortEntryPrivate)) - -struct _EPortEntryPrivate { - CamelNetworkSecurityMethod method; - CamelProviderPortEntry *entries; -}; - -enum { - PORT_NUM_COLUMN, - PORT_DESC_COLUMN, - PORT_IS_SSL_COLUMN -}; - -enum { - PROP_0, - PROP_IS_VALID, - PROP_PORT, - PROP_SECURITY_METHOD -}; - -G_DEFINE_TYPE ( - EPortEntry, - e_port_entry, - GTK_TYPE_COMBO_BOX) - -static GtkEntry * -port_entry_get_entry (EPortEntry *port_entry) -{ - return GTK_ENTRY (gtk_bin_get_child (GTK_BIN (port_entry))); -} - -static gboolean -port_entry_get_numeric_port (EPortEntry *port_entry, - gint *out_port) -{ - GtkEntry *entry; - const gchar *port_string; - gboolean valid; - gint port; - - entry = port_entry_get_entry (port_entry); - - port_string = gtk_entry_get_text (entry); - g_return_val_if_fail (port_string != NULL, FALSE); - - errno = 0; - port = strtol (port_string, NULL, 10); - valid = (errno == 0) && (port == CLAMP (port, 1, G_MAXUINT16)); - - if (valid && out_port != NULL) - *out_port = port; - - return valid; -} - -static void -port_entry_text_changed (GtkEditable *editable, - EPortEntry *port_entry) -{ - GObject *object = G_OBJECT (port_entry); - const gchar *desc = NULL; - gint port = 0; - gint ii = 0; - - g_object_freeze_notify (object); - - port_entry_get_numeric_port (port_entry, &port); - - if (port_entry->priv->entries != NULL) { - while (port_entry->priv->entries[ii].port > 0) { - if (port == port_entry->priv->entries[ii].port) { - desc = port_entry->priv->entries[ii].desc; - break; - } - ii++; - } - } - - if (desc != NULL) - gtk_widget_set_tooltip_text (GTK_WIDGET (port_entry), desc); - else - gtk_widget_set_has_tooltip (GTK_WIDGET (port_entry), FALSE); - - g_object_notify (object, "port"); - g_object_notify (object, "is-valid"); - - g_object_thaw_notify (object); -} - -static void -port_entry_method_changed (EPortEntry *port_entry) -{ - CamelNetworkSecurityMethod method; - gboolean standard_port = FALSE; - gboolean valid, have_ssl = FALSE, have_nossl = FALSE; - gint port = 0; - gint ii; - - method = e_port_entry_get_security_method (port_entry); - valid = port_entry_get_numeric_port (port_entry, &port); - - /* Only change the port number if it's currently on a standard - * port (i.e. listed in a CamelProviderPortEntry). Otherwise, - * leave custom port numbers alone. */ - - if (valid && port_entry->priv->entries != NULL) { - for (ii = 0; port_entry->priv->entries[ii].port > 0 && (!have_ssl || !have_nossl); ii++) { - /* Use only the first SSL/no-SSL port as a default in the list - * and skip the others */ - if (port_entry->priv->entries[ii].is_ssl) { - if (have_ssl) - continue; - have_ssl = TRUE; - } else { - if (have_nossl) - continue; - have_nossl = TRUE; - } - - if (port == port_entry->priv->entries[ii].port) { - standard_port = TRUE; - break; - } - } - } - - if (valid && !standard_port) - return; - - switch (method) { - case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT: - e_port_entry_activate_secured_port (port_entry, 0); - break; - default: - e_port_entry_activate_nonsecured_port (port_entry, 0); - break; - } -} - -static void -port_entry_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_PORT: - e_port_entry_set_port ( - E_PORT_ENTRY (object), - g_value_get_uint (value)); - return; - - case PROP_SECURITY_METHOD: - e_port_entry_set_security_method ( - E_PORT_ENTRY (object), - g_value_get_enum (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -port_entry_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_IS_VALID: - g_value_set_boolean ( - value, e_port_entry_is_valid ( - E_PORT_ENTRY (object))); - return; - - case PROP_PORT: - g_value_set_uint ( - value, e_port_entry_get_port ( - E_PORT_ENTRY (object))); - return; - - case PROP_SECURITY_METHOD: - g_value_set_enum ( - value, e_port_entry_get_security_method ( - E_PORT_ENTRY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -port_entry_constructed (GObject *object) -{ - GtkEntry *entry; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_port_entry_parent_class)->constructed (object); - - entry = port_entry_get_entry (E_PORT_ENTRY (object)); - - g_signal_connect_after ( - entry, "changed", - G_CALLBACK (port_entry_text_changed), object); -} - -static void -port_entry_get_preferred_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size) -{ - PangoContext *context; - PangoFontMetrics *metrics; - PangoFontDescription *font_desc; - GtkStyleContext *style_context; - GtkStateFlags state; - gint digit_width; - gint parent_entry_width_min; - gint parent_width_min; - GtkWidget *entry; - - style_context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); - gtk_style_context_get ( - style_context, state, "font", &font_desc, NULL); - context = gtk_widget_get_pango_context (GTK_WIDGET (widget)); - metrics = pango_context_get_metrics ( - context, font_desc, pango_context_get_language (context)); - - digit_width = PANGO_PIXELS ( - pango_font_metrics_get_approximate_digit_width (metrics)); - - /* Preferred width of the entry */ - entry = gtk_bin_get_child (GTK_BIN (widget)); - gtk_widget_get_preferred_width (entry, NULL, &parent_entry_width_min); - - /* Preferred width of a standard combobox */ - GTK_WIDGET_CLASS (e_port_entry_parent_class)-> - get_preferred_width (widget, &parent_width_min, NULL); - - /* 6 * digit_width - port number has max 5 - * digits + extra free space for better look */ - if (minimum_size != NULL) - *minimum_size = - parent_width_min - parent_entry_width_min + - 6 * digit_width; - - if (natural_size != NULL) - *natural_size = - parent_width_min - parent_entry_width_min + - 6 * digit_width; - - pango_font_metrics_unref (metrics); - pango_font_description_free (font_desc); -} - -static void -e_port_entry_class_init (EPortEntryClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EPortEntryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = port_entry_set_property; - object_class->get_property = port_entry_get_property; - object_class->constructed = port_entry_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->get_preferred_width = port_entry_get_preferred_width; - - g_object_class_install_property ( - object_class, - PROP_IS_VALID, - g_param_spec_boolean ( - "is-valid", - NULL, - NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_PORT, - g_param_spec_uint ( - "port", - NULL, - NULL, - 0, /* Min port, 0 = invalid port */ - G_MAXUINT16, /* Max port */ - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_SECURITY_METHOD, - g_param_spec_enum ( - "security-method", - "Security Method", - "Method used to establish a network connection", - CAMEL_TYPE_NETWORK_SECURITY_METHOD, - CAMEL_NETWORK_SECURITY_METHOD_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_port_entry_init (EPortEntry *port_entry) -{ - GtkCellRenderer *renderer; - GtkListStore *store; - - port_entry->priv = E_PORT_ENTRY_GET_PRIVATE (port_entry); - - store = gtk_list_store_new ( - 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); - - gtk_combo_box_set_model ( - GTK_COMBO_BOX (port_entry), GTK_TREE_MODEL (store)); - gtk_combo_box_set_entry_text_column ( - GTK_COMBO_BOX (port_entry), PORT_NUM_COLUMN); - gtk_combo_box_set_id_column ( - GTK_COMBO_BOX (port_entry), PORT_NUM_COLUMN); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_renderer_set_sensitive (renderer, TRUE); - gtk_cell_layout_pack_start ( - GTK_CELL_LAYOUT (port_entry), renderer, FALSE); - gtk_cell_layout_add_attribute ( - GTK_CELL_LAYOUT (port_entry), - renderer, "text", PORT_NUM_COLUMN); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_renderer_set_sensitive (renderer, FALSE); - gtk_cell_layout_pack_start ( - GTK_CELL_LAYOUT (port_entry), renderer, TRUE); - gtk_cell_layout_add_attribute ( - GTK_CELL_LAYOUT (port_entry), - renderer, "text", PORT_DESC_COLUMN); -} - -GtkWidget * -e_port_entry_new (void) -{ - return g_object_new ( - E_TYPE_PORT_ENTRY, "has-entry", TRUE, NULL); -} - -void -e_port_entry_set_camel_entries (EPortEntry *port_entry, - CamelProviderPortEntry *entries) -{ - GtkComboBox *combo_box; - GtkTreeIter iter; - GtkTreeModel *model; - GtkListStore *store; - gint port = 0; - gint i = 0; - - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - g_return_if_fail (entries); - - port_entry->priv->entries = entries; - - combo_box = GTK_COMBO_BOX (port_entry); - model = gtk_combo_box_get_model (combo_box); - - store = GTK_LIST_STORE (model); - gtk_list_store_clear (store); - - while (entries[i].port > 0) { - gchar *port_string; - - /* Grab the first port number. */ - if (port == 0) - port = entries[i].port; - - port_string = g_strdup_printf ("%i", entries[i].port); - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - PORT_NUM_COLUMN, port_string, - PORT_DESC_COLUMN, entries[i].desc, - PORT_IS_SSL_COLUMN, entries[i].is_ssl, - -1); - i++; - - g_free (port_string); - } - - e_port_entry_set_port (port_entry, port); -} - -gint -e_port_entry_get_port (EPortEntry *port_entry) -{ - gint port = 0; - - g_return_val_if_fail (E_IS_PORT_ENTRY (port_entry), 0); - - port_entry_get_numeric_port (port_entry, &port); - - return port; -} - -void -e_port_entry_set_port (EPortEntry *port_entry, - gint port) -{ - GtkEntry *entry; - gchar *port_string; - - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - entry = port_entry_get_entry (port_entry); - port_string = g_strdup_printf ("%i", port); - gtk_entry_set_text (entry, port_string); - g_free (port_string); -} - -gboolean -e_port_entry_is_valid (EPortEntry *port_entry) -{ - g_return_val_if_fail (E_IS_PORT_ENTRY (port_entry), FALSE); - - return port_entry_get_numeric_port (port_entry, NULL); -} - -CamelNetworkSecurityMethod -e_port_entry_get_security_method (EPortEntry *port_entry) -{ - g_return_val_if_fail ( - E_IS_PORT_ENTRY (port_entry), - CAMEL_NETWORK_SECURITY_METHOD_NONE); - - return port_entry->priv->method; -} - -void -e_port_entry_set_security_method (EPortEntry *port_entry, - CamelNetworkSecurityMethod method) -{ - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - port_entry->priv->method = method; - - port_entry_method_changed (port_entry); - - g_object_notify (G_OBJECT (port_entry), "security-method"); -} - -/** - * If there are more then one secured port in the model, you can specify - * which of the secured ports should be activated by specifying the index. - * The index counts only for secured ports, so if you have 5 ports of which - * ports 1, 3 and 5 are secured, the association is 0=>1, 1=>3, 2=>5 - */ -void -e_port_entry_activate_secured_port (EPortEntry *port_entry, - gint index) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean is_ssl; - gint iters = 0; - - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (port_entry)); - - if (!gtk_tree_model_get_iter_first (model, &iter)) - return; - - do { - gtk_tree_model_get ( - model, &iter, PORT_IS_SSL_COLUMN, &is_ssl, -1); - if (is_ssl && (iters == index)) { - gtk_combo_box_set_active_iter ( - GTK_COMBO_BOX (port_entry), &iter); - return; - } - - if (is_ssl) - iters++; - - } while (gtk_tree_model_iter_next (model, &iter)); -} - -/** - * If there are more then one unsecured port in the model, you can specify - * which of the unsecured ports should be activated by specifiying the index. - * The index counts only for unsecured ports, so if you have 5 ports, of which - * ports 2 and 4 are unsecured, the associtation is 0=>2, 1=>4 - */ -void -e_port_entry_activate_nonsecured_port (EPortEntry *port_entry, - gint index) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean is_ssl; - gint iters = 0; - - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (port_entry)); - - if (!gtk_tree_model_get_iter_first (model, &iter)) - return; - - do { - gtk_tree_model_get (model, &iter, PORT_IS_SSL_COLUMN, &is_ssl, -1); - if (!is_ssl && (iters == index)) { - gtk_combo_box_set_active_iter ( - GTK_COMBO_BOX (port_entry), &iter); - return; - } - - if (!is_ssl) - iters++; - - } while (gtk_tree_model_iter_next (model, &iter)); -} diff --git a/widgets/misc/e-port-entry.h b/widgets/misc/e-port-entry.h deleted file mode 100644 index 2ef9b45cf7..0000000000 --- a/widgets/misc/e-port-entry.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 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 - * - * Authors: - * Dan Vratil <dvratil@redhat.com> - */ - -#ifndef E_PORT_ENTRY_H -#define E_PORT_ENTRY_H - -#include <gtk/gtk.h> -#include <camel/camel.h> - -/* Standard GObject macros */ -#define E_TYPE_PORT_ENTRY \ - (e_port_entry_get_type ()) -#define E_PORT_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_PORT_ENTRY, EPortEntry)) -#define E_PORT_ENTRY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_PORT_ENTRY, EPortEntryClass)) -#define E_IS_PORT_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_PORT_ENTRY)) -#define E_IS_PORT_ENTRY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_PORT_ENTRY)) -#define E_PORT_ENTRY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_PORT_ENTRY, EPortEntryClass)) - -G_BEGIN_DECLS - -typedef struct _EPortEntry EPortEntry; -typedef struct _EPortEntryClass EPortEntryClass; -typedef struct _EPortEntryPrivate EPortEntryPrivate; - -struct _EPortEntry { - GtkComboBox parent; - EPortEntryPrivate *priv; -}; - -struct _EPortEntryClass { - GtkComboBoxClass parent_class; -}; - -GType e_port_entry_get_type (void) G_GNUC_CONST; -GtkWidget * e_port_entry_new (void); -void e_port_entry_set_camel_entries - (EPortEntry *port_entry, - CamelProviderPortEntry *entries); -gint e_port_entry_get_port (EPortEntry *port_entry); -void e_port_entry_set_port (EPortEntry *port_entry, - gint port); -gboolean e_port_entry_is_valid (EPortEntry *port_entry); -CamelNetworkSecurityMethod - e_port_entry_get_security_method - (EPortEntry *port_entry); -void e_port_entry_set_security_method - (EPortEntry *port_entry, - CamelNetworkSecurityMethod method); -void e_port_entry_activate_secured_port - (EPortEntry *port_entry, - gint index); -void e_port_entry_activate_nonsecured_port - (EPortEntry *port_entry, - gint index); - -G_END_DECLS - -#endif /* E_PORT_ENTRY_H */ diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c deleted file mode 100644 index 83c5ed0fd6..0000000000 --- a/widgets/misc/e-preferences-window.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * e-preferences-window.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-preferences-window.h" - -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> -#include <e-util/e-util.h> - -#define SWITCH_PAGE_INTERVAL 250 - -#define E_PREFERENCES_WINDOW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowPrivate)) - -struct _EPreferencesWindowPrivate { - gboolean setup; - gpointer shell; - - GtkWidget *icon_view; - GtkWidget *scroll; - GtkWidget *notebook; - GHashTable *index; - - GtkListStore *store; - GtkTreeModelFilter *filter; - const gchar *filter_view; -}; - -enum { - COLUMN_ID, /* G_TYPE_STRING */ - COLUMN_TEXT, /* G_TYPE_STRING */ - COLUMN_HELP, /* G_TYPE_STRING */ - COLUMN_PIXBUF, /* GDK_TYPE_PIXBUF */ - COLUMN_PAGE, /* G_TYPE_INT */ - COLUMN_SORT /* G_TYPE_INT */ -}; - -G_DEFINE_TYPE ( - EPreferencesWindow, - e_preferences_window, - GTK_TYPE_WINDOW) - -static gboolean -preferences_window_filter_view (GtkTreeModel *model, - GtkTreeIter *iter, - EPreferencesWindow *window) -{ - gchar *str; - gboolean visible = FALSE; - - if (!window->priv->filter_view) - return TRUE; - - gtk_tree_model_get (model, iter, COLUMN_ID, &str, -1); - if (strncmp (window->priv->filter_view, "mail", 4) == 0) { - /* Show everything except calendar */ - if (str && (strncmp (str, "cal", 3) == 0)) - visible = FALSE; - else - visible = TRUE; - } else if (strncmp (window->priv->filter_view, "cal", 3) == 0) { - /* Show only calendar and nothing else */ - if (str && (strncmp (str, "cal", 3) != 0)) - visible = FALSE; - else - visible = TRUE; - - } else /* In any other case, show everything */ - visible = TRUE; - - g_free (str); - - return visible; -} - -static GdkPixbuf * -preferences_window_load_pixbuf (const gchar *icon_name) -{ - GtkIconTheme *icon_theme; - GtkIconInfo *icon_info; - GdkPixbuf *pixbuf; - const gchar *filename; - gint size; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - - if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, 0)) - return NULL; - - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, icon_name, size, 0); - - if (icon_info == NULL) - return NULL; - - filename = gtk_icon_info_get_filename (icon_info); - - pixbuf = gdk_pixbuf_new_from_file (filename, &error); - - gtk_icon_info_free (icon_info); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - return pixbuf; -} - -static void -preferences_window_help_clicked_cb (EPreferencesWindow *window) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GList *list; - gchar *help = NULL; - - g_return_if_fail (window != NULL); - - model = GTK_TREE_MODEL (window->priv->filter); - list = gtk_icon_view_get_selected_items ( - GTK_ICON_VIEW (window->priv->icon_view)); - - if (list != NULL) { - gtk_tree_model_get_iter (model, &iter, list->data); - gtk_tree_model_get (model, &iter, COLUMN_HELP, &help, -1); - - } else if (gtk_tree_model_get_iter_first (model, &iter)) { - gint page_index, current_index; - - current_index = gtk_notebook_get_current_page ( - GTK_NOTEBOOK (window->priv->notebook)); - do { - gtk_tree_model_get ( - model, &iter, COLUMN_PAGE, &page_index, -1); - - if (page_index == current_index) { - gtk_tree_model_get ( - model, &iter, COLUMN_HELP, &help, -1); - break; - } - } while (gtk_tree_model_iter_next (model, &iter)); - } - - e_display_help (GTK_WINDOW (window), help ? help : "index"); - - g_free (help); -} - -static void -preferences_window_selection_changed_cb (EPreferencesWindow *window) -{ - GtkIconView *icon_view; - GtkNotebook *notebook; - GtkTreeModel *model; - GtkTreeIter iter; - GList *list; - gint page; - - icon_view = GTK_ICON_VIEW (window->priv->icon_view); - list = gtk_icon_view_get_selected_items (icon_view); - if (list == NULL) - return; - - model = GTK_TREE_MODEL (window->priv->filter); - gtk_tree_model_get_iter (model, &iter, list->data); - gtk_tree_model_get (model, &iter, COLUMN_PAGE, &page, -1); - - notebook = GTK_NOTEBOOK (window->priv->notebook); - gtk_notebook_set_current_page (notebook, page); - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); - - gtk_widget_grab_focus (GTK_WIDGET (icon_view)); -} - -static void -preferences_window_dispose (GObject *object) -{ - EPreferencesWindowPrivate *priv; - - priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object); - - if (priv->icon_view != NULL) { - g_object_unref (priv->icon_view); - priv->icon_view = NULL; - } - - if (priv->notebook != NULL) { - g_object_unref (priv->notebook); - priv->notebook = NULL; - } - - if (priv->shell) { - g_object_remove_weak_pointer (priv->shell, &priv->shell); - priv->shell = NULL; - } - - g_hash_table_remove_all (priv->index); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_preferences_window_parent_class)->dispose (object); -} - -static void -preferences_window_finalize (GObject *object) -{ - EPreferencesWindowPrivate *priv; - - priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object); - - g_hash_table_destroy (priv->index); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_preferences_window_parent_class)->finalize (object); -} - -static void -preferences_window_show (GtkWidget *widget) -{ - EPreferencesWindowPrivate *priv; - GtkIconView *icon_view; - GtkTreePath *path; - - priv = E_PREFERENCES_WINDOW_GET_PRIVATE (widget); - if (!priv->setup) - g_warning ("Preferences window has not been setup correctly"); - - icon_view = GTK_ICON_VIEW (priv->icon_view); - - path = gtk_tree_path_new_first (); - gtk_icon_view_select_path (icon_view, path); - gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - gtk_widget_grab_focus (priv->icon_view); - - /* Chain up to parent's show() method. */ - GTK_WIDGET_CLASS (e_preferences_window_parent_class)->show (widget); -} - -static void -e_preferences_window_class_init (EPreferencesWindowClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EPreferencesWindowPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = preferences_window_dispose; - object_class->finalize = preferences_window_finalize; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->show = preferences_window_show; -} - -static void -e_preferences_window_init (EPreferencesWindow *window) -{ - GtkListStore *store; - GtkWidget *container; - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *widget; - GHashTable *index; - const gchar *title; - GtkAccelGroup *accel_group; - - index = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gtk_tree_row_reference_free); - - window->priv = E_PREFERENCES_WINDOW_GET_PRIVATE (window); - window->priv->index = index; - window->priv->filter_view = NULL; - - store = gtk_list_store_new ( - 6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_INT); - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (store), COLUMN_SORT, GTK_SORT_ASCENDING); - window->priv->store = store; - - window->priv->filter = (GtkTreeModelFilter *) - gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); - gtk_tree_model_filter_set_visible_func ( - window->priv->filter, (GtkTreeModelFilterVisibleFunc) - preferences_window_filter_view, window, NULL); - - title = _("Evolution Preferences"); - gtk_window_set_title (GTK_WINDOW (window), title); - gtk_window_set_resizable (GTK_WINDOW (window), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (window), 12); - - g_signal_connect ( - window, "delete-event", - G_CALLBACK (gtk_widget_hide_on_delete), NULL); - - widget = gtk_vbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (window), widget); - gtk_widget_show (widget); - - vbox = widget; - - widget = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - hbox = widget; - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (widget), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, TRUE, 0); - window->priv->scroll = widget; - gtk_widget_show (widget); - - container = widget; - - widget = gtk_icon_view_new_with_model ( - GTK_TREE_MODEL (window->priv->filter)); - gtk_icon_view_set_columns (GTK_ICON_VIEW (widget), 1); - gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COLUMN_TEXT); - gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF); - g_signal_connect_swapped ( - widget, "selection-changed", - G_CALLBACK (preferences_window_selection_changed_cb), window); - gtk_container_add (GTK_CONTAINER (container), widget); - window->priv->icon_view = g_object_ref (widget); - gtk_widget_show (widget); - g_object_unref (store); - - widget = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - window->priv->notebook = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_hbutton_box_new (); - gtk_button_box_set_layout ( - GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_END); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_button_new_from_stock (GTK_STOCK_HELP); - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (preferences_window_help_clicked_cb), window); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_button_box_set_child_secondary ( - GTK_BUTTON_BOX (container), widget, TRUE); - gtk_widget_show (widget); - - widget = gtk_button_new_from_stock (GTK_STOCK_CLOSE); - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (gtk_widget_hide), window); - gtk_widget_set_can_default (widget, TRUE); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - accel_group = gtk_accel_group_new (); - gtk_widget_add_accelerator ( - widget, "activate", accel_group, - GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); - gtk_widget_grab_default (widget); - gtk_widget_show (widget); -} - -GtkWidget * -e_preferences_window_new (gpointer shell) -{ - EPreferencesWindow *window; - - window = g_object_new (E_TYPE_PREFERENCES_WINDOW, NULL); - - /* ideally should be an object property */ - window->priv->shell = shell; - if (shell) - g_object_add_weak_pointer (shell, &window->priv->shell); - - return GTK_WIDGET (window); -} - -gpointer -e_preferences_window_get_shell (EPreferencesWindow *window) -{ - g_return_val_if_fail (E_IS_PREFERENCES_WINDOW (window), NULL); - - return window->priv->shell; -} - -void -e_preferences_window_add_page (EPreferencesWindow *window, - const gchar *page_name, - const gchar *icon_name, - const gchar *caption, - const gchar *help_target, - EPreferencesWindowCreatePageFn create_fn, - gint sort_order) -{ - GtkTreeRowReference *reference; - GtkIconView *icon_view; - GtkNotebook *notebook; - GtkTreeModel *model; - GtkTreePath *path; - GHashTable *index; - GdkPixbuf *pixbuf; - GtkTreeIter iter; - GtkWidget *align; - gint page; - - g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); - g_return_if_fail (create_fn != NULL); - g_return_if_fail (page_name != NULL); - g_return_if_fail (icon_name != NULL); - g_return_if_fail (caption != NULL); - - icon_view = GTK_ICON_VIEW (window->priv->icon_view); - notebook = GTK_NOTEBOOK (window->priv->notebook); - - page = gtk_notebook_get_n_pages (notebook); - model = GTK_TREE_MODEL (window->priv->store); - pixbuf = preferences_window_load_pixbuf (icon_name); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - COLUMN_ID, page_name, - COLUMN_TEXT, caption, - COLUMN_HELP, help_target, - COLUMN_PIXBUF, pixbuf, - COLUMN_PAGE, page, - COLUMN_SORT, sort_order, - -1); - - index = window->priv->index; - path = gtk_tree_model_get_path (model, &iter); - reference = gtk_tree_row_reference_new (model, path); - g_hash_table_insert (index, g_strdup (page_name), reference); - gtk_tree_path_free (path); - - align = g_object_new (GTK_TYPE_ALIGNMENT, NULL); - gtk_widget_show (GTK_WIDGET (align)); - g_object_set_data (G_OBJECT (align), "create_fn", create_fn); - gtk_notebook_append_page (notebook, align, NULL); - gtk_container_child_set ( - GTK_CONTAINER (notebook), align, - "tab-fill", FALSE, "tab-expand", FALSE, NULL); - - /* Force GtkIconView to recalculate the text wrap width, - * otherwise we get a really narrow icon list on the left - * side of the preferences window. */ - gtk_icon_view_set_item_width (icon_view, -1); - gtk_widget_queue_resize (GTK_WIDGET (window)); -} - -void -e_preferences_window_show_page (EPreferencesWindow *window, - const gchar *page_name) -{ - GtkTreeRowReference *reference; - GtkIconView *icon_view; - GtkTreePath *path; - - g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); - g_return_if_fail (page_name != NULL); - g_return_if_fail (window->priv->setup); - - icon_view = GTK_ICON_VIEW (window->priv->icon_view); - reference = g_hash_table_lookup (window->priv->index, page_name); - g_return_if_fail (reference != NULL); - - path = gtk_tree_row_reference_get_path (reference); - gtk_icon_view_select_path (icon_view, path); - gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); -} - -void -e_preferences_window_filter_page (EPreferencesWindow *window, - const gchar *page_name) -{ - GtkTreeRowReference *reference; - GtkIconView *icon_view; - GtkTreePath *path; - - g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); - g_return_if_fail (page_name != NULL); - g_return_if_fail (window->priv->setup); - - icon_view = GTK_ICON_VIEW (window->priv->icon_view); - reference = g_hash_table_lookup (window->priv->index, page_name); - g_return_if_fail (reference != NULL); - - path = gtk_tree_row_reference_get_path (reference); - gtk_icon_view_select_path (icon_view, path); - gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - window->priv->filter_view = page_name; - gtk_tree_model_filter_refilter (window->priv->filter); - - /* XXX: We need a better solution to hide the icon view when - * there is just one entry */ - if (strncmp (page_name, "cal", 3) == 0) { - gtk_widget_hide (window->priv->scroll); - } else - gtk_widget_show (window->priv->scroll); -} - -/* - * Create all the deferred configuration pages. - */ -void -e_preferences_window_setup (EPreferencesWindow *window) -{ - gint i, num; - GtkNotebook *notebook; - GtkRequisition requisition; - gint width = -1, height = -1, content_width = -1, content_height = -1; - EPreferencesWindowPrivate *priv; - - g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); - - priv = E_PREFERENCES_WINDOW_GET_PRIVATE (window); - - if (priv->setup) - return; - - gtk_window_get_default_size (GTK_WINDOW (window), &width, &height); - if (width < 0 || height < 0) { - gtk_widget_get_preferred_size (GTK_WIDGET (window), &requisition, NULL); - - width = requisition.width; - height = requisition.height; - } - - notebook = GTK_NOTEBOOK (priv->notebook); - num = gtk_notebook_get_n_pages (notebook); - - for (i = 0; i < num; i++) { - GtkBin *align; - GtkWidget *content; - EPreferencesWindowCreatePageFn create_fn; - - align = GTK_BIN (gtk_notebook_get_nth_page (notebook, i)); - create_fn = g_object_get_data (G_OBJECT (align), "create_fn"); - - if (!create_fn || gtk_bin_get_child (align)) - continue; - - content = create_fn (window); - if (content) { - GtkScrolledWindow *scrolled; - - scrolled = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL)); - gtk_scrolled_window_add_with_viewport (scrolled, content); - gtk_scrolled_window_set_min_content_width (scrolled, 320); - gtk_scrolled_window_set_min_content_height (scrolled, 240); - gtk_scrolled_window_set_policy (scrolled, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (scrolled, GTK_SHADOW_NONE); - - gtk_viewport_set_shadow_type ( - GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (scrolled))), - GTK_SHADOW_NONE); - - gtk_widget_show (content); - - gtk_widget_get_preferred_size (GTK_WIDGET (content), &requisition, NULL); - - if (requisition.width > content_width) - content_width = requisition.width; - if (requisition.height > content_height) - content_height = requisition.height; - - gtk_widget_show (GTK_WIDGET (scrolled)); - - gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (scrolled)); - } - } - - if (content_width > 0 && content_height > 0 && width > 0 && height > 0) { - GdkScreen *screen; - GdkRectangle monitor_area; - gint x = 0, y = 0, monitor; - - screen = gtk_window_get_screen (GTK_WINDOW (window)); - gtk_window_get_position (GTK_WINDOW (window), &x, &y); - - monitor = gdk_screen_get_monitor_at_point (screen, x, y); - if (monitor < 0 || monitor >= gdk_screen_get_n_monitors (screen)) - monitor = 0; - - gdk_screen_get_monitor_workarea (screen, monitor, &monitor_area); - - if (content_width > monitor_area.width - width) - content_width = monitor_area.width - width; - - if (content_height > monitor_area.height - height) - content_height = monitor_area.height - height; - - if (content_width > 0 && content_height > 0) - gtk_window_set_default_size (GTK_WINDOW (window), width + content_width, height + content_height); - } - - priv->setup = TRUE; -} diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h deleted file mode 100644 index 72ae63eb7e..0000000000 --- a/widgets/misc/e-preferences-window.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * e-preferences-window.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_PREFERENCES_WINDOW_H -#define E_PREFERENCES_WINDOW_H - -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_PREFERENCES_WINDOW \ - (e_preferences_window_get_type ()) -#define E_PREFERENCES_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindow)) -#define E_PREFERENCES_WINDOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass)) -#define E_IS_PREFERENCES_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_PREFERENCES_WINDOW)) -#define E_IS_PREFERENCES_WINDOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_PREFERENCES_WINDOW)) -#define E_PREFERENCES_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_TYPE \ - ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass)) - -G_BEGIN_DECLS - -typedef struct _EPreferencesWindow EPreferencesWindow; -typedef struct _EPreferencesWindowClass EPreferencesWindowClass; -typedef struct _EPreferencesWindowPrivate EPreferencesWindowPrivate; - -struct _EPreferencesWindow { - GtkWindow parent; - EPreferencesWindowPrivate *priv; -}; - -struct _EPreferencesWindowClass { - GtkWindowClass parent_class; -}; - -typedef GtkWidget * - (*EPreferencesWindowCreatePageFn) - (EPreferencesWindow *window); - -GType e_preferences_window_get_type (void); -GtkWidget * e_preferences_window_new (gpointer shell); -gpointer e_preferences_window_get_shell (EPreferencesWindow *window); -void e_preferences_window_setup (EPreferencesWindow *window); -void e_preferences_window_add_page (EPreferencesWindow *window, - const gchar *page_name, - const gchar *icon_name, - const gchar *caption, - const gchar *help_target, - EPreferencesWindowCreatePageFn create_fn, - gint sort_order); -void e_preferences_window_show_page (EPreferencesWindow *window, - const gchar *page_name); -void e_preferences_window_filter_page - (EPreferencesWindow *window, - const gchar *page_name); - -G_END_DECLS - -#endif /* E_PREFERENCES_WINDOW_H */ diff --git a/widgets/misc/e-preview-pane.c b/widgets/misc/e-preview-pane.c deleted file mode 100644 index 92644ec883..0000000000 --- a/widgets/misc/e-preview-pane.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * e-preview-pane.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-preview-pane.h" - -#include <gdk/gdkkeysyms.h> - -#include <libevolution-utils/e-alert-sink.h> -#include <libevolution-utils/e-alert-dialog.h> - -#include "e-alert-bar.h" - -#define E_PREVIEW_PANE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_PREVIEW_PANE, EPreviewPanePrivate)) - -struct _EPreviewPanePrivate { - GtkWidget *alert_bar; - GtkWidget *web_view; - GtkWidget *search_bar; -}; - -enum { - PROP_0, - PROP_SEARCH_BAR, - PROP_WEB_VIEW -}; - -enum { - SHOW_SEARCH_BAR, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -/* Forward Declarations */ -static void e_preview_pane_alert_sink_init - (EAlertSinkInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EPreviewPane, - e_preview_pane, - GTK_TYPE_VBOX, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_preview_pane_alert_sink_init)) - -static void -preview_pane_set_web_view (EPreviewPane *preview_pane, - EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - g_return_if_fail (preview_pane->priv->web_view == NULL); - - preview_pane->priv->web_view = g_object_ref_sink (web_view); -} - -static void -preview_pane_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_WEB_VIEW: - preview_pane_set_web_view ( - E_PREVIEW_PANE (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -preview_pane_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SEARCH_BAR: - g_value_set_object ( - value, e_preview_pane_get_search_bar ( - E_PREVIEW_PANE (object))); - return; - - case PROP_WEB_VIEW: - g_value_set_object ( - value, e_preview_pane_get_web_view ( - E_PREVIEW_PANE (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -preview_pane_dispose (GObject *object) -{ - EPreviewPanePrivate *priv; - - priv = E_PREVIEW_PANE_GET_PRIVATE (object); - - if (priv->alert_bar != NULL) { - g_object_unref (priv->alert_bar); - priv->alert_bar = NULL; - } - - if (priv->search_bar != NULL) { - g_object_unref (priv->search_bar); - priv->search_bar = NULL; - } - - if (priv->web_view != NULL) { - g_object_unref (priv->web_view); - priv->web_view = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_preview_pane_parent_class)->dispose (object); -} - -static void -preview_pane_constructed (GObject *object) -{ - EPreviewPanePrivate *priv; - GtkWidget *widget; - - priv = E_PREVIEW_PANE_GET_PRIVATE (object); - - widget = e_alert_bar_new (); - gtk_box_pack_start (GTK_BOX (object), widget, FALSE, FALSE, 0); - priv->alert_bar = g_object_ref (widget); - /* EAlertBar controls its own visibility. */ - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (object), widget, TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (widget), priv->web_view); - gtk_widget_show (widget); - gtk_widget_show (priv->web_view); - - widget = e_search_bar_new (E_WEB_VIEW (priv->web_view)); - gtk_box_pack_start (GTK_BOX (object), widget, FALSE, FALSE, 0); - priv->search_bar = g_object_ref (widget); - gtk_widget_hide (widget); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_preview_pane_parent_class)->constructed (object); -} - -static void -preview_pane_show_search_bar (EPreviewPane *preview_pane) -{ - GtkWidget *search_bar; - - search_bar = preview_pane->priv->search_bar; - - if (!gtk_widget_get_visible (search_bar)) - gtk_widget_show (search_bar); -} - -static void -preview_pane_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - EPreviewPane *preview_pane; - EAlertBar *alert_bar; - GtkWidget *dialog; - GtkWindow *parent; - - preview_pane = E_PREVIEW_PANE (alert_sink); - alert_bar = E_ALERT_BAR (preview_pane->priv->alert_bar); - - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - case GTK_MESSAGE_WARNING: - case GTK_MESSAGE_QUESTION: - case GTK_MESSAGE_ERROR: - e_alert_bar_add_alert (alert_bar, alert); - break; - - default: - parent = GTK_WINDOW (alert_sink); - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - break; - } -} - -static void -e_preview_pane_class_init (EPreviewPaneClass *class) -{ - GObjectClass *object_class; - GtkBindingSet *binding_set; - - g_type_class_add_private (class, sizeof (EPreviewPanePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = preview_pane_set_property; - object_class->get_property = preview_pane_get_property; - object_class->dispose = preview_pane_dispose; - object_class->constructed = preview_pane_constructed; - - class->show_search_bar = preview_pane_show_search_bar; - - g_object_class_install_property ( - object_class, - PROP_SEARCH_BAR, - g_param_spec_object ( - "search-bar", - "Search Bar", - NULL, - E_TYPE_SEARCH_BAR, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_WEB_VIEW, - g_param_spec_object ( - "web-view", - "Web View", - NULL, - E_TYPE_WEB_VIEW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - signals[SHOW_SEARCH_BAR] = g_signal_new ( - "show-search-bar", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EPreviewPaneClass, show_search_bar), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - binding_set = gtk_binding_set_by_class (class); - - gtk_binding_entry_add_signal ( - binding_set, GDK_KEY_f, GDK_SHIFT_MASK | GDK_CONTROL_MASK, - "show-search-bar", 0); -} - -static void -e_preview_pane_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = preview_pane_submit_alert; -} - -static void -e_preview_pane_init (EPreviewPane *preview_pane) -{ - preview_pane->priv = E_PREVIEW_PANE_GET_PRIVATE (preview_pane); - - gtk_box_set_spacing (GTK_BOX (preview_pane), 1); -} - -GtkWidget * -e_preview_pane_new (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return g_object_new ( - E_TYPE_PREVIEW_PANE, - "web-view", web_view, NULL); -} - -EWebView * -e_preview_pane_get_web_view (EPreviewPane *preview_pane) -{ - g_return_val_if_fail (E_IS_PREVIEW_PANE (preview_pane), NULL); - - return E_WEB_VIEW (preview_pane->priv->web_view); -} - -ESearchBar * -e_preview_pane_get_search_bar (EPreviewPane *preview_pane) -{ - g_return_val_if_fail (E_IS_PREVIEW_PANE (preview_pane), NULL); - - return E_SEARCH_BAR (preview_pane->priv->search_bar); -} - -void -e_preview_pane_clear_alerts (EPreviewPane *preview_pane) -{ - g_return_if_fail (E_IS_PREVIEW_PANE (preview_pane)); - - e_alert_bar_clear (E_ALERT_BAR (preview_pane->priv->alert_bar)); -} - -void -e_preview_pane_show_search_bar (EPreviewPane *preview_pane) -{ - g_return_if_fail (E_IS_PREVIEW_PANE (preview_pane)); - - g_signal_emit (preview_pane, signals[SHOW_SEARCH_BAR], 0); -} diff --git a/widgets/misc/e-preview-pane.h b/widgets/misc/e-preview-pane.h deleted file mode 100644 index 01e216c1cc..0000000000 --- a/widgets/misc/e-preview-pane.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * e-preview-pane.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_PREVIEW_PANE_H -#define E_PREVIEW_PANE_H - -#include <gtk/gtk.h> -#include <misc/e-search-bar.h> -#include <misc/e-web-view.h> - -/* Standard GObject macros */ -#define E_TYPE_PREVIEW_PANE \ - (e_preview_pane_get_type ()) -#define E_PREVIEW_PANE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_PREVIEW_PANE, EPreviewPane)) -#define E_PREVIEW_PANE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_PREVIEW_PANE, EPreviewPaneClass)) -#define E_IS_PREVIEW_PANE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_PREVIEW_PANE)) -#define E_IS_PREVIEW_PANE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_PREVIEW_PANE)) -#define E_PREVIEW_PANE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_PREVIEW_PANE, EPreviewPaneClass)) - -G_BEGIN_DECLS - -typedef struct _EPreviewPane EPreviewPane; -typedef struct _EPreviewPaneClass EPreviewPaneClass; -typedef struct _EPreviewPanePrivate EPreviewPanePrivate; - -struct _EPreviewPane { - GtkBox parent; - EPreviewPanePrivate *priv; -}; - -struct _EPreviewPaneClass { - GtkBoxClass parent_class; - - /* Signals */ - void (*show_search_bar) (EPreviewPane *preview_pane); -}; - -GType e_preview_pane_get_type (void); -GtkWidget * e_preview_pane_new (EWebView *web_view); -EWebView * e_preview_pane_get_web_view (EPreviewPane *preview_pane); -ESearchBar * e_preview_pane_get_search_bar (EPreviewPane *preview_pane); -void e_preview_pane_clear_alerts (EPreviewPane *preview_pane); -void e_preview_pane_show_search_bar (EPreviewPane *preview_pane); - -G_END_DECLS - -#endif /* E_PREVIEW_PANE_H */ diff --git a/widgets/misc/e-printable.c b/widgets/misc/e-printable.c deleted file mode 100644 index 2e98143b1a..0000000000 --- a/widgets/misc/e-printable.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-printable.h" - -#define EP_CLASS(e) ((EPrintableClass *)((GObject *)e)->class) - -G_DEFINE_TYPE ( - EPrintable, - e_printable, - G_TYPE_INITIALLY_UNOWNED) - -enum { - PRINT_PAGE, - DATA_LEFT, - RESET, - HEIGHT, - WILL_FIT, - LAST_SIGNAL -}; - -static guint e_printable_signals[LAST_SIGNAL] = { 0, }; - -static void -e_printable_class_init (EPrintableClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - e_printable_signals[PRINT_PAGE] = g_signal_new ( - "print_page", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EPrintableClass, print_page), - NULL, NULL, - e_marshal_NONE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, - G_TYPE_NONE, 4, - G_TYPE_OBJECT, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE, - G_TYPE_BOOLEAN); - - e_printable_signals[DATA_LEFT] = g_signal_new ( - "data_left", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EPrintableClass, data_left), - NULL, NULL, - e_marshal_BOOLEAN__NONE, - G_TYPE_BOOLEAN, 0, - G_TYPE_NONE); - - e_printable_signals[RESET] = g_signal_new ( - "reset", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EPrintableClass, reset), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, - G_TYPE_NONE); - - e_printable_signals[HEIGHT] = g_signal_new ( - "height", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EPrintableClass, height), - NULL, NULL, - e_marshal_DOUBLE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, - G_TYPE_DOUBLE, 4, - G_TYPE_OBJECT, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE, - G_TYPE_BOOLEAN); - - e_printable_signals[WILL_FIT] = g_signal_new ( - "will_fit", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EPrintableClass, will_fit), - NULL, NULL, - e_marshal_BOOLEAN__OBJECT_DOUBLE_DOUBLE_BOOLEAN, - G_TYPE_BOOLEAN, 4, - G_TYPE_OBJECT, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE, - G_TYPE_BOOLEAN); - - class->print_page = NULL; - class->data_left = NULL; - class->reset = NULL; - class->height = NULL; - class->will_fit = NULL; -} - -static void -e_printable_init (EPrintable *e_printable) -{ - /* nothing to do */ -} - -EPrintable * -e_printable_new (void) -{ - return E_PRINTABLE (g_object_new (E_PRINTABLE_TYPE, NULL)); -} - -void -e_printable_print_page (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble height, - gboolean quantized) -{ - g_return_if_fail (e_printable != NULL); - g_return_if_fail (E_IS_PRINTABLE (e_printable)); - - g_signal_emit ( - e_printable, - e_printable_signals[PRINT_PAGE], 0, - context, - width, - height, - quantized); -} - -gboolean -e_printable_data_left (EPrintable *e_printable) -{ - gboolean ret_val; - - g_return_val_if_fail (e_printable != NULL, FALSE); - g_return_val_if_fail (E_IS_PRINTABLE (e_printable), FALSE); - - g_signal_emit ( - e_printable, - e_printable_signals[DATA_LEFT], 0, - &ret_val); - - return ret_val; -} - -void -e_printable_reset (EPrintable *e_printable) -{ - g_return_if_fail (e_printable != NULL); - g_return_if_fail (E_IS_PRINTABLE (e_printable)); - - g_signal_emit ( - e_printable, - e_printable_signals[RESET], 0); -} - -gdouble -e_printable_height (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantized) -{ - gdouble ret_val; - - g_return_val_if_fail (e_printable != NULL, -1); - g_return_val_if_fail (E_IS_PRINTABLE (e_printable), -1); - - g_signal_emit ( - e_printable, - e_printable_signals[HEIGHT], 0, - context, - width, - max_height, - quantized, - &ret_val); - - return ret_val; -} - -gboolean -e_printable_will_fit (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantized) -{ - gboolean ret_val; - - g_return_val_if_fail (e_printable != NULL, FALSE); - g_return_val_if_fail (E_IS_PRINTABLE (e_printable), FALSE); - - g_signal_emit ( - e_printable, - e_printable_signals[WILL_FIT], 0, - context, - width, - max_height, - quantized, - &ret_val); - - return ret_val; -} diff --git a/widgets/misc/e-printable.h b/widgets/misc/e-printable.h deleted file mode 100644 index b8d9893799..0000000000 --- a/widgets/misc/e-printable.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_PRINTABLE_H_ -#define _E_PRINTABLE_H_ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define E_PRINTABLE_TYPE (e_printable_get_type ()) -#define E_PRINTABLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_PRINTABLE_TYPE, EPrintable)) -#define E_PRINTABLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_PRINTABLE_TYPE, EPrintableClass)) -#define E_IS_PRINTABLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_PRINTABLE_TYPE)) -#define E_IS_PRINTABLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_PRINTABLE_TYPE)) - -typedef struct { - GObject base; -} EPrintable; - -typedef struct { - GObjectClass parent_class; - - /* - * Signals - */ - - void (*print_page) (EPrintable *etm, GtkPrintContext *context, gdouble width, gdouble height, gboolean quantized); - gboolean (*data_left) (EPrintable *etm); - void (*reset) (EPrintable *etm); - gdouble (*height) (EPrintable *etm, GtkPrintContext *context, gdouble width, gdouble max_height, gboolean quantized); - - /* e_printable_will_fit (ep, ...) should be equal in value to - * (e_printable_print_page (ep, ...), - * !e_printable_data_left(ep)) except that the latter has the - * side effect of doing the printing and advancing the - * position of the printable. - */ - - gboolean (*will_fit) (EPrintable *etm, GtkPrintContext *context, gdouble width, gdouble max_height, gboolean quantized); -} EPrintableClass; - -GType e_printable_get_type (void); - -EPrintable *e_printable_new (void); - -/* - * Routines for emitting signals on the e_table */ -void e_printable_print_page (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble height, - gboolean quantized); -gboolean e_printable_data_left (EPrintable *e_printable); -void e_printable_reset (EPrintable *e_printable); -gdouble e_printable_height (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantized); -gboolean e_printable_will_fit (EPrintable *e_printable, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantized); - -G_END_DECLS - -#endif /* _E_PRINTABLE_H_ */ diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c deleted file mode 100644 index 9ed0c2d1c9..0000000000 --- a/widgets/misc/e-search-bar.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - * e-search-bar.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-search-bar.h" - -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> - -#define E_SEARCH_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate)) - -struct _ESearchBarPrivate { - EWebView *web_view; - GtkWidget *entry; - GtkWidget *case_sensitive_button; - GtkWidget *wrapped_next_box; - GtkWidget *wrapped_prev_box; - GtkWidget *matches_label; - - gchar *active_search; - - guint rerun_search : 1; -}; - -enum { - PROP_0, - PROP_ACTIVE_SEARCH, - PROP_CASE_SENSITIVE, - PROP_TEXT, - PROP_WEB_VIEW -}; - -enum { - CHANGED, - CLEAR, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE ( - ESearchBar, - e_search_bar, - GTK_TYPE_HBOX) - -static void -search_bar_update_matches (ESearchBar *search_bar, - guint matches) -{ - GtkWidget *matches_label; - gchar *text; - - search_bar->priv->rerun_search = FALSE; - matches_label = search_bar->priv->matches_label; - - text = g_strdup_printf (_("Matches: %u"), matches); - gtk_label_set_text (GTK_LABEL (matches_label), text); - gtk_widget_show (matches_label); - g_free (text); -} - -static void -search_bar_update_highlights (ESearchBar *search_bar) -{ - EWebView *web_view; - gboolean visible; - - web_view = e_search_bar_get_web_view (search_bar); - - visible = gtk_widget_get_visible (GTK_WIDGET (search_bar)); - - webkit_web_view_set_highlight_text_matches ( - WEBKIT_WEB_VIEW (web_view), visible); - - e_search_bar_changed (search_bar); -} - -static void -search_bar_find (ESearchBar *search_bar, - gboolean search_forward) -{ - EWebView *web_view; - GtkWidget *widget; - gboolean case_sensitive; - gboolean new_search; - gboolean wrapped = FALSE; - gboolean success; - gchar *text; - - web_view = e_search_bar_get_web_view (search_bar); - case_sensitive = e_search_bar_get_case_sensitive (search_bar); - text = e_search_bar_get_text (search_bar); - - if (text == NULL || *text == '\0') { - e_search_bar_clear (search_bar); - g_free (text); - return; - } - - new_search = - (search_bar->priv->active_search == NULL) || - (g_strcmp0 (text, search_bar->priv->active_search) != 0); - - if (new_search) { - guint matches; - - webkit_web_view_unmark_text_matches ( - WEBKIT_WEB_VIEW (web_view)); - matches = webkit_web_view_mark_text_matches ( - WEBKIT_WEB_VIEW (web_view), - text, case_sensitive, 0); - webkit_web_view_set_highlight_text_matches ( - WEBKIT_WEB_VIEW (web_view), TRUE); - search_bar_update_matches (search_bar, matches); - } - - success = webkit_web_view_search_text ( - WEBKIT_WEB_VIEW (web_view), - text, case_sensitive, search_forward, FALSE); - - if (!success) - wrapped = webkit_web_view_search_text ( - WEBKIT_WEB_VIEW (web_view), - text, case_sensitive, search_forward, TRUE); - - g_free (search_bar->priv->active_search); - search_bar->priv->active_search = text; - - g_object_notify (G_OBJECT (search_bar), "active-search"); - - /* Update wrapped label visibility. */ - - widget = search_bar->priv->wrapped_next_box; - - if (wrapped && search_forward) - gtk_widget_show (widget); - else - gtk_widget_hide (widget); - - widget = search_bar->priv->wrapped_prev_box; - - if (wrapped && !search_forward) - gtk_widget_show (widget); - else - gtk_widget_hide (widget); -} - -static void -search_bar_changed_cb (ESearchBar *search_bar) -{ - g_object_notify (G_OBJECT (search_bar), "text"); -} - -static void -search_bar_find_next_cb (ESearchBar *search_bar) -{ - search_bar_find (search_bar, TRUE); -} - -static void -search_bar_find_previous_cb (ESearchBar *search_bar) -{ - search_bar_find (search_bar, FALSE); -} - -static void -search_bar_icon_release_cb (ESearchBar *search_bar, - GtkEntryIconPosition icon_pos, - GdkEvent *event) -{ - g_return_if_fail (icon_pos == GTK_ENTRY_ICON_SECONDARY); - - e_search_bar_clear (search_bar); - gtk_widget_grab_focus (search_bar->priv->entry); -} - -static void -search_bar_toggled_cb (ESearchBar *search_bar) -{ - g_free (search_bar->priv->active_search); - search_bar->priv->active_search = NULL; - - g_object_notify (G_OBJECT (search_bar), "active-search"); - g_object_notify (G_OBJECT (search_bar), "case-sensitive"); -} - -static void -search_bar_set_web_view (ESearchBar *search_bar, - EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - g_return_if_fail (search_bar->priv->web_view == NULL); - - search_bar->priv->web_view = g_object_ref (web_view); -} - -static void -search_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CASE_SENSITIVE: - e_search_bar_set_case_sensitive ( - E_SEARCH_BAR (object), - g_value_get_boolean (value)); - return; - - case PROP_TEXT: - e_search_bar_set_text ( - E_SEARCH_BAR (object), - g_value_get_string (value)); - return; - - case PROP_WEB_VIEW: - search_bar_set_web_view ( - E_SEARCH_BAR (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -search_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACTIVE_SEARCH: - g_value_set_boolean ( - value, e_search_bar_get_active_search ( - E_SEARCH_BAR (object))); - return; - - case PROP_CASE_SENSITIVE: - g_value_set_boolean ( - value, e_search_bar_get_case_sensitive ( - E_SEARCH_BAR (object))); - return; - - case PROP_TEXT: - g_value_take_string ( - value, e_search_bar_get_text ( - E_SEARCH_BAR (object))); - return; - - case PROP_WEB_VIEW: - g_value_set_object ( - value, e_search_bar_get_web_view ( - E_SEARCH_BAR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -search_bar_dispose (GObject *object) -{ - ESearchBarPrivate *priv; - - priv = E_SEARCH_BAR_GET_PRIVATE (object); - - if (priv->web_view != NULL) { - g_object_unref (priv->web_view); - priv->web_view = NULL; - } - - if (priv->entry != NULL) { - g_object_unref (priv->entry); - priv->entry = NULL; - } - - if (priv->case_sensitive_button != NULL) { - g_object_unref (priv->case_sensitive_button); - priv->case_sensitive_button = NULL; - } - - if (priv->wrapped_next_box != NULL) { - g_object_unref (priv->wrapped_next_box); - priv->wrapped_next_box = NULL; - } - - if (priv->wrapped_prev_box != NULL) { - g_object_unref (priv->wrapped_prev_box); - priv->wrapped_prev_box = NULL; - } - - if (priv->matches_label != NULL) { - g_object_unref (priv->matches_label); - priv->matches_label = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_search_bar_parent_class)->dispose (object); -} - -static void -search_bar_finalize (GObject *object) -{ - ESearchBarPrivate *priv; - - priv = E_SEARCH_BAR_GET_PRIVATE (object); - - g_free (priv->active_search); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_search_bar_parent_class)->finalize (object); -} - -static void -search_bar_constructed (GObject *object) -{ - ESearchBarPrivate *priv; - - priv = E_SEARCH_BAR_GET_PRIVATE (object); - - g_object_bind_property ( - object, "case-sensitive", - priv->case_sensitive_button, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_search_bar_parent_class)->constructed (object); -} - -static void -search_bar_show (GtkWidget *widget) -{ - ESearchBar *search_bar; - - search_bar = E_SEARCH_BAR (widget); - - /* Chain up to parent's show() method. */ - GTK_WIDGET_CLASS (e_search_bar_parent_class)->show (widget); - - gtk_widget_grab_focus (search_bar->priv->entry); - - search_bar_update_highlights (search_bar); -} - -static void -search_bar_hide (GtkWidget *widget) -{ - ESearchBar *search_bar; - - search_bar = E_SEARCH_BAR (widget); - - /* Chain up to parent's hide() method. */ - GTK_WIDGET_CLASS (e_search_bar_parent_class)->hide (widget); - - search_bar_update_highlights (search_bar); -} - -static gboolean -search_bar_key_press_event (GtkWidget *widget, - GdkEventKey *event) -{ - GtkWidgetClass *widget_class; - - if (event->keyval == GDK_KEY_Escape) { - gtk_widget_hide (widget); - return TRUE; - } - - /* Chain up to parent's key_press_event() method. */ - widget_class = GTK_WIDGET_CLASS (e_search_bar_parent_class); - return widget_class->key_press_event (widget, event); -} - -static void -search_bar_clear (ESearchBar *search_bar) -{ - WebKitWebView *web_view; - - g_free (search_bar->priv->active_search); - search_bar->priv->active_search = NULL; - - gtk_entry_set_text (GTK_ENTRY (search_bar->priv->entry), ""); - - gtk_widget_hide (search_bar->priv->wrapped_next_box); - gtk_widget_hide (search_bar->priv->wrapped_prev_box); - gtk_widget_hide (search_bar->priv->matches_label); - - search_bar_update_highlights (search_bar); - - web_view = WEBKIT_WEB_VIEW (search_bar->priv->web_view); - webkit_web_view_unmark_text_matches (web_view); - - g_object_notify (G_OBJECT (search_bar), "active-search"); -} - -static void -e_search_bar_class_init (ESearchBarClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (ESearchBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = search_bar_set_property; - object_class->get_property = search_bar_get_property; - object_class->dispose = search_bar_dispose; - object_class->finalize = search_bar_finalize; - object_class->constructed = search_bar_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->show = search_bar_show; - widget_class->hide = search_bar_hide; - widget_class->key_press_event = search_bar_key_press_event; - - class->clear = search_bar_clear; - - g_object_class_install_property ( - object_class, - PROP_ACTIVE_SEARCH, - g_param_spec_boolean ( - "active-search", - "Active Search", - NULL, - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_CASE_SENSITIVE, - g_param_spec_boolean ( - "case-sensitive", - "Case Sensitive", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TEXT, - g_param_spec_string ( - "text", - "Search Text", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WEB_VIEW, - g_param_spec_object ( - "web-view", - "Web View", - NULL, - E_TYPE_WEB_VIEW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ESearchBarClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CLEAR] = g_signal_new ( - "clear", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ESearchBarClass, clear), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_search_bar_init (ESearchBar *search_bar) -{ - GtkWidget *label; - GtkWidget *widget; - GtkWidget *container; - - search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar); - - gtk_box_set_spacing (GTK_BOX (search_bar), 12); - - container = GTK_WIDGET (search_bar); - - widget = gtk_hbox_new (FALSE, 1); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_button_new (); - gtk_button_set_image ( - GTK_BUTTON (widget), gtk_image_new_from_stock ( - GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)); - gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); - gtk_widget_set_tooltip_text (widget, _("Close the find bar")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (gtk_widget_hide), search_bar); - - widget = gtk_label_new_with_mnemonic (_("Fin_d:")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 3); - gtk_widget_show (widget); - - label = widget; - - widget = gtk_entry_new (); - gtk_entry_set_icon_from_stock ( - GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY, - GTK_STOCK_CLEAR); - gtk_entry_set_icon_tooltip_text ( - GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY, - _("Clear the search")); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_widget_set_size_request (widget, 200, -1); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - search_bar->priv->entry = g_object_ref (widget); - gtk_widget_show (widget); - - g_object_bind_property ( - search_bar, "active-search", - widget, "secondary-icon-sensitive", - G_BINDING_SYNC_CREATE); - - g_signal_connect_swapped ( - widget, "activate", - G_CALLBACK (search_bar_find_next_cb), search_bar); - - g_signal_connect_swapped ( - widget, "changed", - G_CALLBACK (search_bar_changed_cb), search_bar); - - g_signal_connect_swapped ( - widget, "icon-release", - G_CALLBACK (search_bar_icon_release_cb), search_bar); - - widget = gtk_button_new_with_mnemonic (_("_Previous")); - gtk_button_set_image ( - GTK_BUTTON (widget), gtk_image_new_from_stock ( - GTK_STOCK_GO_BACK, GTK_ICON_SIZE_MENU)); - gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); - gtk_widget_set_tooltip_text ( - widget, _("Find the previous occurrence of the phrase")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_object_bind_property ( - search_bar, "active-search", - widget, "sensitive", - G_BINDING_SYNC_CREATE); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (search_bar_find_previous_cb), search_bar); - - widget = gtk_button_new_with_mnemonic (_("_Next")); - gtk_button_set_image ( - GTK_BUTTON (widget), gtk_image_new_from_stock ( - GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU)); - gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); - gtk_widget_set_tooltip_text ( - widget, _("Find the next occurrence of the phrase")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_object_bind_property ( - search_bar, "active-search", - widget, "sensitive", - G_BINDING_SYNC_CREATE); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (search_bar_find_next_cb), search_bar); - - widget = gtk_check_button_new_with_mnemonic (_("Mat_ch case")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - search_bar->priv->case_sensitive_button = g_object_ref (widget); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "toggled", - G_CALLBACK (search_bar_toggled_cb), search_bar); - - g_signal_connect_swapped ( - widget, "toggled", - G_CALLBACK (search_bar_find_next_cb), search_bar); - - container = GTK_WIDGET (search_bar); - - widget = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - search_bar->priv->wrapped_next_box = g_object_ref (widget); - gtk_widget_hide (widget); - - container = widget; - - widget = gtk_image_new_from_icon_name ( - "wrapped", GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = gtk_label_new ( - _("Reached bottom of page, continued from top")); - gtk_label_set_ellipsize ( - GTK_LABEL (widget), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = GTK_WIDGET (search_bar); - - widget = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - search_bar->priv->wrapped_prev_box = g_object_ref (widget); - gtk_widget_hide (widget); - - container = widget; - - widget = gtk_image_new_from_icon_name ( - "wrapped", GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = gtk_label_new ( - _("Reached top of page, continued from bottom")); - gtk_label_set_ellipsize ( - GTK_LABEL (widget), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = GTK_WIDGET (search_bar); - - widget = gtk_label_new (NULL); - gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 12); - search_bar->priv->matches_label = g_object_ref (widget); - gtk_widget_show (widget); -} - -GtkWidget * -e_search_bar_new (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return g_object_new ( - E_TYPE_SEARCH_BAR, "web-view", web_view, NULL); -} - -void -e_search_bar_clear (ESearchBar *search_bar) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - g_signal_emit (search_bar, signals[CLEAR], 0); -} - -void -e_search_bar_changed (ESearchBar *search_bar) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - g_signal_emit (search_bar, signals[CHANGED], 0); -} - -EWebView * -e_search_bar_get_web_view (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - return search_bar->priv->web_view; -} - -gboolean -e_search_bar_get_active_search (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - - return (search_bar->priv->active_search != NULL); -} - -gboolean -e_search_bar_get_case_sensitive (ESearchBar *search_bar) -{ - GtkToggleButton *button; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - - button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button); - - return gtk_toggle_button_get_active (button); -} - -void -e_search_bar_set_case_sensitive (ESearchBar *search_bar, - gboolean case_sensitive) -{ - GtkToggleButton *button; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button); - - gtk_toggle_button_set_active (button, case_sensitive); - - g_object_notify (G_OBJECT (search_bar), "case-sensitive"); -} - -gchar * -e_search_bar_get_text (ESearchBar *search_bar) -{ - GtkEntry *entry; - const gchar *text; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - entry = GTK_ENTRY (search_bar->priv->entry); - text = gtk_entry_get_text (entry); - - return g_strstrip (g_strdup (text)); -} - -void -e_search_bar_set_text (ESearchBar *search_bar, - const gchar *text) -{ - GtkEntry *entry; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - entry = GTK_ENTRY (search_bar->priv->entry); - - if (text == NULL) - text = ""; - - /* This will trigger a "notify::text" signal. */ - gtk_entry_set_text (entry, text); -} diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h deleted file mode 100644 index 939a476e17..0000000000 --- a/widgets/misc/e-search-bar.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * e-search-bar.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_SEARCH_BAR_H -#define E_SEARCH_BAR_H - -#include <gtk/gtk.h> -#include <misc/e-web-view.h> - -/* Standard GObject macros */ -#define E_TYPE_SEARCH_BAR \ - (e_search_bar_get_type ()) -#define E_SEARCH_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBar)) -#define E_SEARCH_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SEARCH_BAR, ESearchBarClass)) -#define E_IS_SEARCH_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SEARCH_BAR)) -#define E_IS_SEARCH_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SEARCH_BAR)) -#define E_SEARCH_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBarClass)) - -G_BEGIN_DECLS - -typedef struct _ESearchBar ESearchBar; -typedef struct _ESearchBarClass ESearchBarClass; -typedef struct _ESearchBarPrivate ESearchBarPrivate; - -struct _ESearchBar { - GtkBox parent; - ESearchBarPrivate *priv; -}; - -struct _ESearchBarClass { - GtkBoxClass parent_class; - - /* Signals */ - void (*changed) (ESearchBar *search_bar); - void (*clear) (ESearchBar *search_bar); -}; - -GType e_search_bar_get_type (void); -GtkWidget * e_search_bar_new (EWebView *web_view); -void e_search_bar_clear (ESearchBar *search_bar); -void e_search_bar_changed (ESearchBar *search_bar); -EWebView * e_search_bar_get_web_view (ESearchBar *search_bar); -gboolean e_search_bar_get_active_search - (ESearchBar *search_bar); -gboolean e_search_bar_get_case_sensitive - (ESearchBar *search_bar); -void e_search_bar_set_case_sensitive - (ESearchBar *search_bar, - gboolean case_sensitive); -gchar * e_search_bar_get_text (ESearchBar *search_bar); -void e_search_bar_set_text (ESearchBar *search_bar, - const gchar *text); - -G_END_DECLS - -#endif /* E_SEARCH_BAR_H */ diff --git a/widgets/misc/e-selectable.c b/widgets/misc/e-selectable.c deleted file mode 100644 index b8e4337fef..0000000000 --- a/widgets/misc/e-selectable.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * e-selectable.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-selectable.h" - -G_DEFINE_INTERFACE ( - ESelectable, - e_selectable, - GTK_TYPE_WIDGET) - -static void -e_selectable_default_init (ESelectableInterface *interface) -{ - g_object_interface_install_property ( - interface, - g_param_spec_boxed ( - "copy-target-list", - "Copy Target List", - NULL, - GTK_TYPE_TARGET_LIST, - G_PARAM_READABLE)); - - g_object_interface_install_property ( - interface, - g_param_spec_boxed ( - "paste-target-list", - "Paste Target List", - NULL, - GTK_TYPE_TARGET_LIST, - G_PARAM_READABLE)); -} - -void -e_selectable_update_actions (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - g_return_if_fail (interface->update_actions != NULL); - - interface->update_actions ( - selectable, focus_tracker, - clipboard_targets, n_clipboard_targets); -} - -void -e_selectable_cut_clipboard (ESelectable *selectable) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - if (interface->cut_clipboard != NULL) - interface->cut_clipboard (selectable); -} - -void -e_selectable_copy_clipboard (ESelectable *selectable) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - if (interface->copy_clipboard != NULL) - interface->copy_clipboard (selectable); -} - -void -e_selectable_paste_clipboard (ESelectable *selectable) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - if (interface->paste_clipboard != NULL) - interface->paste_clipboard (selectable); -} - -void -e_selectable_delete_selection (ESelectable *selectable) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - if (interface->delete_selection != NULL) - interface->delete_selection (selectable); -} - -void -e_selectable_select_all (ESelectable *selectable) -{ - ESelectableInterface *interface; - - g_return_if_fail (E_IS_SELECTABLE (selectable)); - - interface = E_SELECTABLE_GET_INTERFACE (selectable); - - if (interface->select_all != NULL) - interface->select_all (selectable); -} - -GtkTargetList * -e_selectable_get_copy_target_list (ESelectable *selectable) -{ - GtkTargetList *target_list; - - g_return_val_if_fail (E_IS_SELECTABLE (selectable), NULL); - - g_object_get (selectable, "copy-target-list", &target_list, NULL); - - /* We want to return a borrowed reference to the target - * list, so undo the reference that g_object_get() added. */ - gtk_target_list_unref (target_list); - - return target_list; -} - -GtkTargetList * -e_selectable_get_paste_target_list (ESelectable *selectable) -{ - GtkTargetList *target_list; - - g_return_val_if_fail (E_IS_SELECTABLE (selectable), NULL); - - g_object_get (selectable, "paste-target-list", &target_list, NULL); - - /* We want to return a borrowed reference to the target - * list, so undo the reference that g_object_get() added. */ - gtk_target_list_unref (target_list); - - return target_list; -} diff --git a/widgets/misc/e-selectable.h b/widgets/misc/e-selectable.h deleted file mode 100644 index c9a0b6dded..0000000000 --- a/widgets/misc/e-selectable.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * e-selectable.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_SELECTABLE_H -#define E_SELECTABLE_H - -#include <gtk/gtk.h> -#include <misc/e-focus-tracker.h> - -/* Standard GObject macros */ -#define E_TYPE_SELECTABLE \ - (e_selectable_get_type ()) -#define E_SELECTABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SELECTABLE, ESelectable)) -#define E_IS_SELECTABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SELECTABLE)) -#define E_SELECTABLE_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE \ - ((obj), E_TYPE_SELECTABLE, ESelectableInterface)) - -G_BEGIN_DECLS - -typedef struct _ESelectable ESelectable; -typedef struct _ESelectableInterface ESelectableInterface; - -struct _ESelectableInterface { - GTypeInterface parent_iface; - - /* Required Methods */ - void (*update_actions) (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets); - - /* Optional Methods */ - void (*cut_clipboard) (ESelectable *selectable); - void (*copy_clipboard) (ESelectable *selectable); - void (*paste_clipboard) (ESelectable *selectable); - void (*delete_selection) (ESelectable *selectable); - void (*select_all) (ESelectable *selectable); -}; - -GType e_selectable_get_type (void); -void e_selectable_update_actions (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets); -void e_selectable_cut_clipboard (ESelectable *selectable); -void e_selectable_copy_clipboard (ESelectable *selectable); -void e_selectable_paste_clipboard (ESelectable *selectable); -void e_selectable_delete_selection (ESelectable *selectable); -void e_selectable_select_all (ESelectable *selectable); -GtkTargetList * e_selectable_get_copy_target_list - (ESelectable *selectable); -GtkTargetList * e_selectable_get_paste_target_list - (ESelectable *selectable); - -G_END_DECLS - -#endif /* E_SELECTABLE_H */ diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c deleted file mode 100644 index f2f5b93379..0000000000 --- a/widgets/misc/e-selection-model-array.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-selection-model-array.h" - -G_DEFINE_TYPE ( - ESelectionModelArray, - e_selection_model_array, - E_TYPE_SELECTION_MODEL) - -enum { - PROP_0, - PROP_CURSOR_ROW, - PROP_CURSOR_COL -}; - -void -e_selection_model_array_confirm_row_count (ESelectionModelArray *esma) -{ - if (esma->eba == NULL) { - gint row_count = e_selection_model_array_get_row_count (esma); - esma->eba = e_bit_array_new (row_count); - esma->selected_row = -1; - esma->selected_range_end = -1; - } -} - -static gint -es_row_model_to_sorted (ESelectionModelArray *esma, - gint model_row) -{ - if (model_row >= 0 && esma && esma->base.sorter && e_sorter_needs_sorting (esma->base.sorter)) - return e_sorter_model_to_sorted (esma->base.sorter, model_row); - - return model_row; -} - -static gint -es_row_sorted_to_model (ESelectionModelArray *esma, - gint sorted_row) -{ - if (sorted_row >= 0 && esma && esma->base.sorter && e_sorter_needs_sorting (esma->base.sorter)) - return e_sorter_sorted_to_model (esma->base.sorter, sorted_row); - - return sorted_row; -} - -/* FIXME: Should this deal with moving the selection if it's in single mode? */ -void -e_selection_model_array_delete_rows (ESelectionModelArray *esma, - gint row, - gint count) -{ - if (esma->eba) { - if (E_SELECTION_MODEL (esma)->mode == GTK_SELECTION_SINGLE) - e_bit_array_delete_single_mode (esma->eba, row, count); - else - e_bit_array_delete (esma->eba, row, count); - - if (esma->cursor_row >= row && esma->cursor_row < row + count) { - /* we should move the cursor_row, because some lines before us are going to be removed */ - if (esma->cursor_row_sorted >= e_bit_array_bit_count (esma->eba)) { - esma->cursor_row_sorted = e_bit_array_bit_count (esma->eba) - 1; - } - - if (esma->cursor_row_sorted >= 0) { - esma->cursor_row = es_row_sorted_to_model (esma, esma->cursor_row_sorted); - esma->selection_start_row = 0; - e_bit_array_change_one_row (esma->eba, esma->cursor_row, TRUE); - } else { - esma->cursor_row = -1; - esma->cursor_row_sorted = -1; - esma->selection_start_row = 0; - } - } else { - /* some code earlier changed the selected row, so just update the sorted one */ - if (esma->cursor_row >= row) - esma->cursor_row = MAX (0, esma->cursor_row - count); - - if (esma->cursor_row >= e_bit_array_bit_count (esma->eba)) - esma->cursor_row = e_bit_array_bit_count (esma->eba) - 1; - - if (esma->cursor_row >= 0) { - esma->cursor_row_sorted = es_row_model_to_sorted (esma, esma->cursor_row); - esma->selection_start_row = 0; - e_bit_array_change_one_row (esma->eba, esma->cursor_row, TRUE); - } else { - esma->cursor_row = -1; - esma->cursor_row_sorted = -1; - esma->selection_start_row = 0; - } - } - - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (E_SELECTION_MODEL (esma)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (esma), esma->cursor_row, esma->cursor_col); - } -} - -void -e_selection_model_array_insert_rows (ESelectionModelArray *esma, - gint row, - gint count) -{ - if (esma->eba) { - e_bit_array_insert (esma->eba, row, count); - - /* just recalculate new position of the previously set cursor row */ - esma->cursor_row = es_row_sorted_to_model (esma, esma->cursor_row_sorted); - - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (E_SELECTION_MODEL (esma)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (esma), esma->cursor_row, esma->cursor_col); - } -} - -void -e_selection_model_array_move_row (ESelectionModelArray *esma, - gint old_row, - gint new_row) -{ - ESelectionModel *esm = E_SELECTION_MODEL (esma); - - if (esma->eba) { - gboolean selected = e_bit_array_value_at (esma->eba, old_row); - gboolean cursor = (esma->cursor_row == old_row); - gint old_row_sorted, new_row_sorted; - - old_row_sorted = es_row_model_to_sorted (esma, old_row); - new_row_sorted = es_row_model_to_sorted (esma, new_row); - - if (old_row_sorted < esma->cursor_row_sorted && esma->cursor_row_sorted < new_row_sorted) - esma->cursor_row_sorted--; - else if (new_row_sorted < esma->cursor_row_sorted && esma->cursor_row_sorted < old_row_sorted) - esma->cursor_row_sorted++; - - e_bit_array_move_row (esma->eba, old_row, new_row); - - if (selected) { - if (esm->mode == GTK_SELECTION_SINGLE) - e_bit_array_select_single_row (esma->eba, new_row); - else - e_bit_array_change_one_row (esma->eba, new_row, TRUE); - } - if (cursor) { - esma->cursor_row = new_row; - esma->cursor_row_sorted = es_row_model_to_sorted (esma, esma->cursor_row); - } else - esma->cursor_row = es_row_sorted_to_model (esma, esma->cursor_row_sorted); - - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (esm); - e_selection_model_cursor_changed (esm, esma->cursor_row, esma->cursor_col); - } -} - -static void -esma_dispose (GObject *object) -{ - ESelectionModelArray *esma; - - esma = E_SELECTION_MODEL_ARRAY (object); - - if (esma->eba) { - g_object_unref (esma->eba); - esma->eba = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_selection_model_array_parent_class)->dispose (object); -} - -static void -esma_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (object); - - switch (property_id) { - case PROP_CURSOR_ROW: - g_value_set_int (value, esma->cursor_row); - break; - - case PROP_CURSOR_COL: - g_value_set_int (value, esma->cursor_col); - break; - } -} - -static void -esma_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ESelectionModel *esm = E_SELECTION_MODEL (object); - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (object); - - switch (property_id) { - case PROP_CURSOR_ROW: - e_selection_model_do_something (esm, g_value_get_int (value), esma->cursor_col, 0); - break; - - case PROP_CURSOR_COL: - e_selection_model_do_something (esm, esma->cursor_row, g_value_get_int (value), 0); - break; - } -} - -/** - * e_selection_model_is_row_selected - * @selection: #ESelectionModel to check - * @n: The row to check - * - * This routine calculates whether the given row is selected. - * - * Returns: %TRUE if the given row is selected - */ -static gboolean -esma_is_row_selected (ESelectionModel *selection, - gint n) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - if (esma->eba) - return e_bit_array_value_at (esma->eba, n); - else - return FALSE; -} - -/** - * e_selection_model_foreach - * @selection: #ESelectionModel to traverse - * @callback: The callback function to call back. - * @closure: The closure - * - * This routine calls the given callback function once for each - * selected row, passing closure as the closure. - */ -static void -esma_foreach (ESelectionModel *selection, - EForeachFunc callback, - gpointer closure) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - if (esma->eba) - e_bit_array_foreach (esma->eba, callback, closure); -} - -/** - * e_selection_model_clear - * @selection: #ESelectionModel to clear - * - * This routine clears the selection to no rows selected. - */ -static void -esma_clear (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - if (esma->eba) { - g_object_unref (esma->eba); - esma->eba = NULL; - } - esma->cursor_row = -1; - esma->cursor_col = -1; - esma->cursor_row_sorted = -1; - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (E_SELECTION_MODEL (esma)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (esma), -1, -1); -} - -#define PART(x,n) (((x) & (0x01010101 << n)) >> n) -#define SECTION(x, n) (((x) >> (n * 8)) & 0xff) - -/** - * e_selection_model_selected_count - * @selection: #ESelectionModel to count - * - * This routine calculates the number of rows selected. - * - * Returns: The number of rows selected in the given model. - */ -static gint -esma_selected_count (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - if (esma->eba) - return e_bit_array_selected_count (esma->eba); - else - return 0; -} - -/** - * e_selection_model_select_all - * @selection: #ESelectionModel to select all - * - * This routine selects all the rows in the given - * #ESelectionModel. - */ -static void -esma_select_all (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - - e_selection_model_array_confirm_row_count (esma); - - e_bit_array_select_all (esma->eba); - - esma->cursor_col = 0; - esma->cursor_row_sorted = 0; - esma->cursor_row = es_row_sorted_to_model (esma, esma->cursor_row_sorted); - esma->selection_start_row = esma->cursor_row; - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (E_SELECTION_MODEL (esma)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (esma), 0, 0); -} - -/** - * e_selection_model_invert_selection - * @selection: #ESelectionModel to invert - * - * This routine inverts all the rows in the given - * #ESelectionModel. - */ -static void -esma_invert_selection (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - - e_selection_model_array_confirm_row_count (esma); - - e_bit_array_invert_selection (esma->eba); - - esma->cursor_col = -1; - esma->cursor_row = -1; - esma->cursor_row_sorted = -1; - esma->selection_start_row = 0; - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_changed (E_SELECTION_MODEL (esma)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (esma), -1, -1); -} - -static gint -esma_row_count (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - e_selection_model_array_confirm_row_count (esma); - return e_bit_array_bit_count (esma->eba); -} - -static void -esma_change_one_row (ESelectionModel *selection, - gint row, - gboolean grow) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - e_selection_model_array_confirm_row_count (esma); - e_bit_array_change_one_row (esma->eba, row, grow); -} - -static void -esma_change_cursor (ESelectionModel *selection, - gint row, - gint col) -{ - ESelectionModelArray *esma; - - g_return_if_fail (selection != NULL); - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - esma = E_SELECTION_MODEL_ARRAY (selection); - - esma->cursor_row = row; - esma->cursor_col = col; - esma->cursor_row_sorted = es_row_model_to_sorted (esma, esma->cursor_row); -} - -static void -esma_change_range (ESelectionModel *selection, - gint start, - gint end, - gboolean grow) -{ - gint i; - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - if (start != end) { - if (selection->sorter && e_sorter_needs_sorting (selection->sorter)) { - for (i = start; i < end; i++) { - e_bit_array_change_one_row (esma->eba, e_sorter_sorted_to_model (selection->sorter, i), grow); - } - } else { - e_selection_model_array_confirm_row_count (esma); - e_bit_array_change_range (esma->eba, start, end, grow); - } - } -} - -static gint -esma_cursor_row (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - return esma->cursor_row; -} - -static gint -esma_cursor_col (ESelectionModel *selection) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - return esma->cursor_col; -} - -static void -esma_real_select_single_row (ESelectionModel *selection, - gint row) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - - e_selection_model_array_confirm_row_count (esma); - - e_bit_array_select_single_row (esma->eba, row); - - esma->selection_start_row = row; - esma->selected_row = row; - esma->selected_range_end = row; -} - -static void -esma_select_single_row (ESelectionModel *selection, - gint row) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - gint selected_row = esma->selected_row; - esma_real_select_single_row (selection, row); - - if (selected_row != -1 && esma->eba && selected_row < e_bit_array_bit_count (esma->eba)) { - if (selected_row != row) { - e_selection_model_selection_row_changed (selection, selected_row); - e_selection_model_selection_row_changed (selection, row); - } - } else { - e_selection_model_selection_changed (selection); - } -} - -static void -esma_toggle_single_row (ESelectionModel *selection, - gint row) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - - e_selection_model_array_confirm_row_count (esma); - e_bit_array_toggle_single_row (esma->eba, row); - - esma->selection_start_row = row; - esma->selected_row = -1; - esma->selected_range_end = -1; - e_selection_model_selection_row_changed (E_SELECTION_MODEL (esma), row); -} - -static void -esma_real_move_selection_end (ESelectionModel *selection, - gint row) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - gint old_start; - gint old_end; - gint new_start; - gint new_end; - if (selection->sorter && e_sorter_needs_sorting (selection->sorter)) { - old_start = MIN ( - e_sorter_model_to_sorted (selection->sorter, esma->selection_start_row), - e_sorter_model_to_sorted (selection->sorter, esma->cursor_row)); - old_end = MAX ( - e_sorter_model_to_sorted (selection->sorter, esma->selection_start_row), - e_sorter_model_to_sorted (selection->sorter, esma->cursor_row)) + 1; - new_start = MIN ( - e_sorter_model_to_sorted (selection->sorter, esma->selection_start_row), - e_sorter_model_to_sorted (selection->sorter, row)); - new_end = MAX ( - e_sorter_model_to_sorted (selection->sorter, esma->selection_start_row), - e_sorter_model_to_sorted (selection->sorter, row)) + 1; - } else { - old_start = MIN (esma->selection_start_row, esma->cursor_row); - old_end = MAX (esma->selection_start_row, esma->cursor_row) + 1; - new_start = MIN (esma->selection_start_row, row); - new_end = MAX (esma->selection_start_row, row) + 1; - } - /* This wouldn't work nearly so smoothly if one end of the selection weren't held in place. */ - if (old_start < new_start) - esma_change_range (selection, old_start, new_start, FALSE); - if (new_start < old_start) - esma_change_range (selection, new_start, old_start, TRUE); - if (old_end < new_end) - esma_change_range (selection, old_end, new_end, TRUE); - if (new_end < old_end) - esma_change_range (selection, new_end, old_end, FALSE); - esma->selected_row = -1; - esma->selected_range_end = -1; -} - -static void -esma_move_selection_end (ESelectionModel *selection, - gint row) -{ - esma_real_move_selection_end (selection, row); - e_selection_model_selection_changed (selection); -} - -static void -esma_set_selection_end (ESelectionModel *selection, - gint row) -{ - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (selection); - gint selected_range_end = esma->selected_range_end; - gint view_row = e_sorter_model_to_sorted (selection->sorter, row); - - esma_real_select_single_row (selection, esma->selection_start_row); - esma->cursor_row = esma->selection_start_row; - esma->cursor_row_sorted = es_row_model_to_sorted (esma, esma->cursor_row); - esma_real_move_selection_end (selection, row); - - esma->selected_range_end = view_row; - if (selected_range_end != -1 && view_row != -1) { - if (selected_range_end == view_row - 1 || - selected_range_end == view_row + 1) { - e_selection_model_selection_row_changed (selection, selected_range_end); - e_selection_model_selection_row_changed (selection, view_row); - } - } - e_selection_model_selection_changed (selection); -} - -gint -e_selection_model_array_get_row_count (ESelectionModelArray *esma) -{ - g_return_val_if_fail (esma != NULL, 0); - g_return_val_if_fail (E_IS_SELECTION_MODEL_ARRAY (esma), 0); - - if (E_SELECTION_MODEL_ARRAY_GET_CLASS (esma)->get_row_count) - return E_SELECTION_MODEL_ARRAY_GET_CLASS (esma)->get_row_count (esma); - else - return 0; -} - -static void -e_selection_model_array_init (ESelectionModelArray *esma) -{ - esma->eba = NULL; - esma->selection_start_row = 0; - esma->cursor_row = -1; - esma->cursor_col = -1; - esma->cursor_row_sorted = -1; - - esma->selected_row = -1; - esma->selected_range_end = -1; -} - -static void -e_selection_model_array_class_init (ESelectionModelArrayClass *class) -{ - GObjectClass *object_class; - ESelectionModelClass *esm_class; - - object_class = G_OBJECT_CLASS (class); - esm_class = E_SELECTION_MODEL_CLASS (class); - - object_class->dispose = esma_dispose; - object_class->get_property = esma_get_property; - object_class->set_property = esma_set_property; - - esm_class->is_row_selected = esma_is_row_selected; - esm_class->foreach = esma_foreach; - esm_class->clear = esma_clear; - esm_class->selected_count = esma_selected_count; - esm_class->select_all = esma_select_all; - esm_class->invert_selection = esma_invert_selection; - esm_class->row_count = esma_row_count; - - esm_class->change_one_row = esma_change_one_row; - esm_class->change_cursor = esma_change_cursor; - esm_class->cursor_row = esma_cursor_row; - esm_class->cursor_col = esma_cursor_col; - - esm_class->select_single_row = esma_select_single_row; - esm_class->toggle_single_row = esma_toggle_single_row; - esm_class->move_selection_end = esma_move_selection_end; - esm_class->set_selection_end = esma_set_selection_end; - - class->get_row_count = NULL; - - g_object_class_install_property ( - object_class, - PROP_CURSOR_ROW, - g_param_spec_int ( - "cursor_row", - "Cursor Row", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_COL, - g_param_spec_int ( - "cursor_col", - "Cursor Column", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); -} - diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h deleted file mode 100644 index 4e59789d95..0000000000 --- a/widgets/misc/e-selection-model-array.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_SELECTION_MODEL_ARRAY_H_ -#define _E_SELECTION_MODEL_ARRAY_H_ - -#include <misc/e-selection-model.h> -#include <e-util/e-bit-array.h> - -G_BEGIN_DECLS - -#define E_SELECTION_MODEL_ARRAY_TYPE (e_selection_model_array_get_type ()) -#define E_SELECTION_MODEL_ARRAY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_SELECTION_MODEL_ARRAY_TYPE, ESelectionModelArray)) -#define E_SELECTION_MODEL_ARRAY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_SELECTION_MODEL_ARRAY_TYPE, ESelectionModelArrayClass)) -#define E_IS_SELECTION_MODEL_ARRAY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_SELECTION_MODEL_ARRAY_TYPE)) -#define E_IS_SELECTION_MODEL_ARRAY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_SELECTION_MODEL_ARRAY_TYPE)) -#define E_SELECTION_MODEL_ARRAY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_SELECTION_MODEL_ARRAY_TYPE, ESelectionModelArrayClass)) - -typedef struct { - ESelectionModel base; - - EBitArray *eba; - - gint cursor_row; - gint cursor_col; - gint selection_start_row; - gint cursor_row_sorted; /* cursor_row passed through base::sorter if necessary */ - - guint model_changed_id; - guint model_row_inserted_id, model_row_deleted_id; - - /* Anything other than -1 means that the selection is a single - * row. This being -1 does not impart any information. */ - gint selected_row; - /* Anything other than -1 means that the selection is a all - * rows between selection_start_path and cursor_path where - * selected_range_end is the rwo number of cursor_path. This - * being -1 does not impart any information. */ - gint selected_range_end; - - guint frozen : 1; - guint selection_model_changed : 1; - guint group_info_changed : 1; -} ESelectionModelArray; - -typedef struct { - ESelectionModelClass parent_class; - - gint (*get_row_count) (ESelectionModelArray *selection); -} ESelectionModelArrayClass; - -GType e_selection_model_array_get_type (void); - -/* Protected Functions */ -void e_selection_model_array_insert_rows (ESelectionModelArray *esm, - gint row, - gint count); -void e_selection_model_array_delete_rows (ESelectionModelArray *esm, - gint row, - gint count); -void e_selection_model_array_move_row (ESelectionModelArray *esm, - gint old_row, - gint new_row); -void e_selection_model_array_confirm_row_count (ESelectionModelArray *esm); - -/* Protected Virtual Function */ -gint e_selection_model_array_get_row_count (ESelectionModelArray *esm); - -G_END_DECLS - -#endif /* _E_SELECTION_MODEL_ARRAY_H_ */ diff --git a/widgets/misc/e-selection-model-simple.c b/widgets/misc/e-selection-model-simple.c deleted file mode 100644 index e7bd0c2f16..0000000000 --- a/widgets/misc/e-selection-model-simple.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-util.h" - -#include "e-selection-model-array.h" -#include "e-selection-model-simple.h" - -static gint esms_get_row_count (ESelectionModelArray *esma); - -G_DEFINE_TYPE ( - ESelectionModelSimple, - e_selection_model_simple, - E_SELECTION_MODEL_ARRAY_TYPE) - -static void -e_selection_model_simple_init (ESelectionModelSimple *selection) -{ - selection->row_count = 0; -} - -static void -e_selection_model_simple_class_init (ESelectionModelSimpleClass *class) -{ - ESelectionModelArrayClass *esma_class; - - esma_class = E_SELECTION_MODEL_ARRAY_CLASS (class); - esma_class->get_row_count = esms_get_row_count; -} - -/** - * e_selection_model_simple_new - * - * This routine creates a new #ESelectionModelSimple. - * - * Returns: The new #ESelectionModelSimple. - */ -ESelectionModelSimple * -e_selection_model_simple_new (void) -{ - return g_object_new (E_SELECTION_MODEL_SIMPLE_TYPE, NULL); -} - -void -e_selection_model_simple_set_row_count (ESelectionModelSimple *esms, - gint row_count) -{ - if (esms->row_count != row_count) { - ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (esms); - if (esma->eba) - g_object_unref (esma->eba); - esma->eba = NULL; - esma->selected_row = -1; - esma->selected_range_end = -1; - } - - esms->row_count = row_count; -} - -static gint -esms_get_row_count (ESelectionModelArray *esma) -{ - ESelectionModelSimple *esms = E_SELECTION_MODEL_SIMPLE (esma); - - return esms->row_count; -} - -void -e_selection_model_simple_insert_rows (ESelectionModelSimple *esms, - gint row, - gint count) -{ - esms->row_count += count; - e_selection_model_array_insert_rows ( - E_SELECTION_MODEL_ARRAY (esms), row, count); -} - -void -e_selection_model_simple_delete_rows (ESelectionModelSimple *esms, - gint row, - gint count) -{ - esms->row_count -= count; - e_selection_model_array_delete_rows ( - E_SELECTION_MODEL_ARRAY (esms), row, count); -} - -void -e_selection_model_simple_move_row (ESelectionModelSimple *esms, - gint old_row, - gint new_row) -{ - e_selection_model_array_move_row ( - E_SELECTION_MODEL_ARRAY (esms), old_row, new_row); -} diff --git a/widgets/misc/e-selection-model-simple.h b/widgets/misc/e-selection-model-simple.h deleted file mode 100644 index 2433543ade..0000000000 --- a/widgets/misc/e-selection-model-simple.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_SELECTION_MODEL_SIMPLE_H_ -#define _E_SELECTION_MODEL_SIMPLE_H_ - -#include <misc/e-selection-model-array.h> - -G_BEGIN_DECLS - -#define E_SELECTION_MODEL_SIMPLE_TYPE (e_selection_model_simple_get_type ()) -#define E_SELECTION_MODEL_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_SELECTION_MODEL_SIMPLE_TYPE, ESelectionModelSimple)) -#define E_SELECTION_MODEL_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_SELECTION_MODEL_SIMPLE_TYPE, ESelectionModelSimpleClass)) -#define E_IS_SELECTION_MODEL_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_SELECTION_MODEL_SIMPLE_TYPE)) -#define E_IS_SELECTION_MODEL_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_SELECTION_MODEL_SIMPLE_TYPE)) - -typedef struct { - ESelectionModelArray parent; - - gint row_count; -} ESelectionModelSimple; - -typedef struct { - ESelectionModelArrayClass parent_class; -} ESelectionModelSimpleClass; - -GType e_selection_model_simple_get_type (void); -ESelectionModelSimple *e_selection_model_simple_new (void); - -void e_selection_model_simple_insert_rows (ESelectionModelSimple *esms, - gint row, - gint count); -void e_selection_model_simple_delete_rows (ESelectionModelSimple *esms, - gint row, - gint count); -void e_selection_model_simple_move_row (ESelectionModelSimple *esms, - gint old_row, - gint new_row); - -void e_selection_model_simple_set_row_count (ESelectionModelSimple *selection, - gint row_count); - -G_END_DECLS - -#endif /* _E_SELECTION_MODEL_SIMPLE_H_ */ - diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c deleted file mode 100644 index fece615838..0000000000 --- a/widgets/misc/e-selection-model.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-selection-model.h" - -G_DEFINE_TYPE ( - ESelectionModel, - e_selection_model, - G_TYPE_OBJECT) - -enum { - CURSOR_CHANGED, - CURSOR_ACTIVATED, - SELECTION_CHANGED, - SELECTION_ROW_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -enum { - PROP_0, - PROP_SORTER, - PROP_SELECTION_MODE, - PROP_CURSOR_MODE -}; - -inline static void -add_sorter (ESelectionModel *esm, - ESorter *sorter) -{ - esm->sorter = sorter; - if (sorter) { - g_object_ref (sorter); - } -} - -inline static void -drop_sorter (ESelectionModel *esm) -{ - if (esm->sorter) { - g_object_unref (esm->sorter); - } - esm->sorter = NULL; -} - -static void -esm_dispose (GObject *object) -{ - ESelectionModel *esm; - - esm = E_SELECTION_MODEL (object); - - drop_sorter (esm); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_selection_model_parent_class)->dispose (object); -} - -static void -esm_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ESelectionModel *esm = E_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_SORTER: - g_value_set_object (value, esm->sorter); - break; - - case PROP_SELECTION_MODE: - g_value_set_int (value, esm->mode); - break; - - case PROP_CURSOR_MODE: - g_value_set_int (value, esm->cursor_mode); - break; - } -} - -static void -esm_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ESelectionModel *esm = E_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_SORTER: - drop_sorter (esm); - add_sorter ( - esm, g_value_get_object (value) ? - E_SORTER (g_value_get_object (value)) : NULL); - break; - - case PROP_SELECTION_MODE: - esm->mode = g_value_get_int (value); - if (esm->mode == GTK_SELECTION_SINGLE) { - gint cursor_row = e_selection_model_cursor_row (esm); - gint cursor_col = e_selection_model_cursor_col (esm); - e_selection_model_do_something (esm, cursor_row, cursor_col, 0); - } - break; - - case PROP_CURSOR_MODE: - esm->cursor_mode = g_value_get_int (value); - break; - } -} - -static void -e_selection_model_init (ESelectionModel *selection) -{ - selection->mode = GTK_SELECTION_MULTIPLE; - selection->cursor_mode = E_CURSOR_SIMPLE; - selection->old_selection = -1; -} - -static void -e_selection_model_class_init (ESelectionModelClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = esm_dispose; - object_class->get_property = esm_get_property; - object_class->set_property = esm_set_property; - - signals[CURSOR_CHANGED] = g_signal_new ( - "cursor_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESelectionModelClass, cursor_changed), - NULL, NULL, - e_marshal_NONE__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - signals[CURSOR_ACTIVATED] = g_signal_new ( - "cursor_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESelectionModelClass, cursor_activated), - NULL, NULL, - e_marshal_NONE__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - signals[SELECTION_CHANGED] = g_signal_new ( - "selection_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESelectionModelClass, selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SELECTION_ROW_CHANGED] = g_signal_new ( - "selection_row_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESelectionModelClass, selection_row_changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - g_object_class_install_property ( - object_class, - PROP_SORTER, - g_param_spec_object ( - "sorter", - "Sorter", - NULL, - E_SORTER_TYPE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTION_MODE, - g_param_spec_int ( - "selection_mode", - "Selection Mode", - NULL, - GTK_SELECTION_NONE, - GTK_SELECTION_MULTIPLE, - GTK_SELECTION_SINGLE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_MODE, - g_param_spec_int ( - "cursor_mode", - "Cursor Mode", - NULL, - E_CURSOR_LINE, - E_CURSOR_SPREADSHEET, - E_CURSOR_LINE, - G_PARAM_READWRITE)); -} - -/** - * e_selection_model_is_row_selected - * @selection: #ESelectionModel to check - * @n: The row to check - * - * This routine calculates whether the given row is selected. - * - * Returns: %TRUE if the given row is selected - */ -gboolean -e_selection_model_is_row_selected (ESelectionModel *selection, - gint n) -{ - ESelectionModelClass *class; - - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_val_if_fail (class->is_row_selected != NULL, FALSE); - - return class->is_row_selected (selection, n); -} - -/** - * e_selection_model_foreach - * @selection: #ESelectionModel to traverse - * @callback: The callback function to call back. - * @closure: The closure - * - * This routine calls the given callback function once for each - * selected row, passing closure as the closure. - */ -void -e_selection_model_foreach (ESelectionModel *selection, - EForeachFunc callback, - gpointer closure) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - g_return_if_fail (callback != NULL); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->foreach != NULL); - - class->foreach (selection, callback, closure); -} - -/** - * e_selection_model_clear - * @selection: #ESelectionModel to clear - * - * This routine clears the selection to no rows selected. - */ -void -e_selection_model_clear (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->clear != NULL); - - class->clear (selection); -} - -/** - * e_selection_model_selected_count - * @selection: #ESelectionModel to count - * - * This routine calculates the number of rows selected. - * - * Returns: The number of rows selected in the given model. - */ -gint -e_selection_model_selected_count (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), 0); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_val_if_fail (class->selected_count != NULL, 0); - - return class->selected_count (selection); -} - -/** - * e_selection_model_select_all - * @selection: #ESelectionModel to select all - * - * This routine selects all the rows in the given - * #ESelectionModel. - */ -void -e_selection_model_select_all (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->select_all != NULL); - - class->select_all (selection); -} - -/** - * e_selection_model_invert_selection - * @selection: #ESelectionModel to invert - * - * This routine inverts all the rows in the given - * #ESelectionModel. - */ -void -e_selection_model_invert_selection (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->invert_selection != NULL); - - class->invert_selection (selection); -} - -gint -e_selection_model_row_count (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), 0); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_val_if_fail (class->row_count != NULL, 0); - - return class->row_count (selection); -} - -void -e_selection_model_change_one_row (ESelectionModel *selection, - gint row, - gboolean grow) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->change_one_row != NULL); - - return class->change_one_row (selection, row, grow); -} - -void -e_selection_model_change_cursor (ESelectionModel *selection, - gint row, - gint col) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->change_cursor != NULL); - - class->change_cursor (selection, row, col); -} - -gint -e_selection_model_cursor_row (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), -1); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_val_if_fail (class->cursor_row != NULL, -1); - - return class->cursor_row (selection); -} - -gint -e_selection_model_cursor_col (ESelectionModel *selection) -{ - ESelectionModelClass *class; - - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), -1); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_val_if_fail (class->cursor_col != NULL, -1); - - return class->cursor_col (selection); -} - -void -e_selection_model_select_single_row (ESelectionModel *selection, - gint row) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->select_single_row != NULL); - - class->select_single_row (selection, row); -} - -void -e_selection_model_toggle_single_row (ESelectionModel *selection, - gint row) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->toggle_single_row != NULL); - - class->toggle_single_row (selection, row); -} - -void -e_selection_model_move_selection_end (ESelectionModel *selection, - gint row) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->move_selection_end != NULL); - - class->move_selection_end (selection, row); -} - -void -e_selection_model_set_selection_end (ESelectionModel *selection, - gint row) -{ - ESelectionModelClass *class; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - class = E_SELECTION_MODEL_GET_CLASS (selection); - g_return_if_fail (class->set_selection_end != NULL); - - class->set_selection_end (selection, row); -} - -/** - * e_selection_model_do_something - * @selection: #ESelectionModel to do something to. - * @row: The row to do something in. - * @col: The col to do something in. - * @state: The state in which to do something. - * - * This routine does whatever is appropriate as if the user clicked - * the mouse in the given row and column. - */ -void -e_selection_model_do_something (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state) -{ - gint shift_p = state & GDK_SHIFT_MASK; - gint ctrl_p = state & GDK_CONTROL_MASK; - gint row_count; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - selection->old_selection = -1; - - if (row == -1 && col != -1) - row = 0; - if (col == -1 && row != -1) - col = 0; - - row_count = e_selection_model_row_count (selection); - if (row_count >= 0 && row < row_count) { - switch (selection->mode) { - case GTK_SELECTION_SINGLE: - e_selection_model_select_single_row (selection, row); - break; - case GTK_SELECTION_BROWSE: - case GTK_SELECTION_MULTIPLE: - if (shift_p) { - e_selection_model_set_selection_end (selection, row); - } else { - if (ctrl_p) { - e_selection_model_toggle_single_row (selection, row); - } else { - e_selection_model_select_single_row (selection, row); - } - } - break; - default: - g_return_if_reached (); - break; - } - e_selection_model_change_cursor (selection, row, col); - g_signal_emit ( - selection, - signals[CURSOR_CHANGED], 0, - row, col); - g_signal_emit ( - selection, - signals[CURSOR_ACTIVATED], 0, - row, col); - } -} - -/** - * e_selection_model_maybe_do_something - * @selection: #ESelectionModel to do something to. - * @row: The row to do something in. - * @col: The col to do something in. - * @state: The state in which to do something. - * - * If this row is selected, this routine just moves the cursor row and - * column. Otherwise, it does the same thing as - * e_selection_model_do_something(). This is for being used on - * right clicks and other events where if the user hit the selection, - * they don't want it to change. - */ -gboolean -e_selection_model_maybe_do_something (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state) -{ - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE); - - selection->old_selection = -1; - - if (e_selection_model_is_row_selected (selection, row)) { - e_selection_model_change_cursor (selection, row, col); - g_signal_emit ( - selection, - signals[CURSOR_CHANGED], 0, - row, col); - return FALSE; - } else { - e_selection_model_do_something (selection, row, col, state); - return TRUE; - } -} - -void -e_selection_model_right_click_down (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - if (selection->mode == GTK_SELECTION_SINGLE) { - selection->old_selection = - e_selection_model_cursor_row (selection); - e_selection_model_select_single_row (selection, row); - } else { - e_selection_model_maybe_do_something ( - selection, row, col, state); - } -} - -void -e_selection_model_right_click_up (ESelectionModel *selection) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - if (selection->mode != GTK_SELECTION_SINGLE) - return; - - if (selection->old_selection == -1) - return; - - e_selection_model_select_single_row ( - selection, selection->old_selection); -} - -void -e_selection_model_select_as_key_press (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state) -{ - gint cursor_activated = TRUE; - - gint shift_p = state & GDK_SHIFT_MASK; - gint ctrl_p = state & GDK_CONTROL_MASK; - - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - selection->old_selection = -1; - - switch (selection->mode) { - case GTK_SELECTION_BROWSE: - case GTK_SELECTION_MULTIPLE: - if (shift_p) { - e_selection_model_set_selection_end (selection, row); - } else if (!ctrl_p) { - e_selection_model_select_single_row (selection, row); - } else - cursor_activated = FALSE; - break; - case GTK_SELECTION_SINGLE: - e_selection_model_select_single_row (selection, row); - break; - default: - g_return_if_reached (); - break; - } - if (row != -1) { - e_selection_model_change_cursor (selection, row, col); - g_signal_emit ( - selection, - signals[CURSOR_CHANGED], 0, - row, col); - if (cursor_activated) - g_signal_emit ( - selection, - signals[CURSOR_ACTIVATED], 0, - row, col); - } -} - -static gint -move_selection (ESelectionModel *selection, - gboolean up, - GdkModifierType state) -{ - gint row = e_selection_model_cursor_row (selection); - gint col = e_selection_model_cursor_col (selection); - gint row_count; - - /* there is no selected row when row is -1 */ - if (row != -1) - row = e_sorter_model_to_sorted (selection->sorter, row); - - if (up) - row--; - else - row++; - if (row < 0) - row = 0; - row_count = e_selection_model_row_count (selection); - if (row >= row_count) - row = row_count - 1; - row = e_sorter_sorted_to_model (selection->sorter, row); - - e_selection_model_select_as_key_press (selection, row, col, state); - return TRUE; -} - -/** - * e_selection_model_key_press - * @selection: #ESelectionModel to affect. - * @key: The event. - * - * This routine does whatever is appropriate as if the user pressed - * the given key. - * - * Returns: %TRUE if the #ESelectionModel used the key. - */ -gboolean -e_selection_model_key_press (ESelectionModel *selection, - GdkEventKey *key) -{ - g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE); - g_return_val_if_fail (key != NULL, FALSE); - - selection->old_selection = -1; - - switch (key->keyval) { - case GDK_KEY_Up: - case GDK_KEY_KP_Up: - return move_selection (selection, TRUE, key->state); - case GDK_KEY_Down: - case GDK_KEY_KP_Down: - return move_selection (selection, FALSE, key->state); - case GDK_KEY_space: - case GDK_KEY_KP_Space: - if (selection->mode != GTK_SELECTION_SINGLE) { - gint row = e_selection_model_cursor_row (selection); - gint col = e_selection_model_cursor_col (selection); - if (row == -1) - break; - - e_selection_model_toggle_single_row (selection, row); - g_signal_emit ( - selection, - signals[CURSOR_ACTIVATED], 0, - row, col); - return TRUE; - } - break; - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - if (selection->mode != GTK_SELECTION_SINGLE) { - gint row = e_selection_model_cursor_row (selection); - gint col = e_selection_model_cursor_col (selection); - e_selection_model_select_single_row (selection, row); - g_signal_emit ( - selection, - signals[CURSOR_ACTIVATED], 0, - row, col); - return TRUE; - } - break; - case GDK_KEY_Home: - case GDK_KEY_KP_Home: - if (selection->cursor_mode == E_CURSOR_LINE) { - gint row = 0; - gint cursor_col = e_selection_model_cursor_col (selection); - - row = e_sorter_sorted_to_model (selection->sorter, row); - e_selection_model_select_as_key_press ( - selection, row, cursor_col, key->state); - return TRUE; - } - break; - case GDK_KEY_End: - case GDK_KEY_KP_End: - if (selection->cursor_mode == E_CURSOR_LINE) { - gint row = e_selection_model_row_count (selection) - 1; - gint cursor_col = e_selection_model_cursor_col (selection); - - row = e_sorter_sorted_to_model (selection->sorter, row); - e_selection_model_select_as_key_press ( - selection, row, cursor_col, key->state); - return TRUE; - } - break; - } - return FALSE; -} - -void -e_selection_model_cursor_changed (ESelectionModel *selection, - gint row, - gint col) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - g_signal_emit (selection, signals[CURSOR_CHANGED], 0, row, col); -} - -void -e_selection_model_cursor_activated (ESelectionModel *selection, - gint row, - gint col) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - g_signal_emit (selection, signals[CURSOR_ACTIVATED], 0, row, col); -} - -void -e_selection_model_selection_changed (ESelectionModel *selection) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - g_signal_emit (selection, signals[SELECTION_CHANGED], 0); -} - -void -e_selection_model_selection_row_changed (ESelectionModel *selection, - gint row) -{ - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - g_signal_emit (selection, signals[SELECTION_ROW_CHANGED], 0, row); -} diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h deleted file mode 100644 index 355734b6a5..0000000000 --- a/widgets/misc/e-selection-model.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_SELECTION_MODEL_H -#define E_SELECTION_MODEL_H - -#include <gtk/gtk.h> -#include <e-util/e-sorter.h> - -/* Standard GObject macros */ -#define E_TYPE_SELECTION_MODEL \ - (e_selection_model_get_type ()) -#define E_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SELECTION_MODEL, ESelectionModel)) -#define E_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SELECTION_MODEL, ESelectionModelClass)) -#define E_IS_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SELECTION_MODEL)) -#define E_IS_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SELECTION_MODEL)) -#define E_SELECTION_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SELECTION_MODEL, ESelectionModelClass)) - -G_BEGIN_DECLS - -#ifndef _E_FOREACH_FUNC_H_ -#define _E_FOREACH_FUNC_H_ -typedef void (*EForeachFunc) (gint model_row, - gpointer closure); -#endif - -typedef struct _ESelectionModel ESelectionModel; -typedef struct _ESelectionModelClass ESelectionModelClass; - -/* list selection modes */ -typedef enum { - E_CURSOR_LINE, - E_CURSOR_SIMPLE, - E_CURSOR_SPREADSHEET -} ECursorMode; - -struct _ESelectionModel { - GObject parent; - - ESorter *sorter; - - GtkSelectionMode mode; - ECursorMode cursor_mode; - - gint old_selection; -}; - -struct _ESelectionModelClass { - GObjectClass parent_class; - - /* Virtual methods */ - gboolean (*is_row_selected) (ESelectionModel *esm, - gint row); - void (*foreach) (ESelectionModel *esm, - EForeachFunc callback, - gpointer closure); - void (*clear) (ESelectionModel *esm); - gint (*selected_count) (ESelectionModel *esm); - void (*select_all) (ESelectionModel *esm); - void (*invert_selection) (ESelectionModel *esm); - gint (*row_count) (ESelectionModel *esm); - - /* Protected virtual methods. */ - void (*change_one_row) (ESelectionModel *esm, - gint row, - gboolean on); - void (*change_cursor) (ESelectionModel *esm, - gint row, - gint col); - gint (*cursor_row) (ESelectionModel *esm); - gint (*cursor_col) (ESelectionModel *esm); - - void (*select_single_row) (ESelectionModel *selection, - gint row); - void (*toggle_single_row) (ESelectionModel *selection, - gint row); - void (*move_selection_end) (ESelectionModel *selection, - gint row); - void (*set_selection_end) (ESelectionModel *selection, - gint row); - - /* Signals */ - void (*cursor_changed) (ESelectionModel *esm, - gint row, - gint col); - void (*cursor_activated) (ESelectionModel *esm, - gint row, - gint col); - void (*selection_row_changed)(ESelectionModel *esm, - gint row); - void (*selection_changed) (ESelectionModel *esm); -}; - -GType e_selection_model_get_type (void); -void e_selection_model_do_something (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); -gboolean e_selection_model_maybe_do_something - (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); -void e_selection_model_right_click_down - (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state); -void e_selection_model_right_click_up - (ESelectionModel *selection); -gboolean e_selection_model_key_press (ESelectionModel *esm, - GdkEventKey *key); -void e_selection_model_select_as_key_press - (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); - -/* Virtual functions */ -gboolean e_selection_model_is_row_selected - (ESelectionModel *esm, - gint n); -void e_selection_model_foreach (ESelectionModel *esm, - EForeachFunc callback, - gpointer closure); -void e_selection_model_clear (ESelectionModel *esm); -gint e_selection_model_selected_count - (ESelectionModel *esm); -void e_selection_model_select_all (ESelectionModel *esm); -void e_selection_model_invert_selection - (ESelectionModel *esm); -gint e_selection_model_row_count (ESelectionModel *esm); - -/* Private virtual Functions */ -void e_selection_model_change_one_row - (ESelectionModel *esm, - gint row, - gboolean on); -void e_selection_model_change_cursor (ESelectionModel *esm, - gint row, - gint col); -gint e_selection_model_cursor_row (ESelectionModel *esm); -gint e_selection_model_cursor_col (ESelectionModel *esm); -void e_selection_model_select_single_row - (ESelectionModel *selection, - gint row); -void e_selection_model_toggle_single_row - (ESelectionModel *selection, - gint row); -void e_selection_model_move_selection_end - (ESelectionModel *selection, - gint row); -void e_selection_model_set_selection_end - (ESelectionModel *selection, - gint row); - -/* Signals */ -void e_selection_model_cursor_changed - (ESelectionModel *selection, - gint row, - gint col); -void e_selection_model_cursor_activated - (ESelectionModel *selection, - gint row, - gint col); -void e_selection_model_selection_row_changed - (ESelectionModel *selection, - gint row); -void e_selection_model_selection_changed - (ESelectionModel *selection); - -G_END_DECLS - -#endif /* E_SELECTION_MODEL_H */ - diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c deleted file mode 100644 index d84b8659e4..0000000000 --- a/widgets/misc/e-send-options.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Evolution calendar - Main page of the Groupwise send options Dialog - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chenthill Palanisamy <pchenthill@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <glib/gi18n.h> -#include <time.h> - -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" - -#include "e-dateedit.h" -#include "e-send-options.h" - -#define E_SEND_OPTIONS_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SEND_OPTIONS_DIALOG, ESendOptionsDialogPrivate)) - -struct _ESendOptionsDialogPrivate { - GtkBuilder *builder; - - gboolean gopts_needed; - gboolean global; - - /* Widgets */ - - GtkWidget *main; - - /* Noteboook to add options page and status tracking page*/ - GtkNotebook *notebook; - - GtkWidget *status; - - /* priority */ - GtkWidget *priority; - - /* Security */ - GtkWidget *security; - - /* Widgets for Reply Requestion options */ - GtkWidget *reply_request; - GtkWidget *reply_convenient; - GtkWidget *reply_within; - GtkWidget *within_days; - - /* Widgets for delay delivery Option */ - GtkWidget *delay_delivery; - GtkWidget *delay_until; - - /* Widgets for Choosing expiration date */ - GtkWidget *expiration; - GtkWidget *expire_after; - - /* Widgets to for tracking information through sent Item */ - GtkWidget *create_sent; - GtkWidget *delivered; - GtkWidget *delivered_opened; - GtkWidget *all_info; - GtkWidget *autodelete; - - /* Widgets for setting the Return Notification */ - GtkWidget *when_opened; - GtkWidget *when_declined; - GtkWidget *when_accepted; - GtkWidget *when_completed; - - /* label widgets */ - GtkWidget *security_label; - GtkWidget *priority_label; - GtkWidget *gopts_label; - GtkWidget *opened_label; - GtkWidget *declined_label; - GtkWidget *accepted_label; - GtkWidget *completed_label; - GtkWidget *until_label; - gchar *help_section; -}; - -static void e_send_options_dialog_finalize (GObject *object); -static void e_send_options_cb (GtkDialog *dialog, gint state, gpointer func_data); - -enum { - SOD_RESPONSE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE ( - ESendOptionsDialog, - e_send_options_dialog, - G_TYPE_OBJECT) - -static void -e_send_options_get_widgets_data (ESendOptionsDialog *sod) -{ - ESendOptionsDialogPrivate *priv; - ESendOptionsGeneral *gopts; - ESendOptionsStatusTracking *sopts; - - priv = sod->priv; - gopts = sod->data->gopts; - sopts = sod->data->sopts; - - gopts->priority = gtk_combo_box_get_active ((GtkComboBox *) priv->priority); - gopts->security = gtk_combo_box_get_active ((GtkComboBox *) priv->security); - - gopts->reply_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->reply_request)); - gopts->reply_convenient = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->reply_convenient)); - gopts->reply_within = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->within_days)); - - gopts->expiration_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->expiration)); - gopts->expire_after = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->expire_after)); - gopts->delay_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->delay_delivery)); - - if (e_date_edit_date_is_valid (E_DATE_EDIT (priv->delay_until)) && - e_date_edit_time_is_valid (E_DATE_EDIT (priv->delay_until))) - gopts->delay_until = e_date_edit_get_time (E_DATE_EDIT (priv->delay_until)); - - sopts->tracking_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->create_sent)); - - sopts->autodelete = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->autodelete)); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->delivered))) - sopts->track_when = E_DELIVERED; - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->delivered_opened))) - sopts->track_when = E_DELIVERED_OPENED; - else - sopts->track_when = E_ALL; - - sopts->opened = gtk_combo_box_get_active ((GtkComboBox *) priv->when_opened); - sopts->accepted = gtk_combo_box_get_active ((GtkComboBox *) priv->when_accepted); - sopts->declined = gtk_combo_box_get_active ((GtkComboBox *) priv->when_declined); - sopts->completed = gtk_combo_box_get_active ((GtkComboBox *) priv->when_completed); -} - -static void -e_send_options_fill_widgets_with_data (ESendOptionsDialog *sod) -{ - ESendOptionsDialogPrivate *priv; - ESendOptionsGeneral *gopts; - ESendOptionsStatusTracking *sopts; - time_t tmp; - - priv = sod->priv; - gopts = sod->data->gopts; - sopts = sod->data->sopts; - tmp = time (NULL); - - gtk_combo_box_set_active ((GtkComboBox *) priv->priority, gopts->priority); - gtk_combo_box_set_active ((GtkComboBox *) priv->security, gopts->security); - - if (gopts->reply_enabled) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->reply_request), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->reply_request), FALSE); - - if (gopts->reply_convenient) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->reply_convenient), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->reply_within), TRUE); - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->within_days), (gdouble) gopts->reply_within); - - if (gopts->expiration_enabled) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->expiration), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->expiration), FALSE); - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->expire_after), (gdouble) gopts->expire_after); - - if (gopts->delay_enabled) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delay_delivery), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delay_delivery), FALSE); - - if (!gopts->delay_until || difftime (gopts->delay_until, tmp) < 0) - e_date_edit_set_time (E_DATE_EDIT (priv->delay_until), 0); - else - e_date_edit_set_time (E_DATE_EDIT (priv->delay_until), gopts->delay_until); - - if (sopts->tracking_enabled) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->create_sent), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->create_sent), FALSE); - - if (sopts->autodelete) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->autodelete), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->autodelete), FALSE); - - switch (sopts->track_when) { - case E_DELIVERED: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delivered), TRUE); - break; - case E_DELIVERED_OPENED: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delivered_opened), TRUE); - break; - case E_ALL: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->all_info), TRUE); - } - - gtk_combo_box_set_active ((GtkComboBox *) priv->when_opened, sopts->opened); - gtk_combo_box_set_active ((GtkComboBox *) priv->when_declined, sopts->declined); - gtk_combo_box_set_active ((GtkComboBox *) priv->when_accepted, sopts->accepted); - gtk_combo_box_set_active ((GtkComboBox *) priv->when_completed, sopts->completed); -} - -static void -sensitize_widgets (ESendOptionsDialog *sod) -{ - ESendOptionsDialogPrivate *priv; - ESendOptionsGeneral *gopts; - ESendOptionsStatusTracking *sopts; - - priv = sod->priv; - gopts = sod->data->gopts; - sopts = sod->data->sopts; - - if (!gopts->reply_enabled) { - gtk_widget_set_sensitive (priv->reply_convenient, FALSE); - gtk_widget_set_sensitive (priv->reply_within, FALSE); - gtk_widget_set_sensitive (priv->within_days, FALSE); - } - - if (!gopts->expiration_enabled) - gtk_widget_set_sensitive (priv->expire_after, FALSE); - - if (!gopts->delay_enabled) { - gtk_widget_set_sensitive (priv->delay_until, FALSE); - } - - if (!sopts->tracking_enabled) { - gtk_widget_set_sensitive (priv->delivered, FALSE); - gtk_widget_set_sensitive (priv->delivered_opened, FALSE); - gtk_widget_set_sensitive (priv->all_info, FALSE); - gtk_widget_set_sensitive (priv->autodelete, FALSE); - } -} - -static void -expiration_toggled_cb (GtkToggleButton *toggle, - gpointer data) -{ - gboolean active; - ESendOptionsDialog *sod; - ESendOptionsDialogPrivate *priv; - - sod = data; - priv = sod->priv; - - active = gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (priv->expire_after, active); -} - -static void -reply_request_toggled_cb (GtkToggleButton *toggle, - gpointer data) -{ - gboolean active; - ESendOptionsDialog *sod; - ESendOptionsDialogPrivate *priv; - - sod = data; - priv = sod->priv; - active = gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (priv->reply_convenient, active); - gtk_widget_set_sensitive (priv->reply_within, active); - gtk_widget_set_sensitive (priv->within_days, active); - -} - -static void -delay_delivery_toggled_cb (GtkToggleButton *toggle, - gpointer data) -{ - gboolean active; - ESendOptionsDialog *sod; - ESendOptionsDialogPrivate *priv; - - sod = data; - priv = sod->priv; - active = gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (priv->delay_until, active); -} - -static void -sent_item_toggled_cb (GtkToggleButton *toggle, - gpointer data) -{ - gboolean active; - ESendOptionsDialog *sod; - ESendOptionsDialogPrivate *priv; - - sod = data; - priv = sod->priv; - active = gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (priv->delivered, active); - gtk_widget_set_sensitive (priv->delivered_opened, active); - gtk_widget_set_sensitive (priv->all_info, active); - gtk_widget_set_sensitive (priv->autodelete, active); -} - -static void -delay_until_date_changed_cb (GtkWidget *dedit, - gpointer data) -{ - ESendOptionsDialog *sod; - ESendOptionsDialogPrivate *priv; - time_t tmp, current; - - sod = data; - priv = sod->priv; - - current = time (NULL); - tmp = e_date_edit_get_time (E_DATE_EDIT (priv->delay_until)); - - if ((difftime (tmp, current) < 0) || !e_date_edit_time_is_valid (E_DATE_EDIT (priv->delay_until)) - || !e_date_edit_date_is_valid (E_DATE_EDIT (priv->delay_until))) - e_date_edit_set_time (E_DATE_EDIT (priv->delay_until), 0); - -} -static void -page_changed_cb (GtkNotebook *notebook, - GtkWidget *page, - gint num, - gpointer data) -{ - ESendOptionsDialog *sod = data; - ESendOptionsDialogPrivate *priv = sod->priv; - - e_send_options_get_widgets_data (sod); - if (num > 0) { - GtkWidget *child; - - if (num == 1) { - gtk_widget_hide (priv->accepted_label); - gtk_widget_hide (priv->when_accepted); - gtk_widget_hide (priv->completed_label); - gtk_widget_hide (priv->when_completed); - gtk_widget_set_sensitive (priv->autodelete, TRUE); - sod->data->sopts = sod->data->mopts; - - child = gtk_notebook_get_nth_page (notebook, 1); - if (child != priv->status && (!GTK_IS_BIN (child) || gtk_bin_get_child (GTK_BIN (child)) != priv->status)) - gtk_widget_reparent (priv->status, child); - } else if (num == 2) { - gtk_widget_hide (priv->completed_label); - gtk_widget_hide (priv->when_completed); - gtk_widget_set_sensitive (priv->autodelete, FALSE); - - gtk_widget_show (priv->accepted_label); - gtk_widget_show (priv->when_accepted); - sod->data->sopts = sod->data->copts; - - child = gtk_notebook_get_nth_page (notebook, 2); - if (gtk_bin_get_child (GTK_BIN (child)) != priv->status) - gtk_widget_reparent (priv->status, child); - } else { - gtk_widget_set_sensitive (priv->autodelete, FALSE); - - gtk_widget_show (priv->completed_label); - gtk_widget_show (priv->when_completed); - gtk_widget_show (priv->accepted_label); - gtk_widget_show (priv->when_accepted); - sod->data->sopts = sod->data->topts; - - child = gtk_notebook_get_nth_page (notebook, 3); - if (gtk_bin_get_child (GTK_BIN (child)) != priv->status) - gtk_widget_reparent (priv->status, child); - } - } - e_send_options_fill_widgets_with_data (sod); -} - -static void -init_widgets (ESendOptionsDialog *sod) -{ - ESendOptionsDialogPrivate *priv; - - priv = sod->priv; - - g_signal_connect ( - priv->expiration, "toggled", - G_CALLBACK (expiration_toggled_cb), sod); - g_signal_connect ( - priv->reply_request, "toggled", - G_CALLBACK (reply_request_toggled_cb), sod); - g_signal_connect ( - priv->delay_delivery, "toggled", - G_CALLBACK (delay_delivery_toggled_cb), sod); - g_signal_connect ( - priv->create_sent, "toggled", - G_CALLBACK (sent_item_toggled_cb), sod); - - g_signal_connect ( - priv->main, "response", - G_CALLBACK (e_send_options_cb), sod); - g_signal_connect ( - priv->delay_until, "changed", - G_CALLBACK (delay_until_date_changed_cb), sod); - - if (priv->global) - g_signal_connect ( - priv->notebook, "switch-page", - G_CALLBACK (page_changed_cb), sod); - -} - -static gboolean -get_widgets (ESendOptionsDialog *sod) -{ - ESendOptionsDialogPrivate *priv; - GtkBuilder *builder; - - priv = sod->priv; - builder = sod->priv->builder; - - priv->main = e_builder_get_widget (builder, "send-options-dialog"); - if (!priv->main) - return FALSE; - - priv->priority = e_builder_get_widget (builder, "combo-priority"); - priv->status = e_builder_get_widget (builder, "status-tracking"); - priv->security = e_builder_get_widget (builder, "security-combo"); - priv->notebook = (GtkNotebook *) e_builder_get_widget (builder, "notebook"); - priv->reply_request = e_builder_get_widget (builder, "reply-request-button"); - priv->reply_convenient = e_builder_get_widget (builder, "reply-convinient"); - priv->reply_within = e_builder_get_widget (builder, "reply-within"); - priv->within_days = e_builder_get_widget (builder, "within-days"); - priv->delay_delivery = e_builder_get_widget (builder, "delay-delivery-button"); - priv->delay_until = e_builder_get_widget (builder, "until-date"); - gtk_widget_show (priv->delay_until); - priv->expiration = e_builder_get_widget (builder, "expiration-button"); - priv->expire_after = e_builder_get_widget (builder, "expire-after"); - priv->create_sent = e_builder_get_widget (builder, "create-sent-button"); - priv->delivered = e_builder_get_widget (builder, "delivered"); - priv->delivered_opened = e_builder_get_widget (builder, "delivered-opened"); - priv->all_info = e_builder_get_widget (builder, "all-info"); - priv->autodelete = e_builder_get_widget (builder, "autodelete"); - priv->when_opened = e_builder_get_widget (builder, "open-combo"); - priv->when_declined = e_builder_get_widget (builder, "delete-combo"); - priv->when_accepted = e_builder_get_widget (builder, "accept-combo"); - priv->when_completed = e_builder_get_widget (builder, "complete-combo"); - priv->security_label = e_builder_get_widget (builder, "security-label"); - priv->gopts_label = e_builder_get_widget (builder, "gopts-label"); - priv->priority_label = e_builder_get_widget (builder, "priority-label"); - priv->until_label = e_builder_get_widget (builder, "until-label"); - priv->opened_label = e_builder_get_widget (builder, "opened-label"); - priv->declined_label = e_builder_get_widget (builder, "declined-label"); - priv->accepted_label = e_builder_get_widget (builder, "accepted-label"); - priv->completed_label = e_builder_get_widget (builder, "completed-label"); - - return (priv->priority - && priv->security - && priv->status - && priv->reply_request - && priv->reply_convenient - && priv->reply_within - && priv->within_days - && priv->delay_delivery - && priv->delay_until - && priv->expiration - && priv->expire_after - && priv->create_sent - && priv->delivered - && priv->delivered_opened - && priv->autodelete - && priv->all_info - && priv->when_opened - && priv->when_declined - && priv->when_accepted - && priv->when_completed - && priv->security_label - && priv->priority_label - && priv->opened_label - && priv->gopts_label - && priv->declined_label - && priv->accepted_label - && priv->completed_label); - -} - -static void -setup_widgets (ESendOptionsDialog *sod, - Item_type type) -{ - ESendOptionsDialogPrivate *priv; - - priv = sod->priv; - - if (!priv->gopts_needed) { - gtk_notebook_set_show_tabs (priv->notebook, FALSE); - gtk_notebook_set_current_page (priv->notebook, 1); - gtk_widget_hide (priv->delay_until); - } else - gtk_notebook_set_show_tabs (priv->notebook, TRUE); - - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->priority_label), priv->priority); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->security_label), priv->security); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->accepted_label), priv->when_accepted); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->declined_label), priv->when_declined); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opened_label), priv->when_opened); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->completed_label), priv->when_completed); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->until_label), priv->delay_until); - - if (priv->global) { - GtkWidget *widget, *page; - - widget = gtk_label_new (_("Mail")); - page = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); - gtk_widget_reparent (priv->status, page); - gtk_notebook_append_page (priv->notebook, page, widget); - gtk_container_child_set (GTK_CONTAINER (priv->notebook), page, "tab-fill", FALSE, "tab-expand", FALSE, NULL); - gtk_widget_show (page); - gtk_widget_show (widget); - - widget = gtk_label_new (_("Calendar")); - page = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); - gtk_notebook_append_page (priv->notebook, page, widget); - gtk_container_child_set (GTK_CONTAINER (priv->notebook), page, "tab-fill", FALSE, "tab-expand", FALSE, NULL); - gtk_widget_show (page); - gtk_widget_show (widget); - - widget = gtk_label_new (_("Task")); - page = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); - gtk_notebook_append_page (priv->notebook, page, widget); - gtk_container_child_set (GTK_CONTAINER (priv->notebook), page, "tab-fill", FALSE, "tab-expand", FALSE, NULL); - gtk_widget_show (page); - gtk_widget_show (widget); - - gtk_notebook_set_show_tabs (priv->notebook, TRUE); - } - - switch (type) { - case E_ITEM_MAIL: - priv->help_section = g_strdup ("groupwise-placeholder"); - gtk_widget_hide (priv->accepted_label); - gtk_widget_hide (priv->when_accepted); - gtk_widget_hide (priv->completed_label); - gtk_widget_hide (priv->when_completed); - gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->declined_label), (_("When de_leted:"))); - break; - case E_ITEM_CALENDAR: - priv->help_section = g_strdup ("groupwise-placeholder"); - gtk_widget_hide (priv->completed_label); - gtk_widget_hide (priv->when_completed); - case E_ITEM_TASK: - priv->help_section = g_strdup ("groupwise-placeholder"); - gtk_widget_hide (priv->security_label); - gtk_widget_hide (priv->security); - gtk_widget_set_sensitive (priv->autodelete, FALSE); - break; - default: - break; - } -} - -ESendOptionsDialog * -e_send_options_dialog_new (void) -{ - ESendOptionsDialog *sod; - - sod = g_object_new (E_TYPE_SEND_OPTIONS_DIALOG, NULL); - - return sod; -} - -void -e_send_options_set_need_general_options (ESendOptionsDialog *sod, - gboolean needed) -{ - g_return_if_fail (E_IS_SEND_OPTIONS_DIALOG (sod)); - - sod->priv->gopts_needed = needed; -} - -gboolean -e_send_options_get_need_general_options (ESendOptionsDialog *sod) -{ - g_return_val_if_fail (E_IS_SEND_OPTIONS_DIALOG (sod), FALSE); - - return sod->priv->gopts_needed; -} - -gboolean -e_send_options_set_global (ESendOptionsDialog *sod, - gboolean set) -{ - g_return_val_if_fail (E_IS_SEND_OPTIONS_DIALOG (sod), FALSE); - - sod->priv->global = set; - - return TRUE; -} - -static void -e_send_options_cb (GtkDialog *dialog, - gint state, - gpointer func_data) -{ - ESendOptionsDialogPrivate *priv; - ESendOptionsDialog *sod; - - sod = func_data; - priv = sod->priv; - - switch (state) { - case GTK_RESPONSE_OK: - e_send_options_get_widgets_data (sod); - case GTK_RESPONSE_CANCEL: - gtk_widget_hide (priv->main); - gtk_widget_destroy (priv->main); - g_object_unref (priv->builder); - break; - case GTK_RESPONSE_HELP: - e_display_help ( - GTK_WINDOW (priv->main), - priv->help_section); - break; - } - - g_signal_emit (func_data, signals[SOD_RESPONSE], 0, state); -} - -gboolean -e_send_options_dialog_run (ESendOptionsDialog *sod, - GtkWidget *parent, - Item_type type) -{ - ESendOptionsDialogPrivate *priv; - GtkWidget *toplevel; - - g_return_val_if_fail (sod != NULL || E_IS_SEND_OPTIONS_DIALOG (sod), FALSE); - - priv = sod->priv; - - /* Make sure our custom widget classes are registered with - * GType before we load the GtkBuilder definition file. */ - E_TYPE_DATE_EDIT; - - priv->builder = gtk_builder_new (); - e_load_ui_builder_definition (priv->builder, "e-send-options.ui"); - - if (!get_widgets (sod)) { - g_object_unref (priv->builder); - g_message (G_STRLOC ": Could not get the Widgets \n"); - return FALSE; - } - - if (priv->global) { - g_free (sod->data->sopts); - sod->data->sopts = sod->data->mopts; - } - - setup_widgets (sod, type); - - toplevel = gtk_widget_get_toplevel (priv->main); - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (toplevel), - GTK_WINDOW (parent)); - - e_send_options_fill_widgets_with_data (sod); - sensitize_widgets (sod); - init_widgets (sod); - gtk_window_set_modal ((GtkWindow *) priv->main, TRUE); - - gtk_widget_show (priv->main); - - return TRUE; -} - -static void -e_send_options_dialog_finalize (GObject *object) -{ - ESendOptionsDialog *sod; - - sod = E_SEND_OPTIONS_DIALOG (object); - - g_free (sod->priv->help_section); - - g_free (sod->data->gopts); - - if (!sod->priv->global) - g_free (sod->data->sopts); - - g_free (sod->data->mopts); - g_free (sod->data->copts); - g_free (sod->data->topts); - g_free (sod->data); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_send_options_dialog_parent_class)->finalize (object); -} - -/* Object initialization function for the task page */ -static void -e_send_options_dialog_init (ESendOptionsDialog *sod) -{ - ESendOptionsData *new; - - new = g_new0 (ESendOptionsData, 1); - new->gopts = g_new0 (ESendOptionsGeneral, 1); - new->sopts = g_new0 (ESendOptionsStatusTracking, 1); - new->mopts = g_new0 (ESendOptionsStatusTracking, 1); - new->copts = g_new0 (ESendOptionsStatusTracking, 1); - new->topts = g_new0 (ESendOptionsStatusTracking, 1); - - sod->priv = E_SEND_OPTIONS_DIALOG_GET_PRIVATE (sod); - - sod->data = new; - sod->data->initialized = FALSE; - sod->data->gopts->security = 0; - - sod->priv->gopts_needed = TRUE; -} - -/* Class initialization function for the Send Options */ -static void -e_send_options_dialog_class_init (ESendOptionsDialogClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ESendOptionsDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = e_send_options_dialog_finalize; - - signals[SOD_RESPONSE] = g_signal_new ( - "sod_response", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ESendOptionsDialogClass, sod_response), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - -} diff --git a/widgets/misc/e-send-options.h b/widgets/misc/e-send-options.h deleted file mode 100644 index 2e8ef1d381..0000000000 --- a/widgets/misc/e-send-options.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_SEND_OPTIONS_DIALOG_H__ -#define __E_SEND_OPTIONS_DIALOG_H__ - -#include <gtk/gtk.h> -#include <time.h> - -#define E_TYPE_SEND_OPTIONS_DIALOG (e_send_options_dialog_get_type ()) -#define E_SEND_OPTIONS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SEND_OPTIONS_DIALOG, ESendOptionsDialog)) -#define E_SEND_OPTIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SEND_OPTIONS_DIALOG, ESendOptionsDialogClass)) -#define E_IS_SEND_OPTIONS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SEND_OPTIONS_DIALOG)) -#define E_IS_SEND_OPTIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_SEND_OPTIONS_DIALOG)) - -typedef struct _ESendOptionsDialog ESendOptionsDialog; -typedef struct _ESendOptionsDialogClass ESendOptionsDialogClass; -typedef struct _ESendOptionsDialogPrivate ESendOptionsDialogPrivate; - -typedef enum { - E_ITEM_NONE, - E_ITEM_MAIL, - E_ITEM_CALENDAR, - E_ITEM_TASK -} Item_type; - -typedef enum { - E_PRIORITY_UNDEFINED, - E_PRIORITY_HIGH, - E_PRIORITY_STANDARD, - E_PRIORITY_LOW -} ESendOptionsPriority; - -typedef enum { - E_SECURITY_NORMAL, - E_SECURITY_PROPRIETARY, - E_SECURITY_CONFIDENTIAL, - E_SECURITY_SECRET, - E_SECURITY_TOP_SECRET, - E_SECURITY_FOR_YOUR_EYES_ONLY -} ESendOptionsSecurity; - -typedef enum { - E_RETURN_NOTIFY_NONE, - E_RETURN_NOTIFY_MAIL -} ESendOptionsReturnNotify; - -typedef enum { - E_DELIVERED = 1, - E_DELIVERED_OPENED = 2, - E_ALL = 3 -} TrackInfo; - -typedef struct { - ESendOptionsPriority priority; - gint classify; - gboolean reply_enabled; - gboolean reply_convenient; - gint reply_within; - gboolean expiration_enabled; - gint expire_after; - gboolean delay_enabled; - time_t delay_until; - gint security; -} ESendOptionsGeneral; - -typedef struct { - gboolean tracking_enabled; - TrackInfo track_when; - gboolean autodelete; - ESendOptionsReturnNotify opened; - ESendOptionsReturnNotify accepted; - ESendOptionsReturnNotify declined; - ESendOptionsReturnNotify completed; -} ESendOptionsStatusTracking; - -typedef struct { - gboolean initialized; - - ESendOptionsGeneral *gopts; - ESendOptionsStatusTracking *sopts; - ESendOptionsStatusTracking *mopts; - ESendOptionsStatusTracking *copts; - ESendOptionsStatusTracking *topts; - -} ESendOptionsData; - -struct _ESendOptionsDialog { - GObject object; - - ESendOptionsData *data; - /* Private data */ - ESendOptionsDialogPrivate *priv; -}; - -struct _ESendOptionsDialogClass { - GObjectClass parent_class; - void (* sod_response) (ESendOptionsDialog *sd, gint status); -}; - -GType e_send_options_dialog_get_type (void); -ESendOptionsDialog *e_send_options_dialog_new (void); -void e_send_options_set_need_general_options (ESendOptionsDialog *sod, gboolean needed); -gboolean e_send_options_get_need_general_options (ESendOptionsDialog *sod); -gboolean e_send_options_dialog_run (ESendOptionsDialog *sod, GtkWidget *parent, Item_type type); -gboolean e_send_options_set_global (ESendOptionsDialog *sod, gboolean set); -#endif diff --git a/widgets/misc/e-send-options.ui b/widgets/misc/e-send-options.ui deleted file mode 100644 index 681e6e0693..0000000000 --- a/widgets/misc/e-send-options.ui +++ /dev/null @@ -1,949 +0,0 @@ -<?xml version="1.0"?> -<interface> - <object class="GtkAdjustment" id="adjustment1"> - <property name="upper">100</property> - <property name="lower">0</property> - <property name="page_increment">10</property> - <property name="step_increment">1</property> - <property name="page_size">0</property> - <property name="value">5</property> - </object> - <object class="GtkAdjustment" id="adjustment2"> - <property name="upper">100</property> - <property name="lower">0</property> - <property name="page_increment">10</property> - <property name="step_increment">1</property> - <property name="page_size">0</property> - <property name="value">2</property> - </object> - <object class="GtkListStore" id="model1"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Undefined</col> - </row> - <row> - <col id="0" translatable="yes">High</col> - </row> - <row> - <col id="0" translatable="yes">Standard</col> - </row> - <row> - <col id="0" translatable="yes">Low</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model2"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Normal</col> - </row> - <row> - <col id="0" translatable="yes">Proprietary</col> - </row> - <row> - <col id="0" translatable="yes">Confidential</col> - </row> - <row> - <col id="0" translatable="yes">Secret</col> - </row> - <row> - <col id="0" translatable="yes">Top Secret</col> - </row> - <row> - <col id="0" translatable="yes">For Your Eyes Only</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model3"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="send-options" comments="Translators: Used in send options dialog">None</col> - </row> - <row> - <col id="0" translatable="yes">Mail Receipt</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model4"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="send-options">None</col> - </row> - <row> - <col id="0" translatable="yes">Mail Receipt</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model5"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="send-options">None</col> - </row> - <row> - <col id="0" translatable="yes">Mail Receipt</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model6"> - <columns> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="send-options">None</col> - </row> - <row> - <col id="0" translatable="yes">Mail Receipt</col> - </row> - </data> - </object> - <!-- interface-requires gtk+ 2.16 --> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkDialog" id="send-options-dialog"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="title" translatable="yes">Send Options</property> - <property name="resizable">False</property> - <property name="modal">True</property> - <property name="window_position">mouse</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="vbox"> - <property name="visible">True</property> - <property name="can_default">True</property> - <child> - <object class="GtkNotebook" id="notebook"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <child> - <object class="GtkTable" id="general-options"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="n_rows">4</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">12</property> - <child> - <object class="GtkLabel" id="label92"> - <property name="visible">True</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame16"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkTable" id="table32"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="column_spacing">12</property> - <property name="row_spacing">12</property> - <child> - <object class="GtkCheckButton" id="reply-request-button"> - <property name="label" translatable="yes">R_eply requested</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment38"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="left_padding">12</property> - <child> - <object class="GtkTable" id="table33"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="column_spacing">12</property> - <property name="row_spacing">12</property> - <child> - <object class="GtkRadioButton" id="reply-within"> - <property name="label" translatable="yes" comments="Translators: This is part of 'Within [ X ] days', where [ X ] is a spinner with a number" context="ESendOptionsWithin">Wi_thin</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkSpinButton" id="within-days"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">adjustment1</property> - <property name="climb_rate">1</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="label93"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes" comments="Translators: This is part of 'Within [ X ] days', where [ X ] is a spinner with a number" context="ESendOptionsWithin">days</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="reply-convinient"> - <property name="label" translatable="yes">_When convenient</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">reply-within</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options"/> - <property name="y_options"/> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label94"> - <property name="visible">True</property> - <property name="label" translatable="yes">Replies</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - </child> - </object> - <packing> - <property name="right_attach">4</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame17"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkTable" id="table34"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="n_rows">4</property> - <property name="n_columns">2</property> - <child> - <object class="GtkCheckButton" id="delay-delivery-button"> - <property comments="To translators: This means Delay the message delivery for some time" name="label" translatable="yes">_Delay message delivery</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="label95"> - <property name="visible">True</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment39"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkHBox" id="hbox11"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label96"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes" comments="Translators: This is part of 'After [ X ] days', where [ X ] is a spinner with a number" context="ESendOptionsAfter">_After</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">expire-after</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkSpinButton" id="expire-after"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">adjustment2</property> - <property name="climb_rate">1</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label97"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes" comments="Translators: This is part of 'After [ X ] days', where [ X ] is a spinner with a number" context="ESendOptionsAfter">days</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options">GTK_EXPAND</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="expiration-button"> - <property name="label" translatable="yes">_Set expiration date</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="label98"> - <property name="visible">True</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment40"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkHBox" id="hbox13"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">12</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="until-label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes" comments="Translators: This is part of 'Until [ date ]', where [ date ] is a date picker" context="ESendOptions">_Until</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">until-date</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="EDateEdit" id="until-date"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"/> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label103"> - <property name="visible">True</property> - <property name="label" translatable="yes">Delivery Options</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - </child> - </object> - <packing> - <property name="right_attach">4</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkComboBox" id="combo-priority"> - <property name="visible">True</property> - <property name="model">model1</property> - <child> - <object class="GtkCellRendererText" id="renderer1"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="priority-label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Priority:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">combo-priority</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="security-label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Classification:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">security-combo</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkComboBox" id="security-combo"> - <property name="visible">True</property> - <property name="model">model2</property> - <child> - <object class="GtkCellRendererText" id="renderer2"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="gopts-label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Gene_ral Options</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="status-tracking"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">12</property> - <child> - <object class="GtkFrame" id="frame18"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkAlignment" id="alignment42"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkVBox" id="vbox10"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">12</property> - <child> - <object class="GtkCheckButton" id="create-sent-button"> - <property name="label" translatable="yes">Creat_e a sent item to track information</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment46"> - <property name="visible">True</property> - <property name="left_padding">19</property> - <child> - <object class="GtkRadioButton" id="delivered"> - <property name="label" translatable="yes">_Delivered</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment47"> - <property name="visible">True</property> - <property name="left_padding">19</property> - <child> - <object class="GtkRadioButton" id="delivered-opened"> - <property name="label" translatable="yes">Deli_vered and opened</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">delivered</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment48"> - <property name="visible">True</property> - <property name="left_padding">19</property> - <child> - <object class="GtkRadioButton" id="all-info"> - <property name="label" translatable="yes">_All information</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">delivered</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment56"> - <property name="visible">True</property> - <property name="left_padding">19</property> - <child> - <object class="GtkCheckButton" id="autodelete"> - <property name="label" translatable="yes">A_uto-delete sent item</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> - </packing> - </child> - </object> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label106"> - <property name="visible">True</property> - <property name="label" translatable="yes">Status Tracking</property> - <property name="use_underline">True</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame19"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkAlignment" id="alignment43"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkTable" id="table35"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="n_rows">4</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">12</property> - <child> - <object class="GtkLabel" id="opened-label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_When opened:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">open-combo</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="declined-label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">When decli_ned:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">delete-combo</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="completed-label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">When co_mpleted:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">complete-combo</property> - </object> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkLabel" id="accepted-label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">When acce_pted:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">accept-combo</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"/> - </packing> - </child> - <child> - <object class="GtkComboBox" id="open-combo"> - <property name="visible">True</property> - <property name="model">model3</property> - <child> - <object class="GtkCellRendererText" id="renderer3"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="delete-combo"> - <property name="visible">True</property> - <property name="model">model4</property> - <child> - <object class="GtkCellRendererText" id="renderer4"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="accept-combo"> - <property name="visible">True</property> - <property name="model">model5</property> - <child> - <object class="GtkCellRendererText" id="renderer5"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="complete-combo"> - <property name="visible">True</property> - <property name="model">model6</property> - <child> - <object class="GtkCellRendererText" id="renderer6"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - </packing> - </child> - </object> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label111"> - <property name="visible">True</property> - <property name="label" translatable="yes">Return Notification</property> - <property name="use_underline">True</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="slabel"> - <property name="visible">True</property> - <property name="label" translatable="yes">Sta_tus Tracking</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="helpbutton1"> - <property name="label">gtk-help</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="cancelbutton1"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="okbutton1"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-11">helpbutton1</action-widget> - <action-widget response="-6">cancelbutton1</action-widget> - <action-widget response="-5">okbutton1</action-widget> - </action-widgets> - </object> -</interface> diff --git a/widgets/misc/e-source-config-backend.c b/widgets/misc/e-source-config-backend.c deleted file mode 100644 index e6802f99ae..0000000000 --- a/widgets/misc/e-source-config-backend.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * e-source-config-backend.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-source-config-backend.h" - -G_DEFINE_TYPE ( - ESourceConfigBackend, - e_source_config_backend, - E_TYPE_EXTENSION) - -static gboolean -source_config_backend_allow_creation (ESourceConfigBackend *backend) -{ - return TRUE; -} - -static void -source_config_backend_insert_widgets (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - /* does nothing */ -} - -static gboolean -source_config_backend_check_complete (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - return TRUE; -} - -static void -source_config_backend_commit_changes (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - /* does nothing */ -} - -static void -e_source_config_backend_class_init (ESourceConfigBackendClass *class) -{ - EExtensionClass *extension_class; - - extension_class = E_EXTENSION_CLASS (class); - extension_class->extensible_type = E_TYPE_SOURCE_CONFIG; - - class->allow_creation = source_config_backend_allow_creation; - class->insert_widgets = source_config_backend_insert_widgets; - class->check_complete = source_config_backend_check_complete; - class->commit_changes = source_config_backend_commit_changes; -} - -static void -e_source_config_backend_init (ESourceConfigBackend *backend) -{ -} - -ESourceConfig * -e_source_config_backend_get_config (ESourceConfigBackend *backend) -{ - EExtensible *extensible; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG_BACKEND (backend), NULL); - - extensible = e_extension_get_extensible (E_EXTENSION (backend)); - - return E_SOURCE_CONFIG (extensible); -} - -gboolean -e_source_config_backend_allow_creation (ESourceConfigBackend *backend) -{ - ESourceConfigBackendClass *class; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG_BACKEND (backend), FALSE); - - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - g_return_val_if_fail (class->allow_creation != NULL, FALSE); - - return class->allow_creation (backend); -} - -void -e_source_config_backend_insert_widgets (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - ESourceConfigBackendClass *class; - - g_return_if_fail (E_IS_SOURCE_CONFIG_BACKEND (backend)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - g_return_if_fail (class->insert_widgets != NULL); - - class->insert_widgets (backend, scratch_source); -} - -gboolean -e_source_config_backend_check_complete (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - ESourceConfigBackendClass *class; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG_BACKEND (backend), FALSE); - g_return_val_if_fail (E_IS_SOURCE (scratch_source), FALSE); - - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - g_return_val_if_fail (class->check_complete != NULL, FALSE); - - return class->check_complete (backend, scratch_source); -} - -void -e_source_config_backend_commit_changes (ESourceConfigBackend *backend, - ESource *scratch_source) -{ - ESourceConfigBackendClass *class; - - g_return_if_fail (E_IS_SOURCE_CONFIG_BACKEND (backend)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - g_return_if_fail (class->commit_changes != NULL); - - class->commit_changes (backend, scratch_source); -} diff --git a/widgets/misc/e-source-config-backend.h b/widgets/misc/e-source-config-backend.h deleted file mode 100644 index 8141cea1a5..0000000000 --- a/widgets/misc/e-source-config-backend.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * e-source-config-backend.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_SOURCE_CONFIG_BACKEND_H -#define E_SOURCE_CONFIG_BACKEND_H - -#include <libebackend/libebackend.h> - -#include <misc/e-source-config.h> - -/* Standard GObject macros */ -#define E_TYPE_SOURCE_CONFIG_BACKEND \ - (e_source_config_backend_get_type ()) -#define E_SOURCE_CONFIG_BACKEND(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SOURCE_CONFIG_BACKEND, ESourceConfigBackend)) -#define E_SOURCE_CONFIG_BACKEND_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SOURCE_CONFIG_BACKEND, ESourceConfigBackendClass)) -#define E_IS_SOURCE_CONFIG_BACKEND(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SOURCE_CONFIG_BACKEND)) -#define E_IS_SOURCE_CONFIG_BACKEND_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SOURCE_CONFIG_BACKEND)) -#define E_SOURCE_CONFIG_BACKEND_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SOURCE_CONFIG_BACKEND, ESourceConfigBackendClass)) - -G_BEGIN_DECLS - -typedef struct _ESourceConfigBackend ESourceConfigBackend; -typedef struct _ESourceConfigBackendClass ESourceConfigBackendClass; -typedef struct _ESourceConfigBackendPrivate ESourceConfigBackendPrivate; - -struct _ESourceConfigBackend { - EExtension parent; - ESourceConfigBackendPrivate *priv; -}; - -struct _ESourceConfigBackendClass { - EExtensionClass parent_class; - - /* This should match backend names used in ESourceBackend. */ - const gchar *backend_name; - - /* Optional. Collection-based backends can leave this NULL. - * This is only for sources which have a fixed parent source, - * usually one of the "stub" placeholders ("local-stub", etc). */ - const gchar *parent_uid; - - gboolean (*allow_creation) (ESourceConfigBackend *backend); - void (*insert_widgets) (ESourceConfigBackend *backend, - ESource *scratch_source); - gboolean (*check_complete) (ESourceConfigBackend *backend, - ESource *scratch_source); - void (*commit_changes) (ESourceConfigBackend *backend, - ESource *scratch_source); -}; - -GType e_source_config_backend_get_type - (void) G_GNUC_CONST; -ESourceConfig * e_source_config_backend_get_config - (ESourceConfigBackend *backend); -gboolean e_source_config_backend_allow_creation - (ESourceConfigBackend *backend); -void e_source_config_backend_insert_widgets - (ESourceConfigBackend *backend, - ESource *scratch_source); -gboolean e_source_config_backend_check_complete - (ESourceConfigBackend *backend, - ESource *scratch_source); -void e_source_config_backend_commit_changes - (ESourceConfigBackend *backend, - ESource *scratch_source); - -G_END_DECLS - -#endif /* E_SOURCE_CONFIG_BACKEND_H */ diff --git a/widgets/misc/e-source-config-dialog.c b/widgets/misc/e-source-config-dialog.c deleted file mode 100644 index 437027e498..0000000000 --- a/widgets/misc/e-source-config-dialog.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * e-source-config-dialog.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-source-config-dialog.h" - -#include <libevolution-utils/e-alert-dialog.h> -#include <libevolution-utils/e-alert-sink.h> -#include <misc/e-alert-bar.h> - -#define E_SOURCE_CONFIG_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SOURCE_CONFIG_DIALOG, ESourceConfigDialogPrivate)) - -struct _ESourceConfigDialogPrivate { - ESourceConfig *config; - ESourceRegistry *registry; - - GtkWidget *alert_bar; - gulong alert_bar_visible_handler_id; -}; - -enum { - PROP_0, - PROP_CONFIG -}; - -/* Forward Declarations */ -static void e_source_config_dialog_alert_sink_init - (EAlertSinkInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - ESourceConfigDialog, - e_source_config_dialog, - GTK_TYPE_DIALOG, - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_source_config_dialog_alert_sink_init)) - -static void -source_config_dialog_commit_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - ESourceConfig *config; - ESourceConfigDialog *dialog; - GdkWindow *gdk_window; - GError *error = NULL; - - config = E_SOURCE_CONFIG (object); - dialog = E_SOURCE_CONFIG_DIALOG (user_data); - - /* Set the cursor back to normal. */ - gdk_window = gtk_widget_get_window (GTK_WIDGET (dialog)); - gdk_window_set_cursor (gdk_window, NULL); - - /* Allow user interaction with window content. */ - gtk_widget_set_sensitive (GTK_WIDGET (dialog), TRUE); - - e_source_config_commit_finish (config, result, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_object_unref (dialog); - g_error_free (error); - - } else if (error != NULL) { - e_alert_submit ( - E_ALERT_SINK (dialog), - "system:simple-error", - error->message, NULL); - g_object_unref (dialog); - g_error_free (error); - - } else { - gtk_widget_destroy (GTK_WIDGET (dialog)); - } -} - -static void -source_config_dialog_commit (ESourceConfigDialog *dialog) -{ - GdkCursor *gdk_cursor; - GdkWindow *gdk_window; - ESourceConfig *config; - - config = e_source_config_dialog_get_config (dialog); - - /* Clear any previous alerts. */ - e_alert_bar_clear (E_ALERT_BAR (dialog->priv->alert_bar)); - - /* Make the cursor appear busy. */ - gdk_cursor = gdk_cursor_new (GDK_WATCH); - gdk_window = gtk_widget_get_window (GTK_WIDGET (dialog)); - gdk_window_set_cursor (gdk_window, gdk_cursor); - g_object_unref (gdk_cursor); - - /* Prevent user interaction with window content. */ - gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); - - /* XXX This operation is not cancellable. */ - e_source_config_commit ( - config, NULL, - source_config_dialog_commit_cb, - g_object_ref (dialog)); -} - -static void -source_config_dialog_source_removed_cb (ESourceRegistry *registry, - ESource *removed_source, - ESourceConfigDialog *dialog) -{ - ESourceConfig *config; - ESource *original_source; - - /* If the ESource being edited is removed, cancel the dialog. */ - - config = e_source_config_dialog_get_config (dialog); - original_source = e_source_config_get_original_source (config); - - if (original_source == NULL) - return; - - if (!e_source_equal (original_source, removed_source)) - return; - - gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); -} - -static void -source_config_alert_bar_visible_cb (EAlertBar *alert_bar, - GParamSpec *pspec, - ESourceConfigDialog *dialog) -{ - e_source_config_resize_window (dialog->priv->config); -} - -static void -source_config_dialog_set_config (ESourceConfigDialog *dialog, - ESourceConfig *config) -{ - ESourceRegistry *registry; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (dialog->priv->config == NULL); - - dialog->priv->config = g_object_ref (config); - - registry = e_source_config_get_registry (config); - dialog->priv->registry = g_object_ref (registry); - - g_signal_connect ( - registry, "source-removed", - G_CALLBACK (source_config_dialog_source_removed_cb), dialog); -} - -static void -source_config_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CONFIG: - source_config_dialog_set_config ( - E_SOURCE_CONFIG_DIALOG (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -source_config_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CONFIG: - g_value_set_object ( - value, - e_source_config_dialog_get_config ( - E_SOURCE_CONFIG_DIALOG (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -source_config_dialog_dispose (GObject *object) -{ - ESourceConfigDialogPrivate *priv; - - priv = E_SOURCE_CONFIG_DIALOG_GET_PRIVATE (object); - - if (priv->config != NULL) { - g_object_unref (priv->config); - priv->config = NULL; - } - - 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; - } - - if (priv->alert_bar != NULL) { - g_signal_handler_disconnect ( - priv->alert_bar, - priv->alert_bar_visible_handler_id); - g_object_unref (priv->alert_bar); - priv->alert_bar = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_source_config_dialog_parent_class)->dispose (object); -} - -static void -source_config_dialog_constructed (GObject *object) -{ - ESourceConfigDialogPrivate *priv; - GtkWidget *content_area; - GtkWidget *config; - GtkWidget *widget; - gulong handler_id; - - priv = E_SOURCE_CONFIG_DIALOG_GET_PRIVATE (object); - - config = GTK_WIDGET (priv->config); - - widget = gtk_dialog_get_widget_for_response ( - GTK_DIALOG (object), GTK_RESPONSE_OK); - - gtk_container_set_border_width (GTK_CONTAINER (object), 5); - gtk_container_set_border_width (GTK_CONTAINER (config), 5); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (object)); - gtk_box_pack_start (GTK_BOX (content_area), config, TRUE, TRUE, 0); - gtk_widget_show (config); - - /* Don't use G_BINDING_SYNC_CREATE here. The ESourceConfig widget - * is not ready to run check_complete() until after it's realized. */ - g_object_bind_property ( - config, "complete", - widget, "sensitive", - G_BINDING_DEFAULT); - - widget = e_alert_bar_new (); - gtk_box_pack_start (GTK_BOX (content_area), widget, FALSE, FALSE, 0); - priv->alert_bar = g_object_ref (widget); - /* EAlertBar controls its own visibility. */ - - handler_id = g_signal_connect ( - priv->alert_bar, "notify::visible", - G_CALLBACK (source_config_alert_bar_visible_cb), object); - - priv->alert_bar_visible_handler_id = handler_id; -} - -static void -source_config_dialog_response (GtkDialog *dialog, - gint response_id) -{ - /* Do not chain up. GtkDialog does not implement this method. */ - - switch (response_id) { - case GTK_RESPONSE_OK: - source_config_dialog_commit ( - E_SOURCE_CONFIG_DIALOG (dialog)); - break; - case GTK_RESPONSE_CANCEL: - gtk_widget_destroy (GTK_WIDGET (dialog)); - break; - default: - break; - } -} - -static void -source_config_dialog_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - ESourceConfigDialogPrivate *priv; - EAlertBar *alert_bar; - GtkWidget *dialog; - GtkWindow *parent; - - priv = E_SOURCE_CONFIG_DIALOG_GET_PRIVATE (alert_sink); - - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - case GTK_MESSAGE_WARNING: - case GTK_MESSAGE_ERROR: - alert_bar = E_ALERT_BAR (priv->alert_bar); - e_alert_bar_add_alert (alert_bar, alert); - break; - - default: - parent = GTK_WINDOW (alert_sink); - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - break; - } -} - -static void -e_source_config_dialog_class_init (ESourceConfigDialogClass *class) -{ - GObjectClass *object_class; - GtkDialogClass *dialog_class; - - g_type_class_add_private (class, sizeof (ESourceConfigDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = source_config_dialog_set_property; - object_class->get_property = source_config_dialog_get_property; - object_class->dispose = source_config_dialog_dispose; - object_class->constructed = source_config_dialog_constructed; - - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = source_config_dialog_response; - - g_object_class_install_property ( - object_class, - PROP_CONFIG, - g_param_spec_object ( - "config", - "Config", - "The ESourceConfig instance", - E_TYPE_SOURCE_CONFIG, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -e_source_config_dialog_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = source_config_dialog_submit_alert; -} - -static void -e_source_config_dialog_init (ESourceConfigDialog *dialog) -{ - dialog->priv = E_SOURCE_CONFIG_DIALOG_GET_PRIVATE (dialog); - - 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); -} - -GtkWidget * -e_source_config_dialog_new (ESourceConfig *config) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - return g_object_new ( - E_TYPE_SOURCE_CONFIG_DIALOG, - "config", config, NULL); -} - -ESourceConfig * -e_source_config_dialog_get_config (ESourceConfigDialog *dialog) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFIG_DIALOG (dialog), NULL); - - return dialog->priv->config; -} diff --git a/widgets/misc/e-source-config-dialog.h b/widgets/misc/e-source-config-dialog.h deleted file mode 100644 index b4e49efc63..0000000000 --- a/widgets/misc/e-source-config-dialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * e-source-config-dialog.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_SOURCE_CONFIG_DIALOG_H -#define E_SOURCE_CONFIG_DIALOG_H - -#include <misc/e-source-config.h> - -/* Standard GObject macros */ -#define E_TYPE_SOURCE_CONFIG_DIALOG \ - (e_source_config_dialog_get_type ()) -#define E_SOURCE_CONFIG_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SOURCE_CONFIG_DIALOG, ESourceConfigDialog)) -#define E_SOURCE_CONFIG_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SOURCE_CONFIG_DIALOG, ESourceConfigDialogClass)) -#define E_IS_SOURCE_CONFIG_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SOURCE_CONFIG_DIALOG)) -#define E_IS_SOURCE_CONFIG_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SOURCE_CONFIG_DIALOG)) -#define E_SOURCE_CONFIG_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SOURCE_CONFIG_DIALOG, ESourceConfigDialogClass)) - -G_BEGIN_DECLS - -typedef struct _ESourceConfigDialog ESourceConfigDialog; -typedef struct _ESourceConfigDialogClass ESourceConfigDialogClass; -typedef struct _ESourceConfigDialogPrivate ESourceConfigDialogPrivate; - -struct _ESourceConfigDialog { - GtkDialog parent; - ESourceConfigDialogPrivate *priv; -}; - -struct _ESourceConfigDialogClass { - GtkDialogClass parent_class; -}; - -GType e_source_config_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * e_source_config_dialog_new (ESourceConfig *config); -ESourceConfig * e_source_config_dialog_get_config - (ESourceConfigDialog *dialog); - -G_END_DECLS - -#endif /* E_SOURCE_CONFIG_DIALOG_H */ diff --git a/widgets/misc/e-source-config.c b/widgets/misc/e-source-config.c deleted file mode 100644 index f5ef35287c..0000000000 --- a/widgets/misc/e-source-config.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* - * e-source-config.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-source-config.h" - -#include <config.h> -#include <glib/gi18n-lib.h> - -#include <libebackend/libebackend.h> - -#include <e-util/e-marshal.h> -#include <misc/e-interval-chooser.h> - -#include "e-source-config-backend.h" - -#define E_SOURCE_CONFIG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SOURCE_CONFIG, ESourceConfigPrivate)) - -typedef struct _Candidate Candidate; - -struct _ESourceConfigPrivate { - ESource *original_source; - ESource *collection_source; - ESourceRegistry *registry; - - GHashTable *backends; - GPtrArray *candidates; - - GtkWidget *type_label; - GtkWidget *type_combo; - GtkWidget *name_label; - GtkWidget *name_entry; - GtkWidget *backend_box; - GtkSizeGroup *size_group; - - gboolean complete; -}; - -struct _Candidate { - GtkWidget *page; - ESource *scratch_source; - ESourceConfigBackend *backend; - gulong changed_handler_id; -}; - -enum { - PROP_0, - PROP_COLLECTION_SOURCE, - PROP_COMPLETE, - PROP_ORIGINAL_SOURCE, - PROP_REGISTRY -}; - -enum { - CHECK_COMPLETE, - COMMIT_CHANGES, - INIT_CANDIDATE, - RESIZE_WINDOW, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE_WITH_CODE ( - ESourceConfig, - e_source_config, - GTK_TYPE_BOX, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL)) - -static void -source_config_init_backends (ESourceConfig *config) -{ - GList *list, *iter; - - config->priv->backends = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); - - e_extensible_load_extensions (E_EXTENSIBLE (config)); - - list = e_extensible_list_extensions ( - E_EXTENSIBLE (config), E_TYPE_SOURCE_CONFIG_BACKEND); - - for (iter = list; iter != NULL; iter = g_list_next (iter)) { - ESourceConfigBackend *backend; - ESourceConfigBackendClass *class; - - backend = E_SOURCE_CONFIG_BACKEND (iter->data); - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - - if (class->backend_name != NULL) - g_hash_table_insert ( - config->priv->backends, - g_strdup (class->backend_name), - g_object_ref (backend)); - } - - g_list_free (list); -} - -static gint -source_config_compare_sources (gconstpointer a, - gconstpointer b, - gpointer user_data) -{ - ESource *source_a; - ESource *source_b; - ESource *parent_a; - ESource *parent_b; - ESourceConfig *config; - ESourceRegistry *registry; - const gchar *parent_uid_a; - const gchar *parent_uid_b; - gint result; - - source_a = E_SOURCE (a); - source_b = E_SOURCE (b); - config = E_SOURCE_CONFIG (user_data); - - if (e_source_equal (source_a, source_b)) - return 0; - - /* "On This Computer" always comes first. */ - - parent_uid_a = e_source_get_parent (source_a); - parent_uid_b = e_source_get_parent (source_b); - - if (g_strcmp0 (parent_uid_a, "local-stub") == 0) - return -1; - - if (g_strcmp0 (parent_uid_b, "local-stub") == 0) - return 1; - - registry = e_source_config_get_registry (config); - - parent_a = e_source_registry_ref_source (registry, parent_uid_a); - parent_b = e_source_registry_ref_source (registry, parent_uid_b); - - g_return_val_if_fail (parent_a != NULL, 1); - g_return_val_if_fail (parent_b != NULL, -1); - - result = e_source_compare_by_display_name (parent_a, parent_b); - - g_object_unref (parent_a); - g_object_unref (parent_b); - - return result; -} - -static void -source_config_add_candidate (ESourceConfig *config, - ESource *scratch_source, - ESourceConfigBackend *backend) -{ - Candidate *candidate; - GtkBox *backend_box; - GtkLabel *type_label; - GtkComboBoxText *type_combo; - ESource *parent_source; - ESourceRegistry *registry; - const gchar *display_name; - const gchar *parent_uid; - gulong handler_id; - - backend_box = GTK_BOX (config->priv->backend_box); - type_label = GTK_LABEL (config->priv->type_label); - type_combo = GTK_COMBO_BOX_TEXT (config->priv->type_combo); - - registry = e_source_config_get_registry (config); - parent_uid = e_source_get_parent (scratch_source); - parent_source = e_source_registry_ref_source (registry, parent_uid); - g_return_if_fail (parent_source != NULL); - - candidate = g_slice_new (Candidate); - candidate->backend = g_object_ref (backend); - candidate->scratch_source = g_object_ref (scratch_source); - - /* Do not show the page here. */ - candidate->page = g_object_ref_sink (gtk_vbox_new (FALSE, 6)); - gtk_box_pack_start (backend_box, candidate->page, FALSE, FALSE, 0); - - g_ptr_array_add (config->priv->candidates, candidate); - - display_name = e_source_get_display_name (parent_source); - gtk_combo_box_text_append_text (type_combo, display_name); - gtk_label_set_text (type_label, display_name); - - /* Make sure the combo box has a valid active item before - * adding widgets. Otherwise we'll get run-time warnings - * as property bindings are set up. */ - if (gtk_combo_box_get_active (GTK_COMBO_BOX (type_combo)) == -1) - gtk_combo_box_set_active (GTK_COMBO_BOX (type_combo), 0); - - /* Bind the standard widgets to the new scratch source. */ - g_signal_emit ( - config, signals[INIT_CANDIDATE], 0, - candidate->scratch_source); - - /* Insert any backend-specific widgets. */ - e_source_config_backend_insert_widgets ( - candidate->backend, candidate->scratch_source); - - handler_id = g_signal_connect_swapped ( - candidate->scratch_source, "changed", - G_CALLBACK (e_source_config_check_complete), config); - - candidate->changed_handler_id = handler_id; - - /* Trigger the "changed" handler we just connected to set the - * initial "complete" state based on the widgets we just added. */ - e_source_changed (candidate->scratch_source); - - g_object_unref (parent_source); -} - -static void -source_config_free_candidate (Candidate *candidate) -{ - g_signal_handler_disconnect ( - candidate->scratch_source, - candidate->changed_handler_id); - - g_object_unref (candidate->page); - g_object_unref (candidate->scratch_source); - g_object_unref (candidate->backend); - - g_slice_free (Candidate, candidate); -} - -static Candidate * -source_config_get_active_candidate (ESourceConfig *config) -{ - GtkComboBox *type_combo; - gint index; - - type_combo = GTK_COMBO_BOX (config->priv->type_combo); - index = gtk_combo_box_get_active (type_combo); - g_return_val_if_fail (index >= 0, NULL); - - return g_ptr_array_index (config->priv->candidates, index); -} - -static void -source_config_type_combo_changed_cb (GtkComboBox *type_combo, - ESourceConfig *config) -{ - Candidate *candidate; - GPtrArray *array; - gint index; - - array = config->priv->candidates; - - for (index = 0; index < array->len; index++) { - candidate = g_ptr_array_index (array, index); - gtk_widget_hide (candidate->page); - } - - index = gtk_combo_box_get_active (type_combo); - if (index == CLAMP (index, 0, array->len)) { - candidate = g_ptr_array_index (array, index); - gtk_widget_show (candidate->page); - } - - e_source_config_resize_window (config); - e_source_config_check_complete (config); -} - -static gboolean -source_config_init_for_adding_source_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - ESource *scratch_source; - ESourceBackend *extension; - ESourceConfig *config; - ESourceConfigBackend *backend; - ESourceConfigBackendClass *class; - const gchar *extension_name; - - scratch_source = E_SOURCE (key); - backend = E_SOURCE_CONFIG_BACKEND (value); - config = E_SOURCE_CONFIG (user_data); - - /* This may not be the correct backend name for the child of a - * collection. For example, the "yahoo" collection backend uses - * the "caldav" calender backend for calendar children. But the - * ESourceCollectionBackend can override our setting if needed. */ - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - extension_name = e_source_config_get_backend_extension_name (config); - extension = e_source_get_extension (scratch_source, extension_name); - e_source_backend_set_backend_name (extension, class->backend_name); - - source_config_add_candidate (config, scratch_source, backend); - - return FALSE; /* don't stop traversal */ -} - -static void -source_config_init_for_adding_source (ESourceConfig *config) -{ - GList *list, *link; - ESourceRegistry *registry; - GTree *scratch_source_tree; - - /* Candidates are drawn from two sources: - * - * ESourceConfigBackend classes that specify a fixed parent UID, - * meaning there exists one only possible parent source for any - * scratch source created by the backend. The fixed parent UID - * should be a built-in "stub" placeholder ("local-stub", etc). - * - * -and- - * - * Collection sources. We let ESourceConfig subclasses gather - * eligible collection sources to serve as parents for scratch - * sources. A scratch source is matched to a backend based on - * the collection's backend name. The "calendar-enabled" and - * "contacts-enabled" settings also factor into eligibility. - */ - - /* Use a GTree instead of a GHashTable so inserted scratch - * sources automatically sort themselves by their parent's - * display name. */ - scratch_source_tree = g_tree_new_full ( - source_config_compare_sources, config, - (GDestroyNotify) g_object_unref, - (GDestroyNotify) g_object_unref); - - registry = e_source_config_get_registry (config); - - /* First pick out the backends with a fixed parent UID. */ - - list = g_hash_table_get_values (config->priv->backends); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESourceConfigBackend *backend; - ESourceConfigBackendClass *class; - ESource *scratch_source; - ESource *parent_source; - gboolean parent_is_disabled; - - backend = E_SOURCE_CONFIG_BACKEND (link->data); - class = E_SOURCE_CONFIG_BACKEND_GET_CLASS (backend); - - if (class->parent_uid == NULL) - continue; - - /* Verify the fixed parent UID is valid. */ - parent_source = e_source_registry_ref_source ( - registry, class->parent_uid); - if (parent_source == NULL) { - g_warning ( - "%s: %sClass specifies " - "an invalid parent_uid '%s'", - G_STRFUNC, - G_OBJECT_TYPE_NAME (backend), - class->parent_uid); - continue; - } - parent_is_disabled = !e_source_get_enabled (parent_source); - g_object_unref (parent_source); - - /* It's unusual for a fixed parent source to be disabled. - * A user would have to go out of his way to do this, but - * we should honor it regardless. */ - if (parent_is_disabled) - continue; - - /* Some backends don't allow new sources to be created. - * The "contacts" calendar backend is one such example. */ - if (!e_source_config_backend_allow_creation (backend)) - continue; - - scratch_source = e_source_new (NULL, NULL, NULL); - g_return_if_fail (scratch_source != NULL); - - e_source_set_parent (scratch_source, class->parent_uid); - - g_tree_insert ( - scratch_source_tree, - g_object_ref (scratch_source), - g_object_ref (backend)); - - g_object_unref (scratch_source); - } - - g_list_free (list); - - /* Next gather eligible collection sources to serve as parents. */ - - list = e_source_config_list_eligible_collections (config); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *parent_source; - ESource *scratch_source; - ESourceBackend *extension; - ESourceConfigBackend *backend = NULL; - const gchar *backend_name; - const gchar *parent_uid; - - parent_source = E_SOURCE (link->data); - parent_uid = e_source_get_uid (parent_source); - - extension = e_source_get_extension ( - parent_source, E_SOURCE_EXTENSION_COLLECTION); - backend_name = e_source_backend_get_backend_name (extension); - - if (backend_name != NULL) - backend = g_hash_table_lookup ( - config->priv->backends, backend_name); - - if (backend == NULL) - continue; - - /* Some backends disallow creating certain types of - * resources. For example, the Exchange Web Services - * backend disallows creating new memo lists. */ - if (!e_source_config_backend_allow_creation (backend)) - continue; - - scratch_source = e_source_new (NULL, NULL, NULL); - g_return_if_fail (scratch_source != NULL); - - e_source_set_parent (scratch_source, parent_uid); - - g_tree_insert ( - scratch_source_tree, - g_object_ref (scratch_source), - g_object_ref (backend)); - - g_object_unref (scratch_source); - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - /* XXX GTree doesn't get as much love as GHashTable. - * It's missing an equivalent to GHashTableIter. */ - g_tree_foreach ( - scratch_source_tree, - source_config_init_for_adding_source_foreach, config); - - g_tree_unref (scratch_source_tree); -} - -static void -source_config_init_for_editing_source (ESourceConfig *config) -{ - ESource *original_source; - ESource *scratch_source; - ESourceBackend *extension; - ESourceConfigBackend *backend; - GDBusObject *dbus_object; - const gchar *backend_name; - const gchar *extension_name; - - original_source = e_source_config_get_original_source (config); - g_return_if_fail (original_source != NULL); - - extension_name = e_source_config_get_backend_extension_name (config); - extension = e_source_get_extension (original_source, extension_name); - backend_name = e_source_backend_get_backend_name (extension); - g_return_if_fail (backend_name != NULL); - - backend = g_hash_table_lookup (config->priv->backends, backend_name); - g_return_if_fail (backend != NULL); - - dbus_object = e_source_ref_dbus_object (original_source); - g_return_if_fail (dbus_object != NULL); - - scratch_source = e_source_new (dbus_object, NULL, NULL); - g_return_if_fail (scratch_source != NULL); - - source_config_add_candidate (config, scratch_source, backend); - - g_object_unref (scratch_source); - g_object_unref (dbus_object); -} - -static void -source_config_set_original_source (ESourceConfig *config, - ESource *original_source) -{ - g_return_if_fail (config->priv->original_source == NULL); - - if (original_source != NULL) - g_object_ref (original_source); - - config->priv->original_source = original_source; -} - -static void -source_config_set_registry (ESourceConfig *config, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (config->priv->registry == NULL); - - config->priv->registry = g_object_ref (registry); -} - -static void -source_config_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ORIGINAL_SOURCE: - source_config_set_original_source ( - E_SOURCE_CONFIG (object), - g_value_get_object (value)); - return; - - case PROP_REGISTRY: - source_config_set_registry ( - E_SOURCE_CONFIG (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -source_config_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_COLLECTION_SOURCE: - g_value_set_object ( - value, - e_source_config_get_collection_source ( - E_SOURCE_CONFIG (object))); - return; - - case PROP_COMPLETE: - g_value_set_boolean ( - value, - e_source_config_check_complete ( - E_SOURCE_CONFIG (object))); - return; - - case PROP_ORIGINAL_SOURCE: - g_value_set_object ( - value, - e_source_config_get_original_source ( - E_SOURCE_CONFIG (object))); - return; - - case PROP_REGISTRY: - g_value_set_object ( - value, - e_source_config_get_registry ( - E_SOURCE_CONFIG (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -source_config_dispose (GObject *object) -{ - ESourceConfigPrivate *priv; - - priv = E_SOURCE_CONFIG_GET_PRIVATE (object); - - if (priv->original_source != NULL) { - g_object_unref (priv->original_source); - priv->original_source = NULL; - } - - if (priv->collection_source != NULL) { - g_object_unref (priv->collection_source); - priv->collection_source = NULL; - } - - if (priv->registry != NULL) { - g_object_unref (priv->registry); - priv->registry = NULL; - } - - if (priv->type_label != NULL) { - g_object_unref (priv->type_label); - priv->type_label = NULL; - } - - if (priv->type_combo != NULL) { - g_object_unref (priv->type_combo); - priv->type_combo = NULL; - } - - if (priv->name_label != NULL) { - g_object_unref (priv->name_label); - priv->name_label = NULL; - } - - if (priv->name_entry != NULL) { - g_object_unref (priv->name_entry); - priv->name_entry = NULL; - } - - if (priv->backend_box != NULL) { - g_object_unref (priv->backend_box); - priv->backend_box = NULL; - } - - if (priv->size_group != NULL) { - g_object_unref (priv->size_group); - priv->size_group = NULL; - } - - g_hash_table_remove_all (priv->backends); - g_ptr_array_set_size (priv->candidates, 0); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_source_config_parent_class)->dispose (object); -} - -static void -source_config_finalize (GObject *object) -{ - ESourceConfigPrivate *priv; - - priv = E_SOURCE_CONFIG_GET_PRIVATE (object); - - g_hash_table_destroy (priv->backends); - g_ptr_array_free (priv->candidates, TRUE); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_source_config_parent_class)->finalize (object); -} - -static void -source_config_constructed (GObject *object) -{ - ESourceConfig *config; - ESourceRegistry *registry; - ESource *original_source; - ESource *collection_source = NULL; - - config = E_SOURCE_CONFIG (object); - registry = e_source_config_get_registry (config); - original_source = e_source_config_get_original_source (config); - - /* If we have an original source, see if it's part - * of a collection and note the collection source. */ - if (original_source != NULL) { - const gchar *extension_name; - - extension_name = E_SOURCE_EXTENSION_COLLECTION; - collection_source = e_source_registry_find_extension ( - registry, original_source, extension_name); - config->priv->collection_source = collection_source; - } - - if (original_source != NULL) - e_source_config_insert_widget ( - config, NULL, _("Type:"), - config->priv->type_label); - else - e_source_config_insert_widget ( - config, NULL, _("Type:"), - config->priv->type_combo); - - /* If the original source is part of a collection then we assume - * the display name is server-assigned and not user-assigned, at - * least not assigned through Evolution. */ - if (collection_source != NULL) - e_source_config_insert_widget ( - config, NULL, _("Name:"), - config->priv->name_label); - else - e_source_config_insert_widget ( - config, NULL, _("Name:"), - config->priv->name_entry); - - source_config_init_backends (config); -} - -static void -source_config_realize (GtkWidget *widget) -{ - ESourceConfig *config; - ESource *original_source; - - /* Chain up to parent's realize() method. */ - GTK_WIDGET_CLASS (e_source_config_parent_class)->realize (widget); - - /* Do this after constructed() so subclasses can fully - * initialize themselves before we add candidates. */ - - config = E_SOURCE_CONFIG (widget); - original_source = e_source_config_get_original_source (config); - - if (original_source == NULL) - source_config_init_for_adding_source (config); - else - source_config_init_for_editing_source (config); -} - -static GList * -source_config_list_eligible_collections (ESourceConfig *config) -{ - ESourceRegistry *registry; - GQueue trash = G_QUEUE_INIT; - GList *list, *link; - const gchar *extension_name; - - extension_name = E_SOURCE_EXTENSION_COLLECTION; - registry = e_source_config_get_registry (config); - - list = e_source_registry_list_sources (registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - gboolean elligible; - - elligible = - e_source_get_enabled (source) && - e_source_get_remote_creatable (source); - - if (!elligible) - g_queue_push_tail (&trash, link); - } - - /* Remove ineligible collections from the list. */ - while ((link = g_queue_pop_head (&trash)) != NULL) { - g_object_unref (link->data); - list = g_list_delete_link (list, link); - } - - return list; -} - -static void -source_config_init_candidate (ESourceConfig *config, - ESource *scratch_source) -{ - g_object_bind_property ( - scratch_source, "display-name", - config->priv->name_label, "label", - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - scratch_source, "display-name", - config->priv->name_entry, "text", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} - -static gboolean -source_config_check_complete (ESourceConfig *config, - ESource *scratch_source) -{ - GtkEntry *name_entry; - GtkComboBox *type_combo; - const gchar *text; - - /* Make sure the Type: combo box has a valid item. */ - type_combo = GTK_COMBO_BOX (config->priv->type_combo); - if (gtk_combo_box_get_active (type_combo) < 0) - return FALSE; - - /* Make sure the Name: entry field is not empty. */ - name_entry = GTK_ENTRY (config->priv->name_entry); - text = gtk_entry_get_text (name_entry); - if (text == NULL || *text == '\0') - return FALSE; - - return TRUE; -} - -static void -source_config_commit_changes (ESourceConfig *config, - ESource *scratch_source) -{ - /* Placeholder so subclasses can safely chain up. */ -} - -static void -source_config_resize_window (ESourceConfig *config) -{ - GtkWidget *toplevel; - - /* Expand or shrink our parent window vertically to accommodate - * the newly selected backend's options. Some backends have tons - * of options, some have few. This avoids the case where you - * select a backend with tons of options and then a backend with - * few options and wind up with lots of unused vertical space. */ - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (config)); - - if (GTK_IS_WINDOW (toplevel)) { - GtkWindow *window = GTK_WINDOW (toplevel); - GtkAllocation allocation; - - gtk_widget_get_allocation (toplevel, &allocation); - gtk_window_resize (window, allocation.width, 1); - } -} - -static gboolean -source_config_check_complete_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer unused) -{ - gboolean v_boolean; - - /* Abort emission if a handler returns FALSE. */ - v_boolean = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, v_boolean); - - return v_boolean; -} - -static void -e_source_config_class_init (ESourceConfigClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (ESourceConfigPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = source_config_set_property; - object_class->get_property = source_config_get_property; - object_class->dispose = source_config_dispose; - object_class->finalize = source_config_finalize; - object_class->constructed = source_config_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = source_config_realize; - - class->list_eligible_collections = - source_config_list_eligible_collections; - class->init_candidate = source_config_init_candidate; - class->check_complete = source_config_check_complete; - class->commit_changes = source_config_commit_changes; - class->resize_window = source_config_resize_window; - - g_object_class_install_property ( - object_class, - PROP_COLLECTION_SOURCE, - g_param_spec_object ( - "collection-source", - "Collection Source", - "The collection ESource to which " - "the ESource being edited belongs", - E_TYPE_SOURCE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_COMPLETE, - g_param_spec_boolean ( - "complete", - "Complete", - "Are the required fields complete?", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_ORIGINAL_SOURCE, - g_param_spec_object ( - "original-source", - "Original Source", - "The original ESource", - E_TYPE_SOURCE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - "Registry of ESources", - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - signals[CHECK_COMPLETE] = g_signal_new ( - "check-complete", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESourceConfigClass, check_complete), - source_config_check_complete_accumulator, NULL, - e_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, 1, - E_TYPE_SOURCE); - - signals[COMMIT_CHANGES] = g_signal_new ( - "commit-changes", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESourceConfigClass, commit_changes), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_SOURCE); - - signals[INIT_CANDIDATE] = g_signal_new ( - "init-candidate", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESourceConfigClass, init_candidate), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_SOURCE); - - signals[RESIZE_WINDOW] = g_signal_new ( - "resize-window", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESourceConfigClass, resize_window), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_source_config_init (ESourceConfig *config) -{ - GPtrArray *candidates; - GtkSizeGroup *size_group; - PangoAttribute *attr; - PangoAttrList *attr_list; - GtkWidget *widget; - - /* The candidates array holds scratch ESources, one for each - * item in the "type" combo box. Scratch ESources are never - * added to the registry, so backend extensions can make any - * changes they want to them. Whichever scratch ESource is - * "active" (selected in the "type" combo box) when the user - * clicks OK wins and is written to disk. The others are - * discarded. */ - candidates = g_ptr_array_new_with_free_func ( - (GDestroyNotify) source_config_free_candidate); - - /* The size group is used for caption labels. */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - gtk_box_set_spacing (GTK_BOX (config), 6); - - gtk_orientable_set_orientation ( - GTK_ORIENTABLE (config), GTK_ORIENTATION_VERTICAL); - - config->priv = E_SOURCE_CONFIG_GET_PRIVATE (config); - config->priv->candidates = candidates; - config->priv->size_group = size_group; - - attr_list = pango_attr_list_new (); - - attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); - pango_attr_list_insert (attr_list, attr); - - /* Either the source type combo box or the label is shown, - * never both. But we create both widgets and keep them - * both up-to-date because it makes the logic simpler. */ - - widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_label_set_attributes (GTK_LABEL (widget), attr_list); - config->priv->type_label = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = gtk_combo_box_text_new (); - config->priv->type_combo = g_object_ref_sink (widget); - gtk_widget_show (widget); - - /* Similarly for the display name. Either the text entry - * or the label is shown, depending on whether the source - * is a collection member (new sources never are). */ - - widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_label_set_attributes (GTK_LABEL (widget), attr_list); - config->priv->name_label = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = gtk_entry_new (); - gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); - config->priv->name_entry = g_object_ref_sink (widget); - gtk_widget_show (widget); - - /* The backend box holds backend-specific options. Each backend - * gets a child widget. Only one child widget is visible at once. */ - widget = gtk_vbox_new (FALSE, 12); - gtk_box_pack_end (GTK_BOX (config), widget, TRUE, TRUE, 0); - config->priv->backend_box = g_object_ref (widget); - gtk_widget_show (widget); - - pango_attr_list_unref (attr_list); - - g_signal_connect ( - config->priv->type_combo, "changed", - G_CALLBACK (source_config_type_combo_changed_cb), config); -} - -GtkWidget * -e_source_config_new (ESourceRegistry *registry, - ESource *original_source) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - if (original_source != NULL) - g_return_val_if_fail (E_IS_SOURCE (original_source), NULL); - - return g_object_new ( - E_TYPE_SOURCE_CONFIG, "registry", registry, - "original-source", original_source, NULL); -} - -void -e_source_config_insert_widget (ESourceConfig *config, - ESource *scratch_source, - const gchar *caption, - GtkWidget *widget) -{ - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *label; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (GTK_IS_WIDGET (widget)); - - if (scratch_source == NULL) - vbox = GTK_WIDGET (config); - else - vbox = e_source_config_get_page (config, scratch_source); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); - - g_object_bind_property ( - widget, "visible", - hbox, "visible", - G_BINDING_SYNC_CREATE); - - label = gtk_label_new (caption); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0); - gtk_size_group_add_widget (config->priv->size_group, label); - gtk_widget_show (label); - - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); -} - -GtkWidget * -e_source_config_get_page (ESourceConfig *config, - ESource *scratch_source) -{ - Candidate *candidate; - GtkWidget *page = NULL; - GPtrArray *array; - gint index; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - g_return_val_if_fail (E_IS_SOURCE (scratch_source), NULL); - - array = config->priv->candidates; - - for (index = 0; page == NULL && index < array->len; index++) { - candidate = g_ptr_array_index (array, index); - if (e_source_equal (scratch_source, candidate->scratch_source)) - page = candidate->page; - } - - g_return_val_if_fail (GTK_IS_BOX (page), NULL); - - return page; -} - -const gchar * -e_source_config_get_backend_extension_name (ESourceConfig *config) -{ - ESourceConfigClass *class; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - class = E_SOURCE_CONFIG_GET_CLASS (config); - g_return_val_if_fail (class->get_backend_extension_name != NULL, NULL); - - return class->get_backend_extension_name (config); -} - -GList * -e_source_config_list_eligible_collections (ESourceConfig *config) -{ - ESourceConfigClass *class; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - class = E_SOURCE_CONFIG_GET_CLASS (config); - g_return_val_if_fail (class->list_eligible_collections != NULL, NULL); - - return class->list_eligible_collections (config); -} - -gboolean -e_source_config_check_complete (ESourceConfig *config) -{ - Candidate *candidate; - gboolean complete; - - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), FALSE); - - candidate = source_config_get_active_candidate (config); - g_return_val_if_fail (candidate != NULL, FALSE); - - g_signal_emit ( - config, signals[CHECK_COMPLETE], 0, - candidate->scratch_source, &complete); - - complete &= e_source_config_backend_check_complete ( - candidate->backend, candidate->scratch_source); - - /* XXX Emitting "notify::complete" may cause this function - * to be called repeatedly by signal handlers. The IF - * check below should break any recursive cycles. Not - * very efficient but I think we can live with it. */ - - if (complete != config->priv->complete) { - config->priv->complete = complete; - g_object_notify (G_OBJECT (config), "complete"); - } - - return complete; -} - -ESource * -e_source_config_get_original_source (ESourceConfig *config) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - return config->priv->original_source; -} - -ESource * -e_source_config_get_collection_source (ESourceConfig *config) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - return config->priv->collection_source; -} - -ESourceRegistry * -e_source_config_get_registry (ESourceConfig *config) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL); - - return config->priv->registry; -} - -void -e_source_config_resize_window (ESourceConfig *config) -{ - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - - g_signal_emit (config, signals[RESIZE_WINDOW], 0); -} - -/* Helper for e_source_config_commit() */ -static void -source_config_commit_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - GError *error = NULL; - - simple = G_SIMPLE_ASYNC_RESULT (user_data); - - e_source_registry_commit_source_finish ( - E_SOURCE_REGISTRY (object), result, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -void -e_source_config_commit (ESourceConfig *config, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - ESourceRegistry *registry; - Candidate *candidate; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - - registry = e_source_config_get_registry (config); - - candidate = source_config_get_active_candidate (config); - g_return_if_fail (candidate != NULL); - - e_source_config_backend_commit_changes ( - candidate->backend, candidate->scratch_source); - - g_signal_emit ( - config, signals[COMMIT_CHANGES], 0, - candidate->scratch_source); - - simple = g_simple_async_result_new ( - G_OBJECT (config), callback, - user_data, e_source_config_commit); - - e_source_registry_commit_source ( - registry, candidate->scratch_source, - cancellable, source_config_commit_cb, simple); -} - -gboolean -e_source_config_commit_finish (ESourceConfig *config, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (config), - e_source_config_commit), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -void -e_source_config_add_refresh_interval (ESourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget; - GtkWidget *container; - ESourceExtension *extension; - const gchar *extension_name; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_REFRESH; - extension = e_source_get_extension (scratch_source, extension_name); - - widget = gtk_alignment_new (0.0, 0.5, 0.0, 0.0); - e_source_config_insert_widget (config, scratch_source, NULL, widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_hbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - /* Translators: This is the first of a sequence of widgets: - * "Refresh every [NUMERIC_ENTRY] [TIME_UNITS_COMBO]" */ - widget = gtk_label_new (_("Refresh every")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = e_interval_chooser_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_object_bind_property ( - extension, "interval-minutes", - widget, "interval-minutes", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} - -void -e_source_config_add_secure_connection (ESourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget; - ESourceExtension *extension; - const gchar *extension_name; - const gchar *label; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_SECURITY; - extension = e_source_get_extension (scratch_source, extension_name); - - label = _("Use a secure connection"); - widget = gtk_check_button_new_with_label (label); - e_source_config_insert_widget (config, scratch_source, NULL, widget); - gtk_widget_show (widget); - - g_object_bind_property ( - extension, "secure", - widget, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} - -static gboolean -secure_to_port_cb (GBinding *binding, - const GValue *source_value, - GValue *target_value, - gpointer user_data) -{ - GObject *authentication_extension; - guint16 port; - - authentication_extension = g_binding_get_target (binding); - g_object_get (authentication_extension, "port", &port, NULL); - - if (port == 80 || port == 443 || port == 0) - port = g_value_get_boolean (source_value) ? 443 : 80; - - g_value_set_uint (target_value, port); - - return TRUE; -} - -void -e_source_config_add_secure_connection_for_webdav (ESourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget1; - GtkWidget *widget2; - ESourceExtension *extension; - ESourceAuthentication *authentication_extension; - const gchar *extension_name; - const gchar *label; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_SECURITY; - extension = e_source_get_extension (scratch_source, extension_name); - - label = _("Use a secure connection"); - widget1 = gtk_check_button_new_with_label (label); - e_source_config_insert_widget (config, scratch_source, NULL, widget1); - gtk_widget_show (widget1); - - g_object_bind_property ( - extension, "secure", - widget1, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - extension_name = E_SOURCE_EXTENSION_AUTHENTICATION; - authentication_extension = e_source_get_extension (scratch_source, extension_name); - - g_object_bind_property_full ( - extension, "secure", - authentication_extension, "port", - G_BINDING_DEFAULT, - secure_to_port_cb, - NULL, NULL, NULL); - - extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND; - extension = e_source_get_extension (scratch_source, extension_name); - - label = _("Ignore invalid SSL certificate"); - widget2 = gtk_check_button_new_with_label (label); - gtk_widget_set_margin_left (widget2, 24); - e_source_config_insert_widget (config, scratch_source, NULL, widget2); - gtk_widget_show (widget2); - - g_object_bind_property ( - widget1, "active", - widget2, "sensitive", - G_BINDING_SYNC_CREATE); - - g_object_bind_property ( - extension, "ignore-invalid-cert", - widget2, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); -} - -void -e_source_config_add_user_entry (ESourceConfig *config, - ESource *scratch_source) -{ - GtkWidget *widget; - ESource *original_source; - ESourceExtension *extension; - const gchar *extension_name; - - g_return_if_fail (E_IS_SOURCE_CONFIG (config)); - g_return_if_fail (E_IS_SOURCE (scratch_source)); - - extension_name = E_SOURCE_EXTENSION_AUTHENTICATION; - extension = e_source_get_extension (scratch_source, extension_name); - - original_source = e_source_config_get_original_source (config); - - widget = gtk_entry_new (); - e_source_config_insert_widget ( - config, scratch_source, _("User"), widget); - gtk_widget_show (widget); - - g_object_bind_property ( - extension, "user", - widget, "text", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* If this is a new data source, initialize the - * GtkEntry to the user name of the current user. */ - if (original_source == NULL) - gtk_entry_set_text (GTK_ENTRY (widget), g_get_user_name ()); -} - diff --git a/widgets/misc/e-source-config.h b/widgets/misc/e-source-config.h deleted file mode 100644 index 5d9ff7c93a..0000000000 --- a/widgets/misc/e-source-config.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * e-source-config.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_SOURCE_CONFIG_H -#define E_SOURCE_CONFIG_H - -#include <gtk/gtk.h> -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_SOURCE_CONFIG \ - (e_source_config_get_type ()) -#define E_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SOURCE_CONFIG, ESourceConfig)) -#define E_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SOURCE_CONFIG, ESourceConfigClass)) -#define E_IS_SOURCE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SOURCE_CONFIG)) -#define E_IS_SOURCE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SOURCE_CONFIG)) -#define E_SOURCE_CONFIG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SOURCE_CONFIG, ESourceConfigClass)) - -G_BEGIN_DECLS - -typedef struct _ESourceConfig ESourceConfig; -typedef struct _ESourceConfigClass ESourceConfigClass; -typedef struct _ESourceConfigPrivate ESourceConfigPrivate; - -struct _ESourceConfig { - GtkBox parent; - ESourceConfigPrivate *priv; -}; - -struct _ESourceConfigClass { - GtkBoxClass parent_class; - - /* Methods */ - const gchar * (*get_backend_extension_name) - (ESourceConfig *config); - GList * (*list_eligible_collections) - (ESourceConfig *config); - - /* Signals */ - void (*init_candidate) (ESourceConfig *config, - ESource *scratch_source); - gboolean (*check_complete) (ESourceConfig *config, - ESource *scratch_source); - void (*commit_changes) (ESourceConfig *config, - ESource *scratch_source); - void (*resize_window) (ESourceConfig *config); -}; - -GType e_source_config_get_type (void) G_GNUC_CONST; -GtkWidget * e_source_config_new (ESourceRegistry *registry, - ESource *original_source); -void e_source_config_insert_widget (ESourceConfig *config, - ESource *scratch_source, - const gchar *caption, - GtkWidget *widget); -GtkWidget * e_source_config_get_page (ESourceConfig *config, - ESource *scratch_source); -const gchar * e_source_config_get_backend_extension_name - (ESourceConfig *config); -GList * e_source_config_list_eligible_collections - (ESourceConfig *config); -gboolean e_source_config_check_complete (ESourceConfig *config); -ESource * e_source_config_get_original_source - (ESourceConfig *config); -ESource * e_source_config_get_collection_source - (ESourceConfig *config); -ESourceRegistry * - e_source_config_get_registry (ESourceConfig *config); -void e_source_config_resize_window (ESourceConfig *config); -void e_source_config_commit (ESourceConfig *config, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_source_config_commit_finish (ESourceConfig *config, - GAsyncResult *result, - GError **error); - -/* Convenience functions for common settings. */ -void e_source_config_add_refresh_interval - (ESourceConfig *config, - ESource *scratch_source); -void e_source_config_add_secure_connection - (ESourceConfig *config, - ESource *scratch_source); -void e_source_config_add_secure_connection_for_webdav - (ESourceConfig *config, - ESource *scratch_source); -void e_source_config_add_user_entry (ESourceConfig *config, - ESource *scratch_source); - -#endif /* E_SOURCE_CONFIG_H */ diff --git a/widgets/misc/e-spell-entry.c b/widgets/misc/e-spell-entry.c deleted file mode 100644 index 56f7c14f8c..0000000000 --- a/widgets/misc/e-spell-entry.c +++ /dev/null @@ -1,866 +0,0 @@ -/* - * e-spell-entry.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -/* This code is based on libsexy's SexySpellEntry */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n-lib.h> -#include <gtk/gtk.h> - -#include <editor/gtkhtml-spell-language.h> -#include <editor/gtkhtml-spell-checker.h> - -#include "e-spell-entry.h" - -enum { - PROP_0, - PROP_CHECKING_ENABLED -}; - -struct _ESpellEntryPrivate -{ - PangoAttrList *attr_list; - gint mark_character; - gint entry_scroll_offset; - GSettings *settings; - gboolean custom_checkers; - gboolean checking_enabled; - GSList *checkers; - gchar **words; - gint *word_starts; - gint *word_ends; -}; - -#define E_SPELL_ENTRY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SPELL_ENTRY, ESpellEntryPrivate)) - -G_DEFINE_TYPE (ESpellEntry, e_spell_entry, GTK_TYPE_ENTRY); - -static gboolean -word_misspelled (ESpellEntry *entry, - gint start, - gint end) -{ - const gchar *text; - gchar *word; - gboolean result = TRUE; - - if (start == end) - return FALSE; - - text = gtk_entry_get_text (GTK_ENTRY (entry)); - word = g_new0 (gchar, end - start + 2); - - g_strlcpy (word, text + start, end - start + 1); - - if (g_unichar_isalpha (*word)) { - GSList *li; - gssize wlen = strlen (word); - - for (li = entry->priv->checkers; li; li = g_slist_next (li)) { - GtkhtmlSpellChecker *checker = li->data; - if (gtkhtml_spell_checker_check_word (checker, word, wlen)) { - result = FALSE; - break; - } - } - } - g_free (word); - - return result; -} - -static void -insert_underline (ESpellEntry *entry, - guint start, - guint end) -{ - PangoAttribute *ucolor = pango_attr_underline_color_new (65535, 0, 0); - PangoAttribute *unline = pango_attr_underline_new (PANGO_UNDERLINE_ERROR); - - ucolor->start_index = start; - unline->start_index = start; - - ucolor->end_index = end; - unline->end_index = end; - - pango_attr_list_insert (entry->priv->attr_list, ucolor); - pango_attr_list_insert (entry->priv->attr_list, unline); -} - -static void -check_word (ESpellEntry *entry, - gint start, - gint end) -{ - PangoAttrIterator *it; - - /* Check to see if we've got any attributes at this position. - * If so, free them, since we'll readd it if the word is misspelled */ - it = pango_attr_list_get_iterator (entry->priv->attr_list); - - if (it == NULL) - return; - do { - gint s, e; - pango_attr_iterator_range (it, &s, &e); - if (s == start) { - GSList *attrs = pango_attr_iterator_get_attrs (it); - g_slist_foreach (attrs, (GFunc) pango_attribute_destroy, NULL); - g_slist_free (attrs); - } - } while (pango_attr_iterator_next (it)); - pango_attr_iterator_destroy (it); - - if (word_misspelled (entry, start, end)) - insert_underline (entry, start, end); -} - -static void -spell_entry_recheck_all (ESpellEntry *entry) -{ - GtkWidget *widget = GTK_WIDGET (entry); - PangoLayout *layout; - gint length, i; - - if (!entry->priv->words) - return; - - /* Remove all existing pango attributes. These will get read as we check */ - pango_attr_list_unref (entry->priv->attr_list); - entry->priv->attr_list = pango_attr_list_new (); - - if (entry->priv->checkers && entry->priv->checking_enabled) { - /* Loop through words */ - for (i = 0; entry->priv->words[i]; i++) { - length = strlen (entry->priv->words[i]); - if (length == 0) - continue; - check_word (entry, entry->priv->word_starts[i], entry->priv->word_ends[i]); - } - - layout = gtk_entry_get_layout (GTK_ENTRY (entry)); - pango_layout_set_attributes (layout, entry->priv->attr_list); - } - - if (gtk_widget_get_realized (widget)) - gtk_widget_queue_draw (widget); -} - -static void -get_word_extents_from_position (ESpellEntry *entry, - gint *start, - gint *end, - guint position) -{ - const gchar *text; - gint i, bytes_pos; - - *start = -1; - *end = -1; - - if (entry->priv->words == NULL) - return; - - text = gtk_entry_get_text (GTK_ENTRY (entry)); - bytes_pos = (gint) (g_utf8_offset_to_pointer (text, position) - text); - - for (i = 0; entry->priv->words[i]; i++) { - if (bytes_pos >= entry->priv->word_starts[i] && - bytes_pos <= entry->priv->word_ends[i]) { - *start = entry->priv->word_starts[i]; - *end = entry->priv->word_ends[i]; - return; - } - } -} - -static void -entry_strsplit_utf8 (GtkEntry *entry, - gchar ***set, - gint **starts, - gint **ends) -{ - PangoLayout *layout; - PangoLogAttr *log_attrs; - const gchar *text; - gint n_attrs, n_strings, i, j; - - layout = gtk_entry_get_layout (GTK_ENTRY (entry)); - text = gtk_entry_get_text (GTK_ENTRY (entry)); - pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - - /* Find how many words we have */ - n_strings = 0; - for (i = 0; i < n_attrs; i++) - if (log_attrs[i].is_word_start) - n_strings++; - - *set = g_new0 (gchar *, n_strings + 1); - *starts = g_new0 (gint, n_strings); - *ends = g_new0 (gint, n_strings); - - /* Copy out strings */ - for (i = 0, j = 0; i < n_attrs; i++) { - if (log_attrs[i].is_word_start) { - gint cend, bytes; - gchar *start; - - /* Find the end of this string */ - cend = i; - while (!(log_attrs[cend].is_word_end)) - cend++; - - /* Copy sub-string */ - start = g_utf8_offset_to_pointer (text, i); - bytes = (gint) (g_utf8_offset_to_pointer (text, cend) - start); - (*set)[j] = g_new0 (gchar, bytes + 1); - (*starts)[j] = (gint) (start - text); - (*ends)[j] = (gint) (start - text + bytes); - g_utf8_strncpy ((*set)[j], start, cend - i); - - /* Move on to the next word */ - j++; - } - } - - g_free (log_attrs); -} - -static void -add_to_dictionary (GtkWidget *menuitem, - ESpellEntry *entry) -{ - gchar *word; - gint start, end; - GtkhtmlSpellChecker *checker; - - get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character); - word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); - - checker = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker"); - if (checker) - gtkhtml_spell_checker_add_word (checker, word, -1); - - g_free (word); - - if (entry->priv->words) { - g_strfreev (entry->priv->words); - g_free (entry->priv->word_starts); - g_free (entry->priv->word_ends); - } - - entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends); - spell_entry_recheck_all (entry); -} - -static void -ignore_all (GtkWidget *menuitem, - ESpellEntry *entry) -{ - gchar *word; - gint start, end; - GSList *li; - - get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character); - word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); - - for (li = entry->priv->checkers; li; li = g_slist_next (li)) { - GtkhtmlSpellChecker *checker = li->data; - gtkhtml_spell_checker_add_word_to_session (checker, word, -1); - } - - g_free (word); - - if (entry->priv->words) { - g_strfreev (entry->priv->words); - g_free (entry->priv->word_starts); - g_free (entry->priv->word_ends); - } - entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends); - spell_entry_recheck_all (entry); -} - -static void -replace_word (GtkWidget *menuitem, - ESpellEntry *entry) -{ - gchar *oldword; - const gchar *newword; - gint start, end; - gint cursor; - GtkhtmlSpellChecker *checker; - - get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character); - oldword = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); - newword = gtk_label_get_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (menuitem)))); - - cursor = gtk_editable_get_position (GTK_EDITABLE (entry)); - /* is the cursor at the end? If so, restore it there */ - if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1) == cursor) - cursor = -1; - else if (cursor > start && cursor <= end) - cursor = start; - - gtk_editable_delete_text (GTK_EDITABLE (entry), start, end); - gtk_editable_set_position (GTK_EDITABLE (entry), start); - gtk_editable_insert_text ( - GTK_EDITABLE (entry), newword, strlen (newword), - &start); - gtk_editable_set_position (GTK_EDITABLE (entry), cursor); - - checker = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker"); - - if (checker) - gtkhtml_spell_checker_store_replacement (checker, oldword, -1, newword, -1); - - g_free (oldword); -} - -static void -build_suggestion_menu (ESpellEntry *entry, - GtkWidget *menu, - GtkhtmlSpellChecker *checker, - const gchar *word) -{ - GtkWidget *mi; - GList *suggestions, *iter; - - suggestions = gtkhtml_spell_checker_get_suggestions (checker, word, -1); - - if (!suggestions) { - /* no suggestions. Put something in the menu anyway... */ - GtkWidget *label = gtk_label_new (_("(no suggestions)")); - PangoAttribute *attribute; - PangoAttrList *attribute_list; - - attribute_list = pango_attr_list_new (); - attribute = pango_attr_style_new (PANGO_STYLE_ITALIC); - pango_attr_list_insert (attribute_list, attribute); - gtk_label_set_attributes (GTK_LABEL (label), attribute_list); - pango_attr_list_unref (attribute_list); - - mi = gtk_separator_menu_item_new (); - gtk_container_add (GTK_CONTAINER (mi), label); - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - } else { - gint ii = 0; - - /* build a set of menus with suggestions */ - for (iter = suggestions; iter; iter = g_list_next (iter), ii++) { - if ((ii != 0) && (ii % 10 == 0)) { - mi = gtk_separator_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - - mi = gtk_menu_item_new_with_label (_("More...")); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu); - } - - mi = gtk_menu_item_new_with_label (iter->data); - g_object_set_data (G_OBJECT (mi), "spell-entry-checker", checker); - g_signal_connect (mi, "activate", G_CALLBACK (replace_word), entry); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - } - } - - g_list_free_full (suggestions, g_free); -} - -static GtkWidget * -build_spelling_menu (ESpellEntry *entry, - const gchar *word) -{ - GtkhtmlSpellChecker *checker; - GtkWidget *topmenu, *mi; - gchar *label; - - topmenu = gtk_menu_new (); - - if (!entry->priv->checkers) - return topmenu; - - /* Suggestions */ - if (!entry->priv->checkers->next) { - checker = entry->priv->checkers->data; - build_suggestion_menu (entry, topmenu, checker, word); - } else { - GSList *li; - GtkWidget *menu; - const gchar *lang_name; - - for (li = entry->priv->checkers; li; li = g_slist_next (li)) { - const GtkhtmlSpellLanguage *language; - - checker = li->data; - language = gtkhtml_spell_checker_get_language (checker); - if (!language) - continue; - - lang_name = gtkhtml_spell_language_get_name (language); - if (!lang_name) - lang_name = gtkhtml_spell_language_get_code (language); - - mi = gtk_menu_item_new_with_label (lang_name ? lang_name : "???"); - - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu); - build_suggestion_menu (entry, menu, checker, word); - } - } - - /* Separator */ - mi = gtk_separator_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - /* + Add to Dictionary */ - label = g_strdup_printf (_("Add \"%s\" to Dictionary"), word); - mi = gtk_image_menu_item_new_with_label (label); - g_free (label); - - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU)); - - if (!entry->priv->checkers->next) { - checker = entry->priv->checkers->data; - g_object_set_data (G_OBJECT (mi), "spell-entry-checker", checker); - g_signal_connect (mi, "activate", G_CALLBACK (add_to_dictionary), entry); - } else { - GSList *li; - GtkWidget *menu, *submi; - const gchar *lang_name; - - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu); - - for (li = entry->priv->checkers; li; li = g_slist_next (li)) { - const GtkhtmlSpellLanguage *language; - - checker = li->data; - language = gtkhtml_spell_checker_get_language (checker); - if (!language) - continue; - - lang_name = gtkhtml_spell_language_get_name (language); - if (!lang_name) - lang_name = gtkhtml_spell_language_get_code (language); - - submi = gtk_menu_item_new_with_label (lang_name ? lang_name : "???"); - g_object_set_data (G_OBJECT (submi), "spell-entry-checker", checker); - g_signal_connect (submi, "activate", G_CALLBACK (add_to_dictionary), entry); - - gtk_widget_show (submi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), submi); - } - } - - gtk_widget_show_all (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - /* - Ignore All */ - mi = gtk_image_menu_item_new_with_label (_("Ignore All")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU)); - g_signal_connect (mi, "activate", G_CALLBACK (ignore_all), entry); - gtk_widget_show_all (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - return topmenu; -} - -static void -spell_entry_add_suggestions_menu (ESpellEntry *entry, - GtkMenu *menu, - const gchar *word) -{ - GtkWidget *icon, *mi; - - g_return_if_fail (menu != NULL); - g_return_if_fail (word != NULL); - - /* separator */ - mi = gtk_separator_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - - /* Above the separator, show the suggestions menu */ - icon = gtk_image_new_from_stock (GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU); - mi = gtk_image_menu_item_new_with_label (_("Spelling Suggestions")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), icon); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), build_spelling_menu (entry, word)); - - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); -} - -static gboolean -spell_entry_popup_menu (ESpellEntry *entry) -{ - /* Menu popped up from a keybinding (menu key or <shift>+F10). Use - * the cursor position as the mark position */ - entry->priv->mark_character = gtk_editable_get_position (GTK_EDITABLE (entry)); - - return FALSE; -} - -static void -spell_entry_populate_popup (ESpellEntry *entry, - GtkMenu *menu, - gpointer data) -{ - gint start, end; - gchar *word; - - if (!entry->priv->checkers) - return; - - get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character); - if (start == end) - return; - - if (!word_misspelled (entry, start, end)) - return; - - word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); - g_return_if_fail (word != NULL); - - spell_entry_add_suggestions_menu (entry, menu, word); - - g_free (word); -} - -static void -spell_entry_changed (GtkEditable *editable) -{ - ESpellEntry *entry = E_SPELL_ENTRY (editable); - - if (!entry->priv->checkers) - return; - - if (entry->priv->words) { - g_strfreev (entry->priv->words); - g_free (entry->priv->word_starts); - g_free (entry->priv->word_ends); - } - entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends); - spell_entry_recheck_all (entry); -} - -static void -spell_entry_notify_scroll_offset (ESpellEntry *spell_entry) -{ - g_return_if_fail (spell_entry != NULL); - - g_object_get (G_OBJECT (spell_entry), "scroll-offset", &spell_entry->priv->entry_scroll_offset, NULL); -} - -static GList * -spell_entry_load_spell_languages (void) -{ - GSettings *settings; - GList *spell_languages = NULL; - gchar **strv; - gint ii; - - /* Ask GSettings for a list of spell check language codes. */ - settings = g_settings_new ("org.gnome.evolution.mail"); - strv = g_settings_get_strv (settings, "composer-spell-languages"); - g_object_unref (settings); - - /* Convert the codes to spell language structs. */ - for (ii = 0; strv[ii] != NULL; ii++) { - gchar *language_code = strv[ii]; - const GtkhtmlSpellLanguage *language; - - language = gtkhtml_spell_language_lookup (language_code); - if (language != NULL) - spell_languages = g_list_prepend ( - spell_languages, (gpointer) language); - } - - g_strfreev (strv); - - spell_languages = g_list_reverse (spell_languages); - - /* Pick a default spell language if it came back empty. */ - if (spell_languages == NULL) { - const GtkhtmlSpellLanguage *language; - - language = gtkhtml_spell_language_lookup (NULL); - - if (language) { - spell_languages = g_list_prepend ( - spell_languages, (gpointer) language); - } - } - - return spell_languages; -} - -static void -spell_entry_settings_changed (ESpellEntry *spell_entry, - const gchar *key) -{ - GList *languages; - - g_return_if_fail (spell_entry != NULL); - - if (spell_entry->priv->custom_checkers) - return; - - if (key && !g_str_equal (key, "composer-spell-languages")) - return; - - languages = spell_entry_load_spell_languages (); - e_spell_entry_set_languages (spell_entry, languages); - g_list_free (languages); - - spell_entry->priv->custom_checkers = FALSE; -} - -static gint -spell_entry_find_position (ESpellEntry *spell_entry, - gint x) -{ - PangoLayout *layout; - PangoLayoutLine *line; - gint index; - gint pos; - gint trailing; - const gchar *text; - GtkEntry *entry = GTK_ENTRY (spell_entry); - - layout = gtk_entry_get_layout (entry); - text = pango_layout_get_text (layout); - - line = pango_layout_get_lines_readonly (layout)->data; - pango_layout_line_x_to_index (line, x * PANGO_SCALE, &index, &trailing); - - pos = g_utf8_pointer_to_offset (text, text + index); - pos += trailing; - - return pos; -} - -static gboolean -e_spell_entry_draw (GtkWidget *widget, - cairo_t *cr) -{ - ESpellEntry *spell_entry = E_SPELL_ENTRY (widget); - GtkEntry *entry = GTK_ENTRY (widget); - PangoLayout *layout; - - layout = gtk_entry_get_layout (entry); - pango_layout_set_attributes (layout, spell_entry->priv->attr_list); - - return GTK_WIDGET_CLASS (e_spell_entry_parent_class)->draw (widget, cr); -} - -static gboolean -e_spell_entry_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - ESpellEntry *spell_entry = E_SPELL_ENTRY (widget); - - spell_entry->priv->mark_character = spell_entry_find_position ( - spell_entry, event->x + spell_entry->priv->entry_scroll_offset); - - return GTK_WIDGET_CLASS (e_spell_entry_parent_class)->button_press_event (widget, event); -} - -static void -spell_entry_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CHECKING_ENABLED: - e_spell_entry_set_checking_enabled ( - E_SPELL_ENTRY (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -spell_entry_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CHECKING_ENABLED: - g_value_set_boolean ( - value, - e_spell_entry_get_checking_enabled ( - E_SPELL_ENTRY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_spell_entry_init (ESpellEntry *spell_entry) -{ - spell_entry->priv = E_SPELL_ENTRY_GET_PRIVATE (spell_entry); - spell_entry->priv->attr_list = pango_attr_list_new (); - spell_entry->priv->checkers = NULL; - spell_entry->priv->checking_enabled = TRUE; - - g_signal_connect (spell_entry, "popup-menu", G_CALLBACK (spell_entry_popup_menu), NULL); - g_signal_connect (spell_entry, "populate-popup", G_CALLBACK (spell_entry_populate_popup), NULL); - g_signal_connect (spell_entry, "changed", G_CALLBACK (spell_entry_changed), NULL); - g_signal_connect (spell_entry, "notify::scroll-offset", G_CALLBACK (spell_entry_notify_scroll_offset), NULL); - - /* listen for languages changes */ - spell_entry->priv->settings = g_settings_new ("org.gnome.evolution.mail"); - g_signal_connect_swapped (spell_entry->priv->settings, "changed", G_CALLBACK (spell_entry_settings_changed), spell_entry); - - /* load current settings */ - spell_entry_settings_changed (spell_entry, NULL); -} - -static void -e_spell_entry_finalize (GObject *object) -{ - ESpellEntry *entry; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_SPELL_ENTRY (object)); - - entry = E_SPELL_ENTRY (object); - - if (entry->priv->settings) - g_object_unref (entry->priv->settings); - if (entry->priv->checkers) - g_slist_free_full (entry->priv->checkers, g_object_unref); - if (entry->priv->attr_list) - pango_attr_list_unref (entry->priv->attr_list); - if (entry->priv->words) - g_strfreev (entry->priv->words); - if (entry->priv->word_starts) - g_free (entry->priv->word_starts); - if (entry->priv->word_ends) - g_free (entry->priv->word_ends); - - G_OBJECT_CLASS (e_spell_entry_parent_class)->finalize (object); -} - -static void -e_spell_entry_class_init (ESpellEntryClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (ESpellEntryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = spell_entry_set_property; - object_class->get_property = spell_entry_get_property; - object_class->finalize = e_spell_entry_finalize; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->draw = e_spell_entry_draw; - widget_class->button_press_event = e_spell_entry_button_press; - - g_object_class_install_property ( - object_class, - PROP_CHECKING_ENABLED, - g_param_spec_boolean ( - "checking-enabled", - "checking enabled", - "Spell Checking is Enabled", - TRUE, - G_PARAM_READWRITE)); -} - -GtkWidget * -e_spell_entry_new (void) -{ - return g_object_new (E_TYPE_SPELL_ENTRY, NULL); -} - -/* 'languages' consists of 'const GtkhtmlSpellLanguage *' */ -void -e_spell_entry_set_languages (ESpellEntry *spell_entry, - GList *languages) -{ - GList *iter; - - g_return_if_fail (spell_entry != NULL); - - spell_entry->priv->custom_checkers = TRUE; - - if (spell_entry->priv->checkers) - g_slist_free_full (spell_entry->priv->checkers, g_object_unref); - spell_entry->priv->checkers = NULL; - - for (iter = languages; iter; iter = g_list_next (iter)) { - const GtkhtmlSpellLanguage *language = iter->data; - - if (language) - spell_entry->priv->checkers = g_slist_prepend ( - spell_entry->priv->checkers, - gtkhtml_spell_checker_new (language)); - } - - spell_entry->priv->checkers = g_slist_reverse (spell_entry->priv->checkers); - - if (gtk_widget_get_realized (GTK_WIDGET (spell_entry))) - spell_entry_recheck_all (spell_entry); -} - -gboolean -e_spell_entry_get_checking_enabled (ESpellEntry *spell_entry) -{ - g_return_val_if_fail (spell_entry != NULL, FALSE); - - return spell_entry->priv->checking_enabled; -} - -void -e_spell_entry_set_checking_enabled (ESpellEntry *spell_entry, - gboolean enable_checking) -{ - g_return_if_fail (spell_entry != NULL); - - if (spell_entry->priv->checking_enabled == enable_checking) - return; - - spell_entry->priv->checking_enabled = enable_checking; - spell_entry_recheck_all (spell_entry); - - g_object_notify (G_OBJECT (spell_entry), "checking-enabled"); - -} diff --git a/widgets/misc/e-spell-entry.h b/widgets/misc/e-spell-entry.h deleted file mode 100644 index 2d6aabad95..0000000000 --- a/widgets/misc/e-spell-entry.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * e-spell-entry.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_SPELL_ENTRY_H -#define E_SPELL_ENTRY_H - -#include <gtk/gtk.h> - -#define E_TYPE_SPELL_ENTRY (e_spell_entry_get_type()) -#define E_SPELL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), E_TYPE_SPELL_ENTRY, ESpellEntry)) -#define E_SPELL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), E_TYPE_SPELL_ENTRY, ESpellEntryClass)) -#define E_IS_SPELL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), E_TYPE_SPELL_ENTRY)) -#define E_IS_SPELL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), E_TYPE_SPELL_ENTRY)) -#define E_SPELL_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), E_TYPE_SPELL_ENTRY, ESpellEntryClass)) - -G_BEGIN_DECLS - -typedef struct _ESpellEntry ESpellEntry; -typedef struct _ESpellEntryClass ESpellEntryClass; -typedef struct _ESpellEntryPrivate ESpellEntryPrivate; - -struct _ESpellEntry -{ - GtkEntry parent_object; - - ESpellEntryPrivate *priv; -}; - -struct _ESpellEntryClass -{ - GtkEntryClass parent_class; -}; - -GType e_spell_entry_get_type (void); -GtkWidget * e_spell_entry_new (void); -void e_spell_entry_set_languages (ESpellEntry *spell_entry, - GList *languages); -gboolean e_spell_entry_get_checking_enabled (ESpellEntry *spell_entry); -void e_spell_entry_set_checking_enabled (ESpellEntry *spell_entry, - gboolean enable_checking); - -G_END_DECLS - -#endif /* E_SPELL_ENTRY_H */ diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c deleted file mode 100644 index 68b8a8fac0..0000000000 --- a/widgets/misc/e-url-entry.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * JP Rosevear <jpr@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include "e-url-entry.h" -#include "e-util/e-util.h" - -#define E_URL_ENTRY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_URL_ENTRY, EUrlEntryPrivate)) - -struct _EUrlEntryPrivate { - GtkWidget *entry; - GtkWidget *button; -}; - -static void button_clicked_cb (GtkWidget *widget, gpointer data); -static void entry_changed_cb (GtkEditable *editable, gpointer data); - -static gboolean mnemonic_activate (GtkWidget *widget, gboolean group_cycling); - -G_DEFINE_TYPE ( - EUrlEntry, - e_url_entry, - GTK_TYPE_HBOX) - -static void -e_url_entry_class_init (EUrlEntryClass *class) -{ - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EUrlEntryPrivate)); - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->mnemonic_activate = mnemonic_activate; -} - -static void -e_url_entry_init (EUrlEntry *url_entry) -{ - GtkWidget *pixmap; - - url_entry->priv = E_URL_ENTRY_GET_PRIVATE (url_entry); - - url_entry->priv->entry = gtk_entry_new (); - gtk_box_pack_start ( - GTK_BOX (url_entry), url_entry->priv->entry, TRUE, TRUE, 0); - url_entry->priv->button = gtk_button_new (); - gtk_widget_set_sensitive (url_entry->priv->button, FALSE); - gtk_box_pack_start ( - GTK_BOX (url_entry), url_entry->priv->button, FALSE, FALSE, 0); - atk_object_set_name ( - gtk_widget_get_accessible (url_entry->priv->button), - _("Click here to go to URL")); - pixmap = gtk_image_new_from_icon_name ("go-jump", GTK_ICON_SIZE_BUTTON); - gtk_container_add (GTK_CONTAINER (url_entry->priv->button), pixmap); - gtk_widget_show (pixmap); - - gtk_widget_show (url_entry->priv->button); - gtk_widget_show (url_entry->priv->entry); - - g_signal_connect ( - url_entry->priv->button, "clicked", - G_CALLBACK (button_clicked_cb), url_entry); - g_signal_connect ( - url_entry->priv->entry, "changed", - G_CALLBACK (entry_changed_cb), url_entry); -} - -/* GtkWidget::mnemonic_activate() handler for the EUrlEntry */ -static gboolean -mnemonic_activate (GtkWidget *widget, - gboolean group_cycling) -{ - EUrlEntry *url_entry; - EUrlEntryPrivate *priv; - - url_entry = E_URL_ENTRY (widget); - priv = url_entry->priv; - - return gtk_widget_mnemonic_activate (priv->entry, group_cycling); -} - -GtkWidget * -e_url_entry_new (void) -{ - return g_object_new (E_TYPE_URL_ENTRY, NULL); -} - -GtkWidget * -e_url_entry_get_entry (EUrlEntry *url_entry) -{ - EUrlEntryPrivate *priv; - - g_return_val_if_fail (url_entry != NULL, NULL); - g_return_val_if_fail (E_IS_URL_ENTRY (url_entry), NULL); - - priv = url_entry->priv; - - return priv->entry; -} - -static void -button_clicked_cb (GtkWidget *widget, - gpointer data) -{ - EUrlEntry *url_entry; - EUrlEntryPrivate *priv; - const gchar *uri; - - url_entry = E_URL_ENTRY (data); - priv = url_entry->priv; - - uri = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - - /* FIXME Pass a parent window. */ - e_show_uri (NULL, uri); -} - -static void -entry_changed_cb (GtkEditable *editable, - gpointer data) -{ - EUrlEntry *url_entry; - EUrlEntryPrivate *priv; - const gchar *url; - - url_entry = E_URL_ENTRY (data); - priv = url_entry->priv; - - url = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - gtk_widget_set_sensitive (priv->button, url != NULL && *url != '\0'); -} diff --git a/widgets/misc/e-url-entry.h b/widgets/misc/e-url-entry.h deleted file mode 100644 index 2393f823ac..0000000000 --- a/widgets/misc/e-url-entry.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * JP Rosevear <jpr@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_URL_ENTRY_H_ -#define _E_URL_ENTRY_H_ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define E_TYPE_URL_ENTRY (e_url_entry_get_type ()) -#define E_URL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_URL_ENTRY, EUrlEntry)) -#define E_URL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_URL_ENTRY, EUrlEntryClass)) -#define E_IS_URL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_URL_ENTRY)) -#define E_IS_URL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_URL_ENTRY)) - -typedef struct _EUrlEntry EUrlEntry; -typedef struct _EUrlEntryPrivate EUrlEntryPrivate; -typedef struct _EUrlEntryClass EUrlEntryClass; - -struct _EUrlEntry { - GtkBox parent; - - EUrlEntryPrivate *priv; -}; - -struct _EUrlEntryClass { - GtkBoxClass parent_class; -}; - -GType e_url_entry_get_type (void); -GtkWidget *e_url_entry_new (void); -GtkWidget *e_url_entry_get_entry (EUrlEntry *url_entry); - -G_END_DECLS - -#endif /* _E_URL_ENTRY_H_ */ diff --git a/widgets/misc/e-web-view-gtkhtml.c b/widgets/misc/e-web-view-gtkhtml.c deleted file mode 100644 index fddbd9ee90..0000000000 --- a/widgets/misc/e-web-view-gtkhtml.c +++ /dev/null @@ -1,2318 +0,0 @@ -/* - * e-web-view-gtkhtml.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-web-view-gtkhtml.h" - -#include <string.h> -#include <glib/gi18n-lib.h> - -#include <camel/camel.h> -#include <libebackend/libebackend.h> - -#include <e-util/e-util.h> -#include <e-util/e-plugin-ui.h> -#include <libevolution-utils/e-alert-dialog.h> -#include <libevolution-utils/e-alert-sink.h> - -#include "e-popup-action.h" -#include "e-selectable.h" - -#define E_WEB_VIEW_GTKHTML_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_WEB_VIEW_GTKHTML, EWebViewGtkHTMLPrivate)) - -typedef struct _EWebViewGtkHTMLRequest EWebViewGtkHTMLRequest; - -struct _EWebViewGtkHTMLPrivate { - GList *requests; - GtkUIManager *ui_manager; - gchar *selected_uri; - GdkPixbufAnimation *cursor_image; - - GtkAction *open_proxy; - GtkAction *print_proxy; - GtkAction *save_as_proxy; - - GtkTargetList *copy_target_list; - GtkTargetList *paste_target_list; - - /* Lockdown Options */ - guint disable_printing : 1; - guint disable_save_to_disk : 1; -}; - -struct _EWebViewGtkHTMLRequest { - GFile *file; - EWebViewGtkHTML *web_view; - GCancellable *cancellable; - GInputStream *input_stream; - GtkHTMLStream *output_stream; - gchar buffer[4096]; -}; - -enum { - PROP_0, - PROP_ANIMATE, - PROP_CARET_MODE, - PROP_COPY_TARGET_LIST, - PROP_DISABLE_PRINTING, - PROP_DISABLE_SAVE_TO_DISK, - PROP_EDITABLE, - PROP_INLINE_SPELLING, - PROP_MAGIC_LINKS, - PROP_MAGIC_SMILEYS, - PROP_OPEN_PROXY, - PROP_PASTE_TARGET_LIST, - PROP_PRINT_PROXY, - PROP_SAVE_AS_PROXY, - PROP_SELECTED_URI, - PROP_CURSOR_IMAGE -}; - -enum { - COPY_CLIPBOARD, - CUT_CLIPBOARD, - PASTE_CLIPBOARD, - POPUP_EVENT, - STATUS_MESSAGE, - STOP_LOADING, - UPDATE_ACTIONS, - PROCESS_MAILTO, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <menuitem action='copy-clipboard'/>" -" <separator/>" -" <placeholder name='custom-actions-1'>" -" <menuitem action='open'/>" -" <menuitem action='save-as'/>" -" <menuitem action='http-open'/>" -" <menuitem action='send-message'/>" -" <menuitem action='print'/>" -" </placeholder>" -" <placeholder name='custom-actions-2'>" -" <menuitem action='uri-copy'/>" -" <menuitem action='mailto-copy'/>" -" <menuitem action='image-copy'/>" -" </placeholder>" -" <placeholder name='custom-actions-3'/>" -" <separator/>" -" <menuitem action='select-all'/>" -" </popup>" -"</ui>"; - -/* Forward Declarations */ -static void e_web_view_gtkhtml_alert_sink_init (EAlertSinkInterface *interface); -static void e_web_view_gtkhtml_selectable_init (ESelectableInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EWebViewGtkHTML, - e_web_view_gtkhtml, - GTK_TYPE_HTML, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL) - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_web_view_gtkhtml_alert_sink_init) - G_IMPLEMENT_INTERFACE ( - E_TYPE_SELECTABLE, - e_web_view_gtkhtml_selectable_init)) - -static EWebViewGtkHTMLRequest * -web_view_gtkhtml_request_new (EWebViewGtkHTML *web_view, - const gchar *uri, - GtkHTMLStream *stream) -{ - EWebViewGtkHTMLRequest *request; - GList *list; - - request = g_slice_new (EWebViewGtkHTMLRequest); - - /* Try to detect file paths posing as URIs. */ - if (*uri == '/') - request->file = g_file_new_for_path (uri); - else - request->file = g_file_new_for_uri (uri); - - request->web_view = g_object_ref (web_view); - request->cancellable = g_cancellable_new (); - request->input_stream = NULL; - request->output_stream = stream; - - list = request->web_view->priv->requests; - list = g_list_prepend (list, request); - request->web_view->priv->requests = list; - - return request; -} - -static void -web_view_gtkhtml_request_free (EWebViewGtkHTMLRequest *request) -{ - GList *list; - - list = request->web_view->priv->requests; - list = g_list_remove (list, request); - request->web_view->priv->requests = list; - - g_object_unref (request->file); - g_object_unref (request->web_view); - g_object_unref (request->cancellable); - - if (request->input_stream != NULL) - g_object_unref (request->input_stream); - - g_slice_free (EWebViewGtkHTMLRequest, request); -} - -static void -web_view_gtkhtml_request_cancel (EWebViewGtkHTMLRequest *request) -{ - g_cancellable_cancel (request->cancellable); -} - -static gboolean -web_view_gtkhtml_request_check_for_error (EWebViewGtkHTMLRequest *request, - GError *error) -{ - GtkHTML *html; - GtkHTMLStream *stream; - - if (error == NULL) - return FALSE; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { - /* use this error, but do not close the stream */ - g_error_free (error); - return TRUE; - } - - /* XXX Should we log errors that are not cancellations? */ - - html = GTK_HTML (request->web_view); - stream = request->output_stream; - - gtk_html_end (html, stream, GTK_HTML_STREAM_ERROR); - web_view_gtkhtml_request_free (request); - g_error_free (error); - - return TRUE; -} - -static void -web_view_gtkhtml_request_stream_read_cb (GInputStream *input_stream, - GAsyncResult *result, - EWebViewGtkHTMLRequest *request) -{ - gssize bytes_read; - GError *error = NULL; - - bytes_read = g_input_stream_read_finish (input_stream, result, &error); - - if (web_view_gtkhtml_request_check_for_error (request, error)) - return; - - if (bytes_read == 0) { - gtk_html_end ( - GTK_HTML (request->web_view), - request->output_stream, GTK_HTML_STREAM_OK); - web_view_gtkhtml_request_free (request); - return; - } - - gtk_html_write ( - GTK_HTML (request->web_view), - request->output_stream, request->buffer, bytes_read); - - g_input_stream_read_async ( - request->input_stream, request->buffer, - sizeof (request->buffer), G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_stream_read_cb, request); -} - -static void -web_view_gtkhtml_request_read_cb (GFile *file, - GAsyncResult *result, - EWebViewGtkHTMLRequest *request) -{ - GFileInputStream *input_stream; - GError *error = NULL; - - /* Input stream might be NULL, so don't use cast macro. */ - input_stream = g_file_read_finish (file, result, &error); - request->input_stream = (GInputStream *) input_stream; - - if (web_view_gtkhtml_request_check_for_error (request, error)) - return; - - g_input_stream_read_async ( - request->input_stream, request->buffer, - sizeof (request->buffer), G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_stream_read_cb, request); -} - -static void -action_copy_clipboard_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_copy_clipboard (web_view); -} - -static void -action_http_open_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - const gchar *uri; - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - e_show_uri (parent, uri); -} - -static void -action_mailto_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - CamelURL *curl; - CamelInternetAddress *inet_addr; - GtkClipboard *clipboard; - const gchar *uri; - gchar *text; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - /* This should work because we checked it in update_actions(). */ - curl = camel_url_new (uri, NULL); - g_return_if_fail (curl != NULL); - - inet_addr = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path); - text = camel_address_format (CAMEL_ADDRESS (inet_addr)); - if (text == NULL || *text == '\0') - text = g_strdup (uri + strlen ("mailto:")); - - g_object_unref (inet_addr); - camel_url_free (curl); - - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - g_free (text); -} - -static void -action_select_all_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_select_all (web_view); -} - -static void -action_send_message_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - const gchar *uri; - gpointer parent; - gboolean handled; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - handled = FALSE; - g_signal_emit (web_view, signals[PROCESS_MAILTO], 0, uri, &handled); - - if (!handled) - e_show_uri (parent, uri); -} - -static void -action_uri_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - GtkClipboard *clipboard; - const gchar *uri; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - gtk_clipboard_set_text (clipboard, uri, -1); - gtk_clipboard_store (clipboard); -} - -static void -action_image_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - GtkClipboard *clipboard; - GdkPixbufAnimation *animation; - GdkPixbuf *pixbuf; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - animation = e_web_view_gtkhtml_get_cursor_image (web_view); - g_return_if_fail (animation != NULL); - - pixbuf = gdk_pixbuf_animation_get_static_image (animation); - if (!pixbuf) - return; - - gtk_clipboard_set_image (clipboard, pixbuf); - gtk_clipboard_store (clipboard); -} - -static GtkActionEntry uri_entries[] = { - - { "uri-copy", - GTK_STOCK_COPY, - N_("_Copy Link Location"), - NULL, - N_("Copy the link to the clipboard"), - G_CALLBACK (action_uri_copy_cb) } -}; - -static GtkActionEntry http_entries[] = { - - { "http-open", - "emblem-web", - N_("_Open Link in Browser"), - NULL, - N_("Open the link in a web browser"), - G_CALLBACK (action_http_open_cb) } -}; - -static GtkActionEntry mailto_entries[] = { - - { "mailto-copy", - GTK_STOCK_COPY, - N_("_Copy Email Address"), - NULL, - N_("Copy the email address to the clipboard"), - G_CALLBACK (action_mailto_copy_cb) }, - - { "send-message", - "mail-message-new", - N_("_Send New Message To..."), - NULL, - N_("Send a mail message to this address"), - G_CALLBACK (action_send_message_cb) } -}; - -static GtkActionEntry image_entries[] = { - - { "image-copy", - GTK_STOCK_COPY, - N_("_Copy Image"), - NULL, - N_("Copy the image to the clipboard"), - G_CALLBACK (action_image_copy_cb) } -}; - -static GtkActionEntry selection_entries[] = { - - { "copy-clipboard", - GTK_STOCK_COPY, - NULL, - NULL, - N_("Copy the selection"), - G_CALLBACK (action_copy_clipboard_cb) }, -}; - -static GtkActionEntry standard_entries[] = { - - { "select-all", - GTK_STOCK_SELECT_ALL, - NULL, - NULL, - N_("Select all text and images"), - G_CALLBACK (action_select_all_cb) } -}; - -static gboolean -web_view_gtkhtml_button_press_event_cb (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame) -{ - gboolean event_handled = FALSE; - gchar *uri = NULL; - - if (event) { - GdkPixbufAnimation *anim; - - if (frame == NULL) - frame = GTK_HTML (web_view); - - anim = gtk_html_get_image_at (frame, event->x, event->y); - e_web_view_gtkhtml_set_cursor_image (web_view, anim); - if (anim != NULL) - g_object_unref (anim); - } - - if (event != NULL && event->button != 3) - return FALSE; - - /* Only extract a URI if no selection is active. Selected text - * implies the user is more likely to want to copy the selection - * to the clipboard than open a link within the selection. */ - if (!e_web_view_gtkhtml_is_selection_active (web_view)) - uri = e_web_view_gtkhtml_extract_uri (web_view, event, frame); - - if (uri != NULL && g_str_has_prefix (uri, "##")) { - g_free (uri); - return FALSE; - } - - g_signal_emit ( - web_view, signals[POPUP_EVENT], 0, - event, uri, &event_handled); - - g_free (uri); - - return event_handled; -} - -static void -web_view_gtkhtml_menu_item_select_cb (EWebViewGtkHTML *web_view, - GtkWidget *widget) -{ - GtkAction *action; - GtkActivatable *activatable; - const gchar *tooltip; - - activatable = GTK_ACTIVATABLE (widget); - action = gtk_activatable_get_related_action (activatable); - tooltip = gtk_action_get_tooltip (action); - - if (tooltip == NULL) - return; - - e_web_view_gtkhtml_status_message (web_view, tooltip); -} - -static void -web_view_gtkhtml_menu_item_deselect_cb (EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_status_message (web_view, NULL); -} - -static void -web_view_gtkhtml_connect_proxy_cb (EWebViewGtkHTML *web_view, - GtkAction *action, - GtkWidget *proxy) -{ - if (!GTK_IS_MENU_ITEM (proxy)) - return; - - g_signal_connect_swapped ( - proxy, "select", - G_CALLBACK (web_view_gtkhtml_menu_item_select_cb), web_view); - - g_signal_connect_swapped ( - proxy, "deselect", - G_CALLBACK (web_view_gtkhtml_menu_item_deselect_cb), web_view); -} - -static void -web_view_gtkhtml_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ANIMATE: - e_web_view_gtkhtml_set_animate ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_CARET_MODE: - e_web_view_gtkhtml_set_caret_mode ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_DISABLE_PRINTING: - e_web_view_gtkhtml_set_disable_printing ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - e_web_view_gtkhtml_set_disable_save_to_disk ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_web_view_gtkhtml_set_editable ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_INLINE_SPELLING: - e_web_view_gtkhtml_set_inline_spelling ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_LINKS: - e_web_view_gtkhtml_set_magic_links ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_SMILEYS: - e_web_view_gtkhtml_set_magic_smileys ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_OPEN_PROXY: - e_web_view_gtkhtml_set_open_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_PRINT_PROXY: - e_web_view_gtkhtml_set_print_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_SAVE_AS_PROXY: - e_web_view_gtkhtml_set_save_as_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_SELECTED_URI: - e_web_view_gtkhtml_set_selected_uri ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_string (value)); - return; - case PROP_CURSOR_IMAGE: - e_web_view_gtkhtml_set_cursor_image ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_gtkhtml_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ANIMATE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_animate ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_CARET_MODE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_caret_mode ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_COPY_TARGET_LIST: - g_value_set_boxed ( - value, e_web_view_gtkhtml_get_copy_target_list ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_DISABLE_PRINTING: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_disable_printing ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_disable_save_to_disk ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_editable ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_INLINE_SPELLING: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_inline_spelling ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_MAGIC_LINKS: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_magic_links ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_MAGIC_SMILEYS: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_magic_smileys ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_OPEN_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_open_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_PASTE_TARGET_LIST: - g_value_set_boxed ( - value, e_web_view_gtkhtml_get_paste_target_list ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_PRINT_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_print_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_SAVE_AS_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_save_as_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_SELECTED_URI: - g_value_set_string ( - value, e_web_view_gtkhtml_get_selected_uri ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_CURSOR_IMAGE: - g_value_set_object ( - value, e_web_view_gtkhtml_get_cursor_image ( - E_WEB_VIEW_GTKHTML (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_gtkhtml_dispose (GObject *object) -{ - EWebViewGtkHTMLPrivate *priv; - - priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (object); - - if (priv->ui_manager != NULL) { - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - } - - if (priv->open_proxy != NULL) { - g_object_unref (priv->open_proxy); - priv->open_proxy = NULL; - } - - if (priv->print_proxy != NULL) { - g_object_unref (priv->print_proxy); - priv->print_proxy = NULL; - } - - if (priv->save_as_proxy != NULL) { - g_object_unref (priv->save_as_proxy); - priv->save_as_proxy = NULL; - } - - if (priv->copy_target_list != NULL) { - gtk_target_list_unref (priv->copy_target_list); - priv->copy_target_list = NULL; - } - - if (priv->paste_target_list != NULL) { - gtk_target_list_unref (priv->paste_target_list); - priv->paste_target_list = NULL; - } - - if (priv->cursor_image != NULL) { - g_object_unref (priv->cursor_image); - priv->cursor_image = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->dispose (object); -} - -static void -web_view_gtkhtml_finalize (GObject *object) -{ - EWebViewGtkHTMLPrivate *priv; - - priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (object); - - /* All URI requests should be complete or cancelled by now. */ - if (priv->requests != NULL) - g_warning ("Finalizing EWebViewGtkHTML with active URI requests"); - - g_free (priv->selected_uri); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->finalize (object); -} - -static void -web_view_gtkhtml_constructed (GObject *object) -{ -#ifndef G_OS_WIN32 - GSettings *settings; - - settings = g_settings_new ("org.gnome.desktop.lockdown"); - - g_settings_bind ( - settings, "disable-printing", - object, "disable-printing", - G_SETTINGS_BIND_GET); - - g_settings_bind ( - settings, "disable-save-to-disk", - object, "disable-save-to-disk", - G_SETTINGS_BIND_GET); - - g_object_unref (settings); -#endif - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->constructed (object); -} - -static gboolean -web_view_gtkhtml_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - GtkWidgetClass *widget_class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (widget); - - if (web_view_gtkhtml_button_press_event_cb (web_view, event, NULL)) - return TRUE; - - /* Chain up to parent's button_press_event() method. */ - widget_class = GTK_WIDGET_CLASS (e_web_view_gtkhtml_parent_class); - return widget_class->button_press_event (widget, event); -} - -static gboolean -web_view_gtkhtml_scroll_event (GtkWidget *widget, - GdkEventScroll *event) -{ - if (event->state & GDK_CONTROL_MASK) { - GdkScrollDirection direction = event->direction; - - #if GTK_CHECK_VERSION(3,3,18) - if (direction == GDK_SCROLL_SMOOTH) { - static gdouble total_delta_y = 0.0; - - total_delta_y += event->delta_y; - - if (total_delta_y >= 1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_DOWN; - } else if (total_delta_y <= -1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_UP; - } else { - return FALSE; - } - } - #endif - - switch (direction) { - case GDK_SCROLL_UP: - gtk_html_zoom_in (GTK_HTML (widget)); - return TRUE; - case GDK_SCROLL_DOWN: - gtk_html_zoom_out (GTK_HTML (widget)); - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -web_view_gtkhtml_url_requested (GtkHTML *html, - const gchar *uri, - GtkHTMLStream *stream) -{ - EWebViewGtkHTMLRequest *request; - - request = web_view_gtkhtml_request_new (E_WEB_VIEW_GTKHTML (html), uri, stream); - - g_file_read_async ( - request->file, G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_read_cb, request); -} - -static void -web_view_gtkhtml_gtkhtml_link_clicked (GtkHTML *html, - const gchar *uri) -{ - EWebViewGtkHTMLClass *class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (html); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->link_clicked != NULL); - - class->link_clicked (web_view, uri); -} - -static void -web_view_gtkhtml_on_url (GtkHTML *html, - const gchar *uri) -{ - EWebViewGtkHTMLClass *class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (html); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->hovering_over_link != NULL); - - /* XXX WebKit would supply a title here. */ - class->hovering_over_link (web_view, NULL, uri); -} - -static void -web_view_gtkhtml_iframe_created (GtkHTML *html, - GtkHTML *iframe) -{ - g_signal_connect_swapped ( - iframe, "button-press-event", - G_CALLBACK (web_view_gtkhtml_button_press_event_cb), html); -} - -static gchar * -web_view_gtkhtml_extract_uri (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *html) -{ - gchar *uri; - - if (event != NULL) - uri = gtk_html_get_url_at (html, event->x, event->y); - else - uri = gtk_html_get_cursor_url (html); - - return uri; -} - -static void -web_view_gtkhtml_hovering_over_link (EWebViewGtkHTML *web_view, - const gchar *title, - const gchar *uri) -{ - CamelInternetAddress *address; - CamelURL *curl; - const gchar *format = NULL; - gchar *message = NULL; - gchar *who; - - if (uri == NULL || *uri == '\0') - goto exit; - - if (g_str_has_prefix (uri, "mailto:")) - format = _("Click to mail %s"); - else if (g_str_has_prefix (uri, "callto:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "h323:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "sip:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "##")) - message = g_strdup (_("Click to hide/unhide addresses")); - else - message = g_strdup_printf (_("Click to open %s"), uri); - - if (format == NULL) - goto exit; - - /* XXX Use something other than Camel here. Surely - * there's other APIs around that can do this. */ - curl = camel_url_new (uri, NULL); - address = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (address), curl->path); - who = camel_address_format (CAMEL_ADDRESS (address)); - g_object_unref (address); - camel_url_free (curl); - - if (who == NULL) - who = g_strdup (strchr (uri, ':') + 1); - - message = g_strdup_printf (format, who); - - g_free (who); - -exit: - e_web_view_gtkhtml_status_message (web_view, message); - - g_free (message); -} - -static void -web_view_gtkhtml_link_clicked (EWebViewGtkHTML *web_view, - const gchar *uri) -{ - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - e_show_uri (parent, uri); -} - -static void -web_view_gtkhtml_load_string (EWebViewGtkHTML *web_view, - const gchar *string) -{ - if (string != NULL && *string != '\0') - gtk_html_load_from_string (GTK_HTML (web_view), string, -1); - else - e_web_view_gtkhtml_clear (web_view); -} - -static void -web_view_gtkhtml_copy_clipboard (EWebViewGtkHTML *web_view) -{ - gtk_html_command (GTK_HTML (web_view), "copy"); -} - -static void -web_view_gtkhtml_cut_clipboard (EWebViewGtkHTML *web_view) -{ - if (e_web_view_gtkhtml_get_editable (web_view)) - gtk_html_command (GTK_HTML (web_view), "cut"); -} - -static void -web_view_gtkhtml_paste_clipboard (EWebViewGtkHTML *web_view) -{ - if (e_web_view_gtkhtml_get_editable (web_view)) - gtk_html_command (GTK_HTML (web_view), "paste"); -} - -static gboolean -web_view_gtkhtml_popup_event (EWebViewGtkHTML *web_view, - GdkEventButton *event, - const gchar *uri) -{ - e_web_view_gtkhtml_set_selected_uri (web_view, uri); - e_web_view_gtkhtml_show_popup_menu (web_view, event, NULL, NULL); - - return TRUE; -} - -static void -web_view_gtkhtml_stop_loading (EWebViewGtkHTML *web_view) -{ - g_list_foreach ( - web_view->priv->requests, (GFunc) - web_view_gtkhtml_request_cancel, NULL); - - gtk_html_stop (GTK_HTML (web_view)); -} - -static void -web_view_gtkhtml_update_actions (EWebViewGtkHTML *web_view) -{ - GtkActionGroup *action_group; - gboolean have_selection; - gboolean scheme_is_http = FALSE; - gboolean scheme_is_mailto = FALSE; - gboolean uri_is_valid = FALSE; - gboolean has_cursor_image; - gboolean visible; - const gchar *group_name; - const gchar *uri; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - have_selection = e_web_view_gtkhtml_is_selection_active (web_view); - has_cursor_image = e_web_view_gtkhtml_get_cursor_image (web_view) != NULL; - - /* Parse the URI early so we know if the actions will work. */ - if (uri != NULL) { - CamelURL *curl; - - curl = camel_url_new (uri, NULL); - uri_is_valid = (curl != NULL); - camel_url_free (curl); - - scheme_is_http = - (g_ascii_strncasecmp (uri, "http:", 5) == 0) || - (g_ascii_strncasecmp (uri, "https:", 6) == 0); - - scheme_is_mailto = - (g_ascii_strncasecmp (uri, "mailto:", 7) == 0); - } - - /* Allow copying the URI even if it's malformed. */ - group_name = "uri"; - visible = (uri != NULL) && !scheme_is_mailto; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "http"; - visible = uri_is_valid && scheme_is_http; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "mailto"; - visible = uri_is_valid && scheme_is_mailto; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "image"; - visible = has_cursor_image; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "selection"; - visible = have_selection; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "standard"; - visible = (uri == NULL); - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-printing"; - visible = (uri == NULL) && !web_view->priv->disable_printing; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-save-to-disk"; - visible = (uri == NULL) && !web_view->priv->disable_save_to_disk; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); -} - -static void -web_view_gtkhtml_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - GtkIconInfo *icon_info; - EWebViewGtkHTML *web_view; - GtkWidget *dialog; - GString *buffer; - const gchar *icon_name = NULL; - const gchar *filename; - gpointer parent; - gchar *icon_uri; - gint size = 0; - GError *error = NULL; - - web_view = E_WEB_VIEW_GTKHTML (alert_sink); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - /* We use equivalent named icons instead of stock IDs, - * since it's easier to get the filename of the icon. */ - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - icon_name = "dialog-information"; - break; - - case GTK_MESSAGE_WARNING: - icon_name = "dialog-warning"; - break; - - case GTK_MESSAGE_ERROR: - icon_name = "dialog-error"; - break; - - default: - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - return; - } - - gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, NULL); - - icon_info = gtk_icon_theme_lookup_icon ( - gtk_icon_theme_get_default (), - icon_name, size, GTK_ICON_LOOKUP_NO_SVG); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - icon_uri = g_filename_to_uri (filename, NULL, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - buffer = g_string_sized_new (512); - - g_string_append ( - buffer, - "<html>" - "<head>" - "<meta http-equiv=\"content-type\"" - " content=\"text/html; charset=utf-8\">" - "</head>" - "<body>"); - - g_string_append ( - buffer, - "<table bgcolor='#000000' width='100%'" - " cellpadding='1' cellspacing='0'>" - "<tr>" - "<td>" - "<table bgcolor='#dddddd' width='100%' cellpadding='6'>" - "<tr>"); - - g_string_append_printf ( - buffer, - "<tr>" - "<td valign='top'>" - "<img src='%s'/>" - "</td>" - "<td align='left' width='100%%'>" - "<h3>%s</h3>" - "%s" - "</td>" - "</tr>", - icon_uri, - e_alert_get_primary_text (alert), - e_alert_get_secondary_text (alert)); - - g_string_append ( - buffer, - "</table>" - "</td>" - "</tr>" - "</table>" - "</body>" - "</html>"); - - e_web_view_gtkhtml_load_string (web_view, buffer->str); - - g_string_free (buffer, TRUE); - - gtk_icon_info_free (icon_info); - g_free (icon_uri); -} - -static void -web_view_gtkhtml_selectable_update_actions (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets) -{ - EWebViewGtkHTML *web_view; - GtkAction *action; - /*GtkTargetList *target_list;*/ - gboolean can_paste = FALSE; - gboolean editable; - gboolean have_selection; - gboolean sensitive; - const gchar *tooltip; - /*gint ii;*/ - - web_view = E_WEB_VIEW_GTKHTML (selectable); - editable = e_web_view_gtkhtml_get_editable (web_view); - have_selection = e_web_view_gtkhtml_is_selection_active (web_view); - - /* XXX GtkHtml implements its own clipboard instead of using - * GDK_SELECTION_CLIPBOARD, so we don't get notifications - * when the clipboard contents change. The logic below - * is what we would do if GtkHtml worked properly. - * Instead, we need to keep the Paste action sensitive so - * its accelerator overrides GtkHtml's key binding. */ -#if 0 - target_list = e_selectable_get_paste_target_list (selectable); - for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++) - can_paste = gtk_target_list_find ( - target_list, clipboard_targets[ii], NULL); -#endif - can_paste = TRUE; - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - sensitive = editable && have_selection; - tooltip = _("Cut the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - sensitive = have_selection; - tooltip = _("Copy the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - sensitive = editable && can_paste; - tooltip = _("Paste the clipboard"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_select_all_action (focus_tracker); - sensitive = TRUE; - tooltip = _("Select all text and images"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); -} - -static void -web_view_gtkhtml_selectable_cut_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_cut_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_copy_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_copy_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_paste_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_paste_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_select_all (ESelectable *selectable) -{ - e_web_view_gtkhtml_select_all (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -e_web_view_gtkhtml_class_init (EWebViewGtkHTMLClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkHTMLClass *html_class; - - g_type_class_add_private (class, sizeof (EWebViewGtkHTMLPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = web_view_gtkhtml_set_property; - object_class->get_property = web_view_gtkhtml_get_property; - object_class->dispose = web_view_gtkhtml_dispose; - object_class->finalize = web_view_gtkhtml_finalize; - object_class->constructed = web_view_gtkhtml_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->button_press_event = web_view_gtkhtml_button_press_event; - widget_class->scroll_event = web_view_gtkhtml_scroll_event; - - html_class = GTK_HTML_CLASS (class); - html_class->url_requested = web_view_gtkhtml_url_requested; - html_class->link_clicked = web_view_gtkhtml_gtkhtml_link_clicked; - html_class->on_url = web_view_gtkhtml_on_url; - html_class->iframe_created = web_view_gtkhtml_iframe_created; - - class->extract_uri = web_view_gtkhtml_extract_uri; - class->hovering_over_link = web_view_gtkhtml_hovering_over_link; - class->link_clicked = web_view_gtkhtml_link_clicked; - class->load_string = web_view_gtkhtml_load_string; - class->copy_clipboard = web_view_gtkhtml_copy_clipboard; - class->cut_clipboard = web_view_gtkhtml_cut_clipboard; - class->paste_clipboard = web_view_gtkhtml_paste_clipboard; - class->popup_event = web_view_gtkhtml_popup_event; - class->stop_loading = web_view_gtkhtml_stop_loading; - class->update_actions = web_view_gtkhtml_update_actions; - - g_object_class_install_property ( - object_class, - PROP_ANIMATE, - g_param_spec_boolean ( - "animate", - "Animate Images", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CARET_MODE, - g_param_spec_boolean ( - "caret-mode", - "Caret Mode", - NULL, - FALSE, - G_PARAM_READWRITE)); - - /* Inherited from ESelectableInterface */ - g_object_class_override_property ( - object_class, - PROP_COPY_TARGET_LIST, - "copy-target-list"); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_PRINTING, - g_param_spec_boolean ( - "disable-printing", - "Disable Printing", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_SAVE_TO_DISK, - g_param_spec_boolean ( - "disable-save-to-disk", - "Disable Save-to-Disk", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_INLINE_SPELLING, - g_param_spec_boolean ( - "inline-spelling", - "Inline Spelling", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_LINKS, - g_param_spec_boolean ( - "magic-links", - "Magic Links", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_SMILEYS, - g_param_spec_boolean ( - "magic-smileys", - "Magic Smileys", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_OPEN_PROXY, - g_param_spec_object ( - "open-proxy", - "Open Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - /* Inherited from ESelectableInterface */ - g_object_class_override_property ( - object_class, - PROP_PASTE_TARGET_LIST, - "paste-target-list"); - - g_object_class_install_property ( - object_class, - PROP_PRINT_PROXY, - g_param_spec_object ( - "print-proxy", - "Print Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SAVE_AS_PROXY, - g_param_spec_object ( - "save-as-proxy", - "Save As Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTED_URI, - g_param_spec_string ( - "selected-uri", - "Selected URI", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_IMAGE, - g_param_spec_object ( - "cursor-image", - "Image animation at the mouse cursor", - NULL, - GDK_TYPE_PIXBUF_ANIMATION, - G_PARAM_READWRITE)); - - signals[COPY_CLIPBOARD] = g_signal_new ( - "copy-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, copy_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CUT_CLIPBOARD] = g_signal_new ( - "cut-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, cut_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[PASTE_CLIPBOARD] = g_signal_new ( - "paste-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, paste_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[POPUP_EVENT] = g_signal_new ( - "popup-event", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, popup_event), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__BOXED_STRING, - G_TYPE_BOOLEAN, 2, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING); - - signals[STATUS_MESSAGE] = g_signal_new ( - "status-message", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, status_message), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - signals[STOP_LOADING] = g_signal_new ( - "stop-loading", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, stop_loading), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UPDATE_ACTIONS] = g_signal_new ( - "update-actions", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, update_actions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* return TRUE when a signal handler processed the mailto URI */ - signals[PROCESS_MAILTO] = g_signal_new ( - "process-mailto", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, process_mailto), - NULL, NULL, - e_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, G_TYPE_STRING); -} - -static void -e_web_view_gtkhtml_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = web_view_gtkhtml_submit_alert; -} - -static void -e_web_view_gtkhtml_selectable_init (ESelectableInterface *interface) -{ - interface->update_actions = web_view_gtkhtml_selectable_update_actions; - interface->cut_clipboard = web_view_gtkhtml_selectable_cut_clipboard; - interface->copy_clipboard = web_view_gtkhtml_selectable_copy_clipboard; - interface->paste_clipboard = web_view_gtkhtml_selectable_paste_clipboard; - interface->select_all = web_view_gtkhtml_selectable_select_all; -} - -static void -e_web_view_gtkhtml_init (EWebViewGtkHTML *web_view) -{ - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - GtkTargetList *target_list; - EPopupAction *popup_action; - const gchar *domain = GETTEXT_PACKAGE; - const gchar *id; - GError *error = NULL; - - web_view->priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (web_view); - - ui_manager = gtk_ui_manager_new (); - web_view->priv->ui_manager = ui_manager; - - g_signal_connect_swapped ( - ui_manager, "connect-proxy", - G_CALLBACK (web_view_gtkhtml_connect_proxy_cb), web_view); - - target_list = gtk_target_list_new (NULL, 0); - web_view->priv->copy_target_list = target_list; - - target_list = gtk_target_list_new (NULL, 0); - web_view->priv->paste_target_list = target_list; - - action_group = gtk_action_group_new ("uri"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, uri_entries, - G_N_ELEMENTS (uri_entries), web_view); - - action_group = gtk_action_group_new ("http"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, http_entries, - G_N_ELEMENTS (http_entries), web_view); - - action_group = gtk_action_group_new ("mailto"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, mailto_entries, - G_N_ELEMENTS (mailto_entries), web_view); - - action_group = gtk_action_group_new ("image"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, image_entries, - G_N_ELEMENTS (image_entries), web_view); - - action_group = gtk_action_group_new ("selection"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, selection_entries, - G_N_ELEMENTS (selection_entries), web_view); - - action_group = gtk_action_group_new ("standard"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), web_view); - - popup_action = e_popup_action_new ("open"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "open-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Support lockdown. */ - - action_group = gtk_action_group_new ("lockdown-printing"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("print"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "print-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - action_group = gtk_action_group_new ("lockdown-save-to-disk"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("save-as"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "save-as-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here implies a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); - - id = "org.gnome.evolution.webview"; - e_plugin_ui_register_manager (ui_manager, id, web_view); - e_plugin_ui_enable_manager (ui_manager, id); - - e_extensible_load_extensions (E_EXTENSIBLE (web_view)); -} - -GtkWidget * -e_web_view_gtkhtml_new (void) -{ - return g_object_new (E_TYPE_WEB_VIEW_GTKHTML, NULL); -} - -void -e_web_view_gtkhtml_clear (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_load_empty (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_load_string (EWebViewGtkHTML *web_view, - const gchar *string) -{ - EWebViewGtkHTMLClass *class; - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->load_string != NULL); - - class->load_string (web_view, string); -} - -gboolean -e_web_view_gtkhtml_get_animate (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_animate(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_animate (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_animate (EWebViewGtkHTML *web_view, - gboolean animate) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_animate() - * so we can get a "notify::animate" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_animate (GTK_HTML (web_view), animate); - - g_object_notify (G_OBJECT (web_view), "animate"); -} - -gboolean -e_web_view_gtkhtml_get_caret_mode (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_caret_mode(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_caret_mode (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_caret_mode (EWebViewGtkHTML *web_view, - gboolean caret_mode) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_caret_mode() - * so we can get a "notify::caret-mode" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_caret_mode (GTK_HTML (web_view), caret_mode); - - g_object_notify (G_OBJECT (web_view), "caret-mode"); -} - -GtkTargetList * -e_web_view_gtkhtml_get_copy_target_list (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->copy_target_list; -} - -gboolean -e_web_view_gtkhtml_get_disable_printing (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->disable_printing; -} - -void -e_web_view_gtkhtml_set_disable_printing (EWebViewGtkHTML *web_view, - gboolean disable_printing) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - web_view->priv->disable_printing = disable_printing; - - g_object_notify (G_OBJECT (web_view), "disable-printing"); -} - -gboolean -e_web_view_gtkhtml_get_disable_save_to_disk (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->disable_save_to_disk; -} - -void -e_web_view_gtkhtml_set_disable_save_to_disk (EWebViewGtkHTML *web_view, - gboolean disable_save_to_disk) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - web_view->priv->disable_save_to_disk = disable_save_to_disk; - - g_object_notify (G_OBJECT (web_view), "disable-save-to-disk"); -} - -gboolean -e_web_view_gtkhtml_get_editable (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_editable(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_editable (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_editable (EWebViewGtkHTML *web_view, - gboolean editable) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_editable() - * so we can get a "notify::editable" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_editable (GTK_HTML (web_view), editable); - - g_object_notify (G_OBJECT (web_view), "editable"); -} - -gboolean -e_web_view_gtkhtml_get_inline_spelling (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_inline_spelling(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_inline_spelling (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_inline_spelling (EWebViewGtkHTML *web_view, - gboolean inline_spelling) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_inline_spelling() - * so we get a "notify::inline-spelling" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_inline_spelling (GTK_HTML (web_view), inline_spelling); - - g_object_notify (G_OBJECT (web_view), "inline-spelling"); -} - -gboolean -e_web_view_gtkhtml_get_magic_links (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_links(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_magic_links (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_magic_links (EWebViewGtkHTML *web_view, - gboolean magic_links) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_links() - * so we can get a "notify::magic-links" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_magic_links (GTK_HTML (web_view), magic_links); - - g_object_notify (G_OBJECT (web_view), "magic-links"); -} - -gboolean -e_web_view_gtkhtml_get_magic_smileys (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_smileys(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_magic_smileys (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_magic_smileys (EWebViewGtkHTML *web_view, - gboolean magic_smileys) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_smileys() - * so we can get a "notify::magic-smileys" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_magic_smileys (GTK_HTML (web_view), magic_smileys); - - g_object_notify (G_OBJECT (web_view), "magic-smileys"); -} - -const gchar * -e_web_view_gtkhtml_get_selected_uri (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->selected_uri; -} - -void -e_web_view_gtkhtml_set_selected_uri (EWebViewGtkHTML *web_view, - const gchar *selected_uri) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_free (web_view->priv->selected_uri); - web_view->priv->selected_uri = g_strdup (selected_uri); - - g_object_notify (G_OBJECT (web_view), "selected-uri"); -} - -GdkPixbufAnimation * -e_web_view_gtkhtml_get_cursor_image (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->cursor_image; -} - -void -e_web_view_gtkhtml_set_cursor_image (EWebViewGtkHTML *web_view, - GdkPixbufAnimation *image) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (image != NULL) - g_object_ref (image); - - if (web_view->priv->cursor_image != NULL) - g_object_unref (web_view->priv->cursor_image); - - web_view->priv->cursor_image = image; - - g_object_notify (G_OBJECT (web_view), "cursor-image"); -} - -GtkAction * -e_web_view_gtkhtml_get_open_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->open_proxy; -} - -void -e_web_view_gtkhtml_set_open_proxy (EWebViewGtkHTML *web_view, - GtkAction *open_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (open_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (open_proxy)); - g_object_ref (open_proxy); - } - - if (web_view->priv->open_proxy != NULL) - g_object_unref (web_view->priv->open_proxy); - - web_view->priv->open_proxy = open_proxy; - - g_object_notify (G_OBJECT (web_view), "open-proxy"); -} - -GtkTargetList * -e_web_view_gtkhtml_get_paste_target_list (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->paste_target_list; -} - -GtkAction * -e_web_view_gtkhtml_get_print_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->print_proxy; -} - -void -e_web_view_gtkhtml_set_print_proxy (EWebViewGtkHTML *web_view, - GtkAction *print_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (print_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (print_proxy)); - g_object_ref (print_proxy); - } - - if (web_view->priv->print_proxy != NULL) - g_object_unref (web_view->priv->print_proxy); - - web_view->priv->print_proxy = print_proxy; - - g_object_notify (G_OBJECT (web_view), "print-proxy"); -} - -GtkAction * -e_web_view_gtkhtml_get_save_as_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->save_as_proxy; -} - -void -e_web_view_gtkhtml_set_save_as_proxy (EWebViewGtkHTML *web_view, - GtkAction *save_as_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (save_as_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (save_as_proxy)); - g_object_ref (save_as_proxy); - } - - if (web_view->priv->save_as_proxy != NULL) - g_object_unref (web_view->priv->save_as_proxy); - - web_view->priv->save_as_proxy = save_as_proxy; - - g_object_notify (G_OBJECT (web_view), "save-as-proxy"); -} - -GtkAction * -e_web_view_gtkhtml_get_action (EWebViewGtkHTML *web_view, - const gchar *action_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - g_return_val_if_fail (action_name != NULL, NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - - return e_lookup_action (ui_manager, action_name); -} - -GtkActionGroup * -e_web_view_gtkhtml_get_action_group (EWebViewGtkHTML *web_view, - const gchar *group_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - - return e_lookup_action_group (ui_manager, group_name); -} - -gchar * -e_web_view_gtkhtml_extract_uri (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame) -{ - EWebViewGtkHTMLClass *class; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - if (frame == NULL) - frame = GTK_HTML (web_view); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_val_if_fail (class->extract_uri != NULL, NULL); - - return class->extract_uri (web_view, event, frame); -} - -void -e_web_view_gtkhtml_copy_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[COPY_CLIPBOARD], 0); -} - -void -e_web_view_gtkhtml_cut_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[CUT_CLIPBOARD], 0); -} - -gboolean -e_web_view_gtkhtml_is_selection_active (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "is-selection-active"); -} - -void -e_web_view_gtkhtml_paste_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[PASTE_CLIPBOARD], 0); -} - -gboolean -e_web_view_gtkhtml_scroll_forward (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "scroll-forward"); -} - -gboolean -e_web_view_gtkhtml_scroll_backward (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "scroll-backward"); -} - -void -e_web_view_gtkhtml_select_all (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "select-all"); -} - -void -e_web_view_gtkhtml_unselect_all (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "unselect-all"); -} - -void -e_web_view_gtkhtml_zoom_100 (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-reset"); -} - -void -e_web_view_gtkhtml_zoom_in (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-in"); -} - -void -e_web_view_gtkhtml_zoom_out (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-out"); -} - -GtkUIManager * -e_web_view_gtkhtml_get_ui_manager (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->ui_manager; -} - -GtkWidget * -e_web_view_gtkhtml_get_popup_menu (EWebViewGtkHTML *web_view) -{ - GtkUIManager *ui_manager; - GtkWidget *menu; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - menu = gtk_ui_manager_get_widget (ui_manager, "/context"); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu; -} - -void -e_web_view_gtkhtml_show_popup_menu (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkMenuPositionFunc func, - gpointer user_data) -{ - GtkWidget *menu; - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - e_web_view_gtkhtml_update_actions (web_view); - - menu = e_web_view_gtkhtml_get_popup_menu (web_view); - - if (event != NULL) - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, event->button, event->time); - else - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, 0, gtk_get_current_event_time ()); -} - -void -e_web_view_gtkhtml_status_message (EWebViewGtkHTML *web_view, - const gchar *status_message) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[STATUS_MESSAGE], 0, status_message); -} - -void -e_web_view_gtkhtml_stop_loading (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[STOP_LOADING], 0); -} - -void -e_web_view_gtkhtml_update_actions (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[UPDATE_ACTIONS], 0); -} diff --git a/widgets/misc/e-web-view-gtkhtml.h b/widgets/misc/e-web-view-gtkhtml.h deleted file mode 100644 index aab06e8b54..0000000000 --- a/widgets/misc/e-web-view-gtkhtml.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * e-web-view-gtkhtml.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -/* This is intended to serve as a common base class for all HTML viewing - * needs in Evolution. Currently based on GtkHTML, the idea is to wrap - * the GtkHTML API enough that we no longer have to make direct calls to - * it. This should help smooth the transition to WebKit/GTK+. - * - * This class handles basic tasks like mouse hovers over links, clicked - * links, and servicing URI requests asynchronously via GIO. */ - -#ifndef E_WEB_VIEW_GTKHTML_H -#define E_WEB_VIEW_GTKHTML_H - -#include <gtkhtml/gtkhtml.h> - -/* Standard GObject macros */ -#define E_TYPE_WEB_VIEW_GTKHTML \ - (e_web_view_gtkhtml_get_type ()) -#define E_WEB_VIEW_GTKHTML(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_WEB_VIEW_GTKHTML, EWebViewGtkHTML)) -#define E_WEB_VIEW_GTKHTML_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_WEB_VIEW_GTKHTML, EWebViewGtkHTMLClass)) -#define E_IS_WEB_VIEW_GTKHTML(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_WEB_VIEW_GTKHTML)) -#define E_IS_WEB_VIEW_GTKHTML_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_WEB_VIEW_GTKHTML)) -#define E_WEB_VIEW_GTKHTML_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_WEB_VIEW_GTKHTML, EWebViewGtkHTMLClass)) - -G_BEGIN_DECLS - -typedef struct _EWebViewGtkHTML EWebViewGtkHTML; -typedef struct _EWebViewGtkHTMLClass EWebViewGtkHTMLClass; -typedef struct _EWebViewGtkHTMLPrivate EWebViewGtkHTMLPrivate; - -struct _EWebViewGtkHTML { - GtkHTML parent; - EWebViewGtkHTMLPrivate *priv; -}; - -struct _EWebViewGtkHTMLClass { - GtkHTMLClass parent_class; - - /* Methods */ - gchar * (*extract_uri) (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame); - void (*hovering_over_link) (EWebViewGtkHTML *web_view, - const gchar *title, - const gchar *uri); - void (*link_clicked) (EWebViewGtkHTML *web_view, - const gchar *uri); - void (*load_string) (EWebViewGtkHTML *web_view, - const gchar *load_string); - - /* Signals */ - void (*copy_clipboard) (EWebViewGtkHTML *web_view); - void (*cut_clipboard) (EWebViewGtkHTML *web_view); - void (*paste_clipboard) (EWebViewGtkHTML *web_view); - gboolean (*popup_event) (EWebViewGtkHTML *web_view, - GdkEventButton *event, - const gchar *uri); - void (*status_message) (EWebViewGtkHTML *web_view, - const gchar *status_message); - void (*stop_loading) (EWebViewGtkHTML *web_view); - void (*update_actions) (EWebViewGtkHTML *web_view); - gboolean (*process_mailto) (EWebViewGtkHTML *web_view, - const gchar *mailto_uri); -}; - -GType e_web_view_gtkhtml_get_type (void); -GtkWidget * e_web_view_gtkhtml_new (void); -void e_web_view_gtkhtml_clear (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_load_string (EWebViewGtkHTML *web_view, - const gchar *string); -gboolean e_web_view_gtkhtml_get_animate (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_animate (EWebViewGtkHTML *web_view, - gboolean animate); -gboolean e_web_view_gtkhtml_get_caret_mode (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_caret_mode (EWebViewGtkHTML *web_view, - gboolean caret_mode); -GtkTargetList * e_web_view_gtkhtml_get_copy_target_list (EWebViewGtkHTML *web_view); -gboolean e_web_view_gtkhtml_get_disable_printing (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_disable_printing (EWebViewGtkHTML *web_view, - gboolean disable_printing); -gboolean e_web_view_gtkhtml_get_disable_save_to_disk - (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_disable_save_to_disk - (EWebViewGtkHTML *web_view, - gboolean disable_save_to_disk); -gboolean e_web_view_gtkhtml_get_editable (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_editable (EWebViewGtkHTML *web_view, - gboolean editable); -gboolean e_web_view_gtkhtml_get_inline_spelling (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_inline_spelling (EWebViewGtkHTML *web_view, - gboolean inline_spelling); -gboolean e_web_view_gtkhtml_get_magic_links (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_magic_links (EWebViewGtkHTML *web_view, - gboolean magic_links); -gboolean e_web_view_gtkhtml_get_magic_smileys (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_magic_smileys (EWebViewGtkHTML *web_view, - gboolean magic_smileys); -const gchar * e_web_view_gtkhtml_get_selected_uri (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_selected_uri (EWebViewGtkHTML *web_view, - const gchar *selected_uri); -GdkPixbufAnimation * - e_web_view_gtkhtml_get_cursor_image (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_cursor_image (EWebViewGtkHTML *web_view, - GdkPixbufAnimation *animation); -GtkAction * e_web_view_gtkhtml_get_open_proxy (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_open_proxy (EWebViewGtkHTML *web_view, - GtkAction *open_proxy); -GtkTargetList * e_web_view_gtkhtml_get_paste_target_list - (EWebViewGtkHTML *web_view); -GtkAction * e_web_view_gtkhtml_get_print_proxy (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_print_proxy (EWebViewGtkHTML *web_view, - GtkAction *print_proxy); -GtkAction * e_web_view_gtkhtml_get_save_as_proxy (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_set_save_as_proxy (EWebViewGtkHTML *web_view, - GtkAction *save_as_proxy); -GtkAction * e_web_view_gtkhtml_get_action (EWebViewGtkHTML *web_view, - const gchar *action_name); -GtkActionGroup *e_web_view_gtkhtml_get_action_group (EWebViewGtkHTML *web_view, - const gchar *group_name); -gchar * e_web_view_gtkhtml_extract_uri (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame); -void e_web_view_gtkhtml_copy_clipboard (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_cut_clipboard (EWebViewGtkHTML *web_view); -gboolean e_web_view_gtkhtml_is_selection_active (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_paste_clipboard (EWebViewGtkHTML *web_view); -gboolean e_web_view_gtkhtml_scroll_forward (EWebViewGtkHTML *web_view); -gboolean e_web_view_gtkhtml_scroll_backward (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_select_all (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_unselect_all (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_zoom_100 (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_zoom_in (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_zoom_out (EWebViewGtkHTML *web_view); -GtkUIManager * e_web_view_gtkhtml_get_ui_manager (EWebViewGtkHTML *web_view); -GtkWidget * e_web_view_gtkhtml_get_popup_menu (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_show_popup_menu (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkMenuPositionFunc func, - gpointer user_data); -void e_web_view_gtkhtml_status_message (EWebViewGtkHTML *web_view, - const gchar *status_message); -void e_web_view_gtkhtml_stop_loading (EWebViewGtkHTML *web_view); -void e_web_view_gtkhtml_update_actions (EWebViewGtkHTML *web_view); - -G_END_DECLS - -#endif /* E_WEB_VIEW_GTKHTML_H */ diff --git a/widgets/misc/e-web-view-preview.c b/widgets/misc/e-web-view-preview.c deleted file mode 100644 index b75814fa83..0000000000 --- a/widgets/misc/e-web-view-preview.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * e-web-view-preview.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-web-view-preview.h" - -#include <string.h> -#include <glib/gi18n-lib.h> - -#define E_WEB_VIEW_PREVIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewPrivate)) - -struct _EWebViewPreviewPrivate { - gboolean escape_values; - GString *updating_content; /* is NULL when not between begin_update/end_update */ -}; - -enum { - PROP_0, - PROP_TREE_VIEW, - PROP_PREVIEW_WIDGET, - PROP_ESCAPE_VALUES -}; - -G_DEFINE_TYPE ( - EWebViewPreview, - e_web_view_preview, - GTK_TYPE_VPANED); - -static void -web_view_preview_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ESCAPE_VALUES: - e_web_view_preview_set_escape_values ( - E_WEB_VIEW_PREVIEW (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_preview_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_TREE_VIEW: - g_value_set_object ( - value, e_web_view_preview_get_tree_view ( - E_WEB_VIEW_PREVIEW (object))); - return; - - case PROP_PREVIEW_WIDGET: - g_value_set_object ( - value, e_web_view_preview_get_preview ( - E_WEB_VIEW_PREVIEW (object))); - return; - - case PROP_ESCAPE_VALUES: - g_value_set_boolean ( - value, e_web_view_preview_get_escape_values ( - E_WEB_VIEW_PREVIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_preview_dispose (GObject *object) -{ - EWebViewPreviewPrivate *priv; - - priv = E_WEB_VIEW_PREVIEW_GET_PRIVATE (object); - - if (priv->updating_content != NULL) { - g_string_free (priv->updating_content, TRUE); - priv->updating_content = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_web_view_preview_parent_class)->dispose (object); -} - -static void -e_web_view_preview_class_init (EWebViewPreviewClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EWebViewPreviewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = web_view_preview_set_property; - object_class->get_property = web_view_preview_get_property; - object_class->dispose = web_view_preview_dispose; - - g_object_class_install_property ( - object_class, - PROP_TREE_VIEW, - g_param_spec_object ( - "tree-view", - "Tree View", - NULL, - GTK_TYPE_TREE_VIEW, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_PREVIEW_WIDGET, - g_param_spec_object ( - "preview-widget", - "Preview Widget", - NULL, - GTK_TYPE_WIDGET, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_ESCAPE_VALUES, - g_param_spec_boolean ( - "escape-values", - "Whether escaping values automatically, when inserting", - NULL, - TRUE, - G_PARAM_READWRITE)); -} - -static GtkWidget * -in_scrolled_window (GtkWidget *widget) -{ - GtkWidget *sw; - - g_return_val_if_fail (widget != NULL, NULL); - - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (sw), widget); - - gtk_widget_show (widget); - gtk_widget_show (sw); - - return sw; -} - -static void -e_web_view_preview_init (EWebViewPreview *preview) -{ - GtkWidget *tree_view_sw, *web_view_sw; - - preview->priv = E_WEB_VIEW_PREVIEW_GET_PRIVATE (preview); - preview->priv->escape_values = TRUE; - - tree_view_sw = in_scrolled_window (gtk_tree_view_new ()); - web_view_sw = in_scrolled_window (e_web_view_new ()); - - gtk_widget_hide (tree_view_sw); - gtk_widget_show (web_view_sw); - - gtk_paned_pack1 (GTK_PANED (preview), tree_view_sw, FALSE, TRUE); - gtk_paned_pack2 (GTK_PANED (preview), web_view_sw, TRUE, TRUE); - - /* rawly 3 lines of a text plus a little bit more */ - if (gtk_paned_get_position (GTK_PANED (preview)) < 85) - gtk_paned_set_position (GTK_PANED (preview), 85); -} - -GtkWidget * -e_web_view_preview_new (void) -{ - return g_object_new (E_TYPE_WEB_VIEW_PREVIEW, NULL); -} - -GtkTreeView * -e_web_view_preview_get_tree_view (EWebViewPreview *preview) -{ - g_return_val_if_fail (preview != NULL, NULL); - g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), NULL); - - return GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN (gtk_paned_get_child1 (GTK_PANED (preview))))); -} - -GtkWidget * -e_web_view_preview_get_preview (EWebViewPreview *preview) -{ - g_return_val_if_fail (preview != NULL, NULL); - g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), NULL); - - return gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview)))); -} - -void -e_web_view_preview_set_preview (EWebViewPreview *preview, - GtkWidget *preview_widget) -{ - GtkWidget *old_child; - - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (GTK_IS_WIDGET (preview_widget)); - - old_child = gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview)))); - if (old_child) { - g_return_if_fail (old_child != preview_widget); - gtk_widget_destroy (old_child); - } - - gtk_container_add (GTK_CONTAINER (gtk_paned_get_child2 (GTK_PANED (preview))), preview_widget); -} - -void -e_web_view_preview_show_tree_view (EWebViewPreview *preview) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - - gtk_widget_show (gtk_paned_get_child1 (GTK_PANED (preview))); -} - -void -e_web_view_preview_hide_tree_view (EWebViewPreview *preview) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - - gtk_widget_hide (gtk_paned_get_child1 (GTK_PANED (preview))); -} - -void -e_web_view_preview_set_escape_values (EWebViewPreview *preview, - gboolean escape) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - - preview->priv->escape_values = escape; -} - -gboolean -e_web_view_preview_get_escape_values (EWebViewPreview *preview) -{ - g_return_val_if_fail (preview != NULL, FALSE); - g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), FALSE); - g_return_val_if_fail (preview->priv != NULL, FALSE); - - return preview->priv->escape_values; -} - -void -e_web_view_preview_begin_update (EWebViewPreview *preview) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - - if (preview->priv->updating_content) { - g_warning ("%s: Previous content update isn't finished with e_web_view_preview_end_update()", G_STRFUNC); - g_string_free (preview->priv->updating_content, TRUE); - } - - preview->priv->updating_content = g_string_new ("<TABLE width=\"100%\" border=\"0\" cols=\"2\">"); -} - -void -e_web_view_preview_end_update (EWebViewPreview *preview) -{ - GtkWidget *web_view; - - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - - g_string_append (preview->priv->updating_content, "</TABLE>"); - - web_view = e_web_view_preview_get_preview (preview); - if (E_IS_WEB_VIEW (web_view)) - e_web_view_load_string (E_WEB_VIEW (web_view), preview->priv->updating_content->str); - - g_string_free (preview->priv->updating_content, TRUE); - preview->priv->updating_content = NULL; -} - -static gchar * -replace_string (const gchar *text, - const gchar *find, - const gchar *replace) -{ - const gchar *p, *next; - GString *str; - gint find_len; - - g_return_val_if_fail (text != NULL, NULL); - g_return_val_if_fail (find != NULL, NULL); - g_return_val_if_fail (*find, NULL); - - find_len = strlen (find); - str = g_string_new (""); - - p = text; - while (next = strstr (p, find), next) { - if (p + 1 < next) - g_string_append_len (str, p, next - p); - - if (replace && *replace) - g_string_append (str, replace); - - p = next + find_len; - } - - g_string_append (str, p); - - return g_string_free (str, FALSE); -} - -static gchar * -web_view_preview_escape_text (EWebViewPreview *preview, - const gchar *text) -{ - gchar *utf8_valid, *res, *end; - - if (!e_web_view_preview_get_escape_values (preview)) - return NULL; - - g_return_val_if_fail (text != NULL, NULL); - - if (g_utf8_validate (text, -1, NULL)) { - res = g_markup_escape_text (text, -1); - } else { - utf8_valid = g_strdup (text); - while (end = NULL, !g_utf8_validate (utf8_valid, -1, (const gchar **) &end) && end && *end) - *end = '?'; - - res = g_markup_escape_text (utf8_valid, -1); - - g_free (utf8_valid); - } - - if (res && strchr (res, '\n')) { - /* replace line breaks with <BR> */ - if (strchr (res, '\r')) { - end = replace_string (res, "\r", ""); - g_free (res); - res = end; - } - - end = replace_string (res, "\n", "<BR>"); - g_free (res); - res = end; - } - - return res; -} - -void -e_web_view_preview_add_header (EWebViewPreview *preview, - gint index, - const gchar *header) -{ - gchar *escaped; - - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - g_return_if_fail (header != NULL); - - if (index < 1) - index = 1; - else if (index > 6) - index = 6; - - escaped = web_view_preview_escape_text (preview, header); - if (escaped) - header = escaped; - - g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2><H%d>%s</H%d></TD></TR>", index, header, index); - - g_free (escaped); -} - -void -e_web_view_preview_add_text (EWebViewPreview *preview, - const gchar *text) -{ - gchar *escaped; - - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - g_return_if_fail (text != NULL); - - escaped = web_view_preview_escape_text (preview, text); - if (escaped) - text = escaped; - - g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2><FONT size=\"3\">%s</FONT></TD></TR>", text); - - g_free (escaped); -} - -void -e_web_view_preview_add_raw_html (EWebViewPreview *preview, - const gchar *raw_html) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - g_return_if_fail (raw_html != NULL); - - g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2>%s</TD></TR>", raw_html); -} - -void -e_web_view_preview_add_separator (EWebViewPreview *preview) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - - g_string_append (preview->priv->updating_content, "<TR><TD colspan=2><HR></TD></TR>"); -} - -void -e_web_view_preview_add_empty_line (EWebViewPreview *preview) -{ - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - - g_string_append (preview->priv->updating_content, "<TR><TD colspan=2> </TD></TR>"); -} - -/* section can be NULL, but value cannot */ -void -e_web_view_preview_add_section (EWebViewPreview *preview, - const gchar *section, - const gchar *value) -{ - gchar *escaped_section = NULL, *escaped_value; - - g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview)); - g_return_if_fail (preview->priv->updating_content != NULL); - g_return_if_fail (value != NULL); - - if (section) { - escaped_section = web_view_preview_escape_text (preview, section); - if (escaped_section) - section = escaped_section; - } - - escaped_value = web_view_preview_escape_text (preview, value); - if (escaped_value) - value = escaped_value; - - g_string_append_printf (preview->priv->updating_content, "<TR><TD width=\"10%%\" valign=\"top\" nowrap><FONT size=\"3\"><B>%s</B></FONT></TD><TD width=\"90%%\"><FONT size=\"3\">%s</FONT></TD></TR>", section ? section : "", value); - - g_free (escaped_section); - g_free (escaped_value); -} diff --git a/widgets/misc/e-web-view-preview.h b/widgets/misc/e-web-view-preview.h deleted file mode 100644 index 07c78ff182..0000000000 --- a/widgets/misc/e-web-view-preview.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * e-web-view-preview.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* This is intended to serve as a common widget for previews before import. - * It contains a GtkTreeView at the top and an EWebView at the bottom. - * The tree view is not shown initially, it should be forced with - * e_web_view_preview_show_tree_view(). - * - * The internal default EWebView can be accessed by e_web_view_preview_get_preview() - * and it should be updated for each change of the selected item in the tree - * view, when it's shown. - * - * Updating an EWebView content through helper functions of an EWebViewPreview - * begins with call of e_web_view_preview_begin_update(), which starts an empty - * page construction, which is finished by e_web_view_preview_end_update(), - * and the content of the EWebView is updated. - */ - -#ifndef E_WEB_VIEW_PREVIEW_H -#define E_WEB_VIEW_PREVIEW_H - -#include <misc/e-web-view.h> - -/* Standard GObject macros */ -#define E_TYPE_WEB_VIEW_PREVIEW \ - (e_web_view_preview_get_type ()) -#define E_WEB_VIEW_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreview)) -#define E_WEB_VIEW_PREVIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewClass)) -#define E_IS_WEB_VIEW_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_WEB_VIEW_PREVIEW)) -#define E_IS_WEB_VIEW_PREVIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_WEB_VIEW_PREVIEW)) -#define E_WEB_VIEW_PREVIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewClass)) - -G_BEGIN_DECLS - -typedef struct _EWebViewPreview EWebViewPreview; -typedef struct _EWebViewPreviewClass EWebViewPreviewClass; -typedef struct _EWebViewPreviewPrivate EWebViewPreviewPrivate; - -struct _EWebViewPreview { - GtkVPaned parent; - EWebViewPreviewPrivate *priv; -}; - -struct _EWebViewPreviewClass { - GtkVPanedClass parent_class; -}; - -GType e_web_view_preview_get_type (void); -GtkWidget * e_web_view_preview_new (void); -GtkTreeView * e_web_view_preview_get_tree_view - (EWebViewPreview *preview); -GtkWidget * e_web_view_preview_get_preview (EWebViewPreview *preview); -void e_web_view_preview_set_preview (EWebViewPreview *preview, - GtkWidget *preview_widget); -void e_web_view_preview_show_tree_view - (EWebViewPreview *preview); -void e_web_view_preview_hide_tree_view - (EWebViewPreview *preview); -void e_web_view_preview_set_escape_values - (EWebViewPreview *preview, - gboolean escape); -gboolean e_web_view_preview_get_escape_values - (EWebViewPreview *preview); -void e_web_view_preview_begin_update (EWebViewPreview *preview); -void e_web_view_preview_end_update (EWebViewPreview *preview); -void e_web_view_preview_add_header (EWebViewPreview *preview, - gint index, - const gchar *header); -void e_web_view_preview_add_text (EWebViewPreview *preview, - const gchar *text); -void e_web_view_preview_add_raw_html (EWebViewPreview *preview, - const gchar *raw_html); -void e_web_view_preview_add_separator - (EWebViewPreview *preview); -void e_web_view_preview_add_empty_line - (EWebViewPreview *preview); -void e_web_view_preview_add_section (EWebViewPreview *preview, - const gchar *section, - const gchar *value); - -G_END_DECLS - -#endif /* E_WEB_VIEW_PREVIEW_H */ diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c deleted file mode 100644 index 0d0903c7bd..0000000000 --- a/widgets/misc/e-web-view.c +++ /dev/null @@ -1,2946 +0,0 @@ -/* - * e-web-view.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-web-view.h" - -#include <math.h> - -#include <string.h> -#include <glib/gi18n-lib.h> -#include <pango/pango.h> - -#include <camel/camel.h> -#include <libebackend/libebackend.h> - -#include <e-util/e-util.h> -#include <libevolution-utils/e-alert-dialog.h> -#include <libevolution-utils/e-alert-sink.h> -#include <e-util/e-plugin-ui.h> -#include <e-util/e-file-request.h> -#include <e-util/e-stock-request.h> - -#define LIBSOUP_USE_UNSTABLE_REQUEST_API -#include <libsoup/soup.h> -#include <libsoup/soup-requester.h> - -#include "e-popup-action.h" -#include "e-selectable.h" -#include <stdlib.h> - -#define E_WEB_VIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_WEB_VIEW, EWebViewPrivate)) - -typedef struct _EWebViewRequest EWebViewRequest; - -struct _EWebViewPrivate { - GList *requests; - GtkUIManager *ui_manager; - gchar *selected_uri; - GdkPixbufAnimation *cursor_image; - gchar *cursor_image_src; - - GSList *highlights; - - GtkAction *open_proxy; - GtkAction *print_proxy; - GtkAction *save_as_proxy; - - /* Lockdown Options */ - guint disable_printing : 1; - guint disable_save_to_disk : 1; - - guint caret_mode : 1; - - GSettings *font_settings; - GSettings *aliasing_settings; -}; - -enum { - PROP_0, - PROP_CARET_MODE, - PROP_COPY_TARGET_LIST, - PROP_CURSOR_IMAGE, - PROP_CURSOR_IMAGE_SRC, - PROP_DISABLE_PRINTING, - PROP_DISABLE_SAVE_TO_DISK, - PROP_INLINE_SPELLING, - PROP_MAGIC_LINKS, - PROP_MAGIC_SMILEYS, - PROP_OPEN_PROXY, - PROP_PRINT_PROXY, - PROP_SAVE_AS_PROXY, - PROP_SELECTED_URI -}; - -enum { - POPUP_EVENT, - STATUS_MESSAGE, - STOP_LOADING, - UPDATE_ACTIONS, - PROCESS_MAILTO, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <menuitem action='copy-clipboard'/>" -" <separator/>" -" <placeholder name='custom-actions-1'>" -" <menuitem action='open'/>" -" <menuitem action='save-as'/>" -" <menuitem action='http-open'/>" -" <menuitem action='send-message'/>" -" <menuitem action='print'/>" -" </placeholder>" -" <placeholder name='custom-actions-2'>" -" <menuitem action='uri-copy'/>" -" <menuitem action='mailto-copy'/>" -" <menuitem action='image-copy'/>" -" </placeholder>" -" <placeholder name='custom-actions-3'/>" -" <separator/>" -" <menuitem action='select-all'/>" -" <placeholder name='inspect-menu' />" -" </popup>" -"</ui>"; - -/* Forward Declarations */ -static void e_web_view_alert_sink_init (EAlertSinkInterface *interface); -static void e_web_view_selectable_init (ESelectableInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EWebView, - e_web_view, - WEBKIT_TYPE_WEB_VIEW, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL) - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_web_view_alert_sink_init) - G_IMPLEMENT_INTERFACE ( - E_TYPE_SELECTABLE, - e_web_view_selectable_init)) - -static void -action_copy_clipboard_cb (GtkAction *action, - EWebView *web_view) -{ - e_web_view_copy_clipboard (web_view); -} - -static void -action_http_open_cb (GtkAction *action, - EWebView *web_view) -{ - const gchar *uri; - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - e_show_uri (parent, uri); -} - -static void -action_mailto_copy_cb (GtkAction *action, - EWebView *web_view) -{ - CamelURL *curl; - CamelInternetAddress *inet_addr; - GtkClipboard *clipboard; - const gchar *uri; - gchar *text; - - uri = e_web_view_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - /* This should work because we checked it in update_actions(). */ - curl = camel_url_new (uri, NULL); - g_return_if_fail (curl != NULL); - - inet_addr = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path); - text = camel_address_format (CAMEL_ADDRESS (inet_addr)); - if (text == NULL || *text == '\0') - text = g_strdup (uri + strlen ("mailto:")); - - g_object_unref (inet_addr); - camel_url_free (curl); - - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - g_free (text); -} - -static void -action_select_all_cb (GtkAction *action, - EWebView *web_view) -{ - e_web_view_select_all (web_view); -} - -static void -action_send_message_cb (GtkAction *action, - EWebView *web_view) -{ - const gchar *uri; - gpointer parent; - gboolean handled; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - handled = FALSE; - g_signal_emit (web_view, signals[PROCESS_MAILTO], 0, uri, &handled); - - if (!handled) - e_show_uri (parent, uri); -} - -static void -action_uri_copy_cb (GtkAction *action, - EWebView *web_view) -{ - GtkClipboard *clipboard; - const gchar *uri; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - uri = e_web_view_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - gtk_clipboard_set_text (clipboard, uri, -1); - gtk_clipboard_store (clipboard); -} - -static void -action_image_copy_cb (GtkAction *action, - EWebView *web_view) -{ - GtkClipboard *clipboard; - GdkPixbufAnimation *animation; - GdkPixbuf *pixbuf; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - animation = e_web_view_get_cursor_image (web_view); - g_return_if_fail (animation != NULL); - - pixbuf = gdk_pixbuf_animation_get_static_image (animation); - if (pixbuf == NULL) - return; - - gtk_clipboard_set_image (clipboard, pixbuf); - gtk_clipboard_store (clipboard); -} - -static GtkActionEntry uri_entries[] = { - - { "uri-copy", - GTK_STOCK_COPY, - N_("_Copy Link Location"), - NULL, - N_("Copy the link to the clipboard"), - G_CALLBACK (action_uri_copy_cb) } -}; - -static GtkActionEntry http_entries[] = { - - { "http-open", - "emblem-web", - N_("_Open Link in Browser"), - NULL, - N_("Open the link in a web browser"), - G_CALLBACK (action_http_open_cb) } -}; - -static GtkActionEntry mailto_entries[] = { - - { "mailto-copy", - GTK_STOCK_COPY, - N_("_Copy Email Address"), - NULL, - N_("Copy the email address to the clipboard"), - G_CALLBACK (action_mailto_copy_cb) }, - - { "send-message", - "mail-message-new", - N_("_Send New Message To..."), - NULL, - N_("Send a mail message to this address"), - G_CALLBACK (action_send_message_cb) } -}; - -static GtkActionEntry image_entries[] = { - - { "image-copy", - GTK_STOCK_COPY, - N_("_Copy Image"), - NULL, - N_("Copy the image to the clipboard"), - G_CALLBACK (action_image_copy_cb) } -}; - -static GtkActionEntry selection_entries[] = { - - { "copy-clipboard", - GTK_STOCK_COPY, - NULL, - NULL, - N_("Copy the selection"), - G_CALLBACK (action_copy_clipboard_cb) }, -}; - -static GtkActionEntry standard_entries[] = { - - { "select-all", - GTK_STOCK_SELECT_ALL, - NULL, - NULL, - N_("Select all text and images"), - G_CALLBACK (action_select_all_cb) } -}; - -static void -web_view_menu_item_select_cb (EWebView *web_view, - GtkWidget *widget) -{ - GtkAction *action; - GtkActivatable *activatable; - const gchar *tooltip; - - activatable = GTK_ACTIVATABLE (widget); - action = gtk_activatable_get_related_action (activatable); - tooltip = gtk_action_get_tooltip (action); - - if (tooltip == NULL) - return; - - e_web_view_status_message (web_view, tooltip); -} - -static void -replace_text (WebKitDOMNode *node, - const gchar *text, - WebKitDOMNode *replacement) -{ - /* NodeType 3 = TEXT_NODE */ - if (webkit_dom_node_get_node_type (node) == 3) { - gint text_length = strlen (text); - - while (node) { - - WebKitDOMNode *current_node, *replacement_node; - const gchar *node_data, *offset; - goffset split_offset; - gint data_length; - - current_node = node; - - /* Don't use the WEBKIT_DOM_CHARACTER_DATA macro for - * casting. WebKit lies about type of the object and - * GLib will throw runtime warning about node not being - * WebKitDOMCharacterData, but the function will return - * correct and valid data. - * IMO it's bug in the Gtk bindings and WebKit internally - * handles it by the nodeType so therefor it works - * event for "invalid" objects. But really, who knows..? - */ - node_data = webkit_dom_character_data_get_data ( - (WebKitDOMCharacterData *) node); - - offset = strstr (node_data, text); - if (offset == NULL) { - node = NULL; - continue; - } - - split_offset = offset - node_data + text_length; - replacement_node = - webkit_dom_node_clone_node (replacement, TRUE); - - data_length = webkit_dom_character_data_get_length ( - (WebKitDOMCharacterData *) node); - if (split_offset < data_length) { - - WebKitDOMNode *parent_node; - - node = WEBKIT_DOM_NODE ( - webkit_dom_text_split_text ( - (WebKitDOMText *) node, - offset - node_data + text_length, - NULL)); - parent_node = webkit_dom_node_get_parent_node (node); - webkit_dom_node_insert_before ( - parent_node, replacement_node, - node, NULL); - - } else { - WebKitDOMNode *parent_node; - - parent_node = webkit_dom_node_get_parent_node (node); - webkit_dom_node_append_child ( - parent_node, - replacement_node, NULL); - } - - webkit_dom_character_data_delete_data ( - (WebKitDOMCharacterData *) (current_node), - offset - node_data, text_length, NULL); - } - - } else { - WebKitDOMNode *child, *next_child; - - /* Iframe? Let's traverse inside! */ - if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (node)) { - - WebKitDOMDocument *frame_document; - - frame_document = - webkit_dom_html_iframe_element_get_content_document ( - WEBKIT_DOM_HTML_IFRAME_ELEMENT (node)); - replace_text ( - WEBKIT_DOM_NODE (frame_document), - text, replacement); - - } else { - child = webkit_dom_node_get_first_child (node); - while (child != NULL) { - next_child = webkit_dom_node_get_next_sibling (child); - replace_text (child, text, replacement); - child = next_child; - } - } - } -} - -static void -web_view_update_document_highlights (EWebView *web_view) -{ - WebKitDOMDocument *document; - GSList *iter; - - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view)); - - for (iter = web_view->priv->highlights; iter; iter = iter->next) { - - WebKitDOMDocumentFragment *frag; - WebKitDOMElement *span; - - span = webkit_dom_document_create_element (document, "span", NULL); - - /* See https://bugzilla.gnome.org/show_bug.cgi?id=681400 - * FIXME: This can be removed once we require WebKitGtk 1.10+ */ - #if WEBKIT_CHECK_VERSION (1, 9, 6) - webkit_dom_element_set_class_name ( - span, "__evo-highlight"); - #else - webkit_dom_html_element_set_class_name ( - WEBKIT_DOM_HTML_ELEMENT (span), "__evo-highlight"); - #endif - - webkit_dom_html_element_set_inner_text ( - WEBKIT_DOM_HTML_ELEMENT (span), iter->data, NULL); - - frag = webkit_dom_document_create_document_fragment (document); - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (frag), WEBKIT_DOM_NODE (span), NULL); - - replace_text ( - WEBKIT_DOM_NODE (document), - iter->data, WEBKIT_DOM_NODE (frag)); - } -} - -static void -web_view_menu_item_deselect_cb (EWebView *web_view) -{ - e_web_view_status_message (web_view, NULL); -} - -static void -web_view_connect_proxy_cb (EWebView *web_view, - GtkAction *action, - GtkWidget *proxy) -{ - if (!GTK_IS_MENU_ITEM (proxy)) - return; - - g_signal_connect_swapped ( - proxy, "select", - G_CALLBACK (web_view_menu_item_select_cb), web_view); - - g_signal_connect_swapped ( - proxy, "deselect", - G_CALLBACK (web_view_menu_item_deselect_cb), web_view); -} - -static GtkWidget * -web_view_create_plugin_widget_cb (EWebView *web_view, - const gchar *mime_type, - const gchar *uri, - GHashTable *param) -{ - EWebViewClass *class; - - /* XXX WebKitWebView does not provide a class method for - * this signal, so we do so we can override the default - * behavior from subclasses for special URI types. */ - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_val_if_fail (class->create_plugin_widget != NULL, NULL); - - return class->create_plugin_widget (web_view, mime_type, uri, param); -} - -static void -web_view_hovering_over_link_cb (EWebView *web_view, - const gchar *title, - const gchar *uri) -{ - EWebViewClass *class; - - /* XXX WebKitWebView does not provide a class method for - * this signal, so we do so we can override the default - * behavior from subclasses for special URI types. */ - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_if_fail (class->hovering_over_link != NULL); - - class->hovering_over_link (web_view, title, uri); -} - -static gboolean -web_view_navigation_policy_decision_requested_cb (EWebView *web_view, - WebKitWebFrame *frame, - WebKitNetworkRequest *request, - WebKitWebNavigationAction *navigation_action, - WebKitWebPolicyDecision *policy_decision) -{ - EWebViewClass *class; - WebKitWebNavigationReason reason; - const gchar *uri; - - reason = webkit_web_navigation_action_get_reason (navigation_action); - if (reason != WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) - return FALSE; - - /* XXX WebKitWebView does not provide a class method for - * this signal, so we do so we can override the default - * behavior from subclasses for special URI types. */ - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_val_if_fail (class->link_clicked != NULL, FALSE); - - webkit_web_policy_decision_ignore (policy_decision); - - uri = webkit_network_request_get_uri (request); - - class->link_clicked (web_view, uri); - - return TRUE; -} - -static void -web_view_load_status_changed_cb (WebKitWebView *webkit_web_view, - GParamSpec *pspec, - gpointer user_data) -{ - WebKitLoadStatus status; - EWebView *web_view; - - status = webkit_web_view_get_load_status (webkit_web_view); - if (status != WEBKIT_LOAD_FINISHED) - return; - - web_view = E_WEB_VIEW (webkit_web_view); - web_view_update_document_highlights (web_view); - - /* Workaround webkit bug https://bugs.webkit.org/show_bug.cgi?id=89553 */ - e_web_view_zoom_in (web_view); - e_web_view_zoom_out (web_view); -} - -static void -web_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CARET_MODE: - e_web_view_set_caret_mode ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_CURSOR_IMAGE: - e_web_view_set_cursor_image ( - E_WEB_VIEW (object), - g_value_get_object (value)); - return; - - case PROP_CURSOR_IMAGE_SRC: - e_web_view_set_cursor_image_src ( - E_WEB_VIEW (object), - g_value_get_string (value)); - return; - - case PROP_DISABLE_PRINTING: - e_web_view_set_disable_printing ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - e_web_view_set_disable_save_to_disk ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_INLINE_SPELLING: - e_web_view_set_inline_spelling ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_LINKS: - e_web_view_set_magic_links ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_SMILEYS: - e_web_view_set_magic_smileys ( - E_WEB_VIEW (object), - g_value_get_boolean (value)); - return; - - case PROP_OPEN_PROXY: - e_web_view_set_open_proxy ( - E_WEB_VIEW (object), - g_value_get_object (value)); - return; - - case PROP_PRINT_PROXY: - e_web_view_set_print_proxy ( - E_WEB_VIEW (object), - g_value_get_object (value)); - return; - - case PROP_SAVE_AS_PROXY: - e_web_view_set_save_as_proxy ( - E_WEB_VIEW (object), - g_value_get_object (value)); - return; - - case PROP_SELECTED_URI: - e_web_view_set_selected_uri ( - E_WEB_VIEW (object), - g_value_get_string (value)); - return; - } - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CARET_MODE: - g_value_set_boolean ( - value, e_web_view_get_caret_mode ( - E_WEB_VIEW (object))); - return; - - case PROP_CURSOR_IMAGE: - g_value_set_object ( - value, e_web_view_get_cursor_image ( - E_WEB_VIEW (object))); - return; - - case PROP_CURSOR_IMAGE_SRC: - g_value_set_string ( - value, e_web_view_get_cursor_image_src ( - E_WEB_VIEW (object))); - return; - - case PROP_DISABLE_PRINTING: - g_value_set_boolean ( - value, e_web_view_get_disable_printing ( - E_WEB_VIEW (object))); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - g_value_set_boolean ( - value, e_web_view_get_disable_save_to_disk ( - E_WEB_VIEW (object))); - return; - - case PROP_INLINE_SPELLING: - g_value_set_boolean ( - value, e_web_view_get_inline_spelling ( - E_WEB_VIEW (object))); - return; - - case PROP_MAGIC_LINKS: - g_value_set_boolean ( - value, e_web_view_get_magic_links ( - E_WEB_VIEW (object))); - return; - - case PROP_MAGIC_SMILEYS: - g_value_set_boolean ( - value, e_web_view_get_magic_smileys ( - E_WEB_VIEW (object))); - return; - - case PROP_OPEN_PROXY: - g_value_set_object ( - value, e_web_view_get_open_proxy ( - E_WEB_VIEW (object))); - return; - - case PROP_PRINT_PROXY: - g_value_set_object ( - value, e_web_view_get_print_proxy ( - E_WEB_VIEW (object))); - return; - - case PROP_SAVE_AS_PROXY: - g_value_set_object ( - value, e_web_view_get_save_as_proxy ( - E_WEB_VIEW (object))); - return; - - case PROP_SELECTED_URI: - g_value_set_string ( - value, e_web_view_get_selected_uri ( - E_WEB_VIEW (object))); - return; - - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_dispose (GObject *object) -{ - EWebViewPrivate *priv; - - priv = E_WEB_VIEW_GET_PRIVATE (object); - - if (priv->ui_manager != NULL) { - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - } - - if (priv->open_proxy != NULL) { - g_object_unref (priv->open_proxy); - priv->open_proxy = NULL; - } - - if (priv->print_proxy != NULL) { - g_object_unref (priv->print_proxy); - priv->print_proxy = NULL; - } - - if (priv->save_as_proxy != NULL) { - g_object_unref (priv->save_as_proxy); - priv->save_as_proxy = NULL; - } - - if (priv->cursor_image != NULL) { - g_object_unref (priv->cursor_image); - priv->cursor_image = NULL; - } - - if (priv->cursor_image_src != NULL) { - g_free (priv->cursor_image_src); - priv->cursor_image_src = NULL; - } - - if (priv->highlights != NULL) { - g_slist_free_full (priv->highlights, g_free); - priv->highlights = NULL; - } - - if (priv->aliasing_settings != NULL) { - g_signal_handlers_disconnect_matched ( - priv->aliasing_settings, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->aliasing_settings); - priv->aliasing_settings = NULL; - } - - if (priv->font_settings != NULL) { - g_signal_handlers_disconnect_matched ( - priv->font_settings, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->font_settings); - priv->font_settings = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_web_view_parent_class)->dispose (object); -} - -static void -web_view_finalize (GObject *object) -{ - EWebViewPrivate *priv; - - priv = E_WEB_VIEW_GET_PRIVATE (object); - - /* All URI requests should be complete or cancelled by now. */ - if (priv->requests != NULL) - g_warning ("Finalizing EWebView with active URI requests"); - - g_free (priv->selected_uri); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_web_view_parent_class)->finalize (object); -} - -static void -web_view_constructed (GObject *object) -{ -#ifndef G_OS_WIN32 - GSettings *settings; - - settings = g_settings_new ("org.gnome.desktop.lockdown"); - - g_settings_bind ( - settings, "disable-printing", - object, "disable-printing", - G_SETTINGS_BIND_GET); - - g_settings_bind ( - settings, "disable-save-to-disk", - object, "disable-save-to-disk", - G_SETTINGS_BIND_GET); - - g_object_unref (settings); -#endif - - e_extensible_load_extensions (E_EXTENSIBLE (object)); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_web_view_parent_class)->constructed (object); -} - -static gboolean -web_view_context_menu_cb (WebKitWebView *webkit_web_view, - GtkWidget *default_menu, - WebKitHitTestResult *hit_test_result, - gboolean triggered_with_keyboard) -{ - WebKitHitTestResultContext context; - EWebView *web_view; - gboolean event_handled = FALSE; - gchar *uri; - - web_view = E_WEB_VIEW (webkit_web_view); - - if (web_view->priv->cursor_image != NULL) { - g_object_unref (web_view->priv->cursor_image); - web_view->priv->cursor_image = NULL; - } - - if (web_view->priv->cursor_image_src != NULL) { - g_free (web_view->priv->cursor_image_src); - web_view->priv->cursor_image_src = NULL; - } - - if (hit_test_result == NULL) - return FALSE; - - g_object_get (G_OBJECT (hit_test_result), "context", &context, NULL); - - if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { - WebKitWebDataSource *data_source; - WebKitWebFrame *frame; - GList *subresources, *res; - - g_object_get ( - G_OBJECT (hit_test_result), "image-uri", &uri, NULL); - - if (uri == NULL) - return FALSE; - - g_free (web_view->priv->cursor_image_src); - web_view->priv->cursor_image_src = uri; - - /* Iterate through all resources of the loaded webpage and - * try to find resource with URI matching cursor_image_src */ - frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view)); - data_source = webkit_web_frame_get_data_source (frame); - subresources = webkit_web_data_source_get_subresources (data_source); - for (res = subresources; res; res = res->next) { - WebKitWebResource *src = res->data; - GdkPixbufLoader *loader; - GString *data; - - if (g_strcmp0 (webkit_web_resource_get_uri (src), - web_view->priv->cursor_image_src) != 0) - continue; - - data = webkit_web_resource_get_data (src); - if (data == NULL) - break; - - loader = gdk_pixbuf_loader_new (); - if (!gdk_pixbuf_loader_write (loader, - (guchar *) data->str, data->len, NULL)) { - g_object_unref (loader); - break; - } - gdk_pixbuf_loader_close (loader, NULL); - - if (web_view->priv->cursor_image != NULL) - g_object_unref (web_view->priv->cursor_image); - - web_view->priv->cursor_image = - g_object_ref (gdk_pixbuf_loader_get_animation (loader)); - - g_object_unref (loader); - break; - } - g_list_free (subresources); - } - - g_object_get (hit_test_result, "link-uri", &uri, NULL); - - if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)) { - g_free (uri); - uri = NULL; - } - - g_signal_emit (web_view, signals[POPUP_EVENT], 0, uri, &event_handled); - - g_free (uri); - - return event_handled; -} - -static gboolean -web_view_scroll_event (GtkWidget *widget, - GdkEventScroll *event) -{ - if (event->state & GDK_CONTROL_MASK) { - GdkScrollDirection direction = event->direction; - - if (direction == GDK_SCROLL_SMOOTH) { - static gdouble total_delta_y = 0.0; - - total_delta_y += event->delta_y; - - if (total_delta_y >= 1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_DOWN; - } else if (total_delta_y <= -1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_UP; - } else { - return FALSE; - } - } - - switch (direction) { - case GDK_SCROLL_UP: - e_web_view_zoom_in (E_WEB_VIEW (widget)); - return TRUE; - case GDK_SCROLL_DOWN: - e_web_view_zoom_out (E_WEB_VIEW (widget)); - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static GtkWidget * -web_view_create_plugin_widget (EWebView *web_view, - const gchar *mime_type, - const gchar *uri, - GHashTable *param) -{ - GtkWidget *widget = NULL; - - if (g_strcmp0 (mime_type, "image/x-themed-icon") == 0) { - GtkIconTheme *icon_theme; - GdkPixbuf *pixbuf; - gpointer data; - glong size = 0; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - - if (size == 0) { - data = g_hash_table_lookup (param, "width"); - if (data != NULL) - size = MAX (size, strtol (data, NULL, 10)); - } - - if (size == 0) { - data = g_hash_table_lookup (param, "height"); - if (data != NULL) - size = MAX (size, strtol (data, NULL, 10)); - } - - if (size == 0) - size = 32; /* arbitrary default */ - - pixbuf = gtk_icon_theme_load_icon ( - icon_theme, uri, size, 0, &error); - if (pixbuf != NULL) { - widget = gtk_image_new_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - } else if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - } - - return widget; -} - -static gchar * -web_view_extract_uri (EWebView *web_view, - GdkEventButton *event) -{ - WebKitHitTestResult *result; - WebKitHitTestResultContext context; - gchar *uri = NULL; - - result = webkit_web_view_get_hit_test_result ( - WEBKIT_WEB_VIEW (web_view), event); - - g_object_get (result, "context", &context, "link-uri", &uri, NULL); - g_object_unref (result); - - if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) - return uri; - - g_free (uri); - - return NULL; -} - -static void -web_view_hovering_over_link (EWebView *web_view, - const gchar *title, - const gchar *uri) -{ - CamelInternetAddress *address; - CamelURL *curl; - const gchar *format = NULL; - gchar *message = NULL; - gchar *who; - - if (uri == NULL || *uri == '\0') - goto exit; - - if (g_str_has_prefix (uri, "mailto:")) - format = _("Click to mail %s"); - else if (g_str_has_prefix (uri, "callto:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "h323:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "sip:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "##")) - message = g_strdup (_("Click to hide/unhide addresses")); - else - message = g_strdup_printf (_("Click to open %s"), uri); - - if (format == NULL) - goto exit; - - /* XXX Use something other than Camel here. Surely - * there's other APIs around that can do this. */ - curl = camel_url_new (uri, NULL); - address = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (address), curl->path); - who = camel_address_format (CAMEL_ADDRESS (address)); - g_object_unref (address); - camel_url_free (curl); - - if (who == NULL) - who = g_strdup (strchr (uri, ':') + 1); - - message = g_strdup_printf (format, who); - - g_free (who); - -exit: - e_web_view_status_message (web_view, message); - - g_free (message); -} - -static void -web_view_link_clicked (EWebView *web_view, - const gchar *uri) -{ - gpointer parent; - - if (uri && g_ascii_strncasecmp (uri, "mailto:", 7) == 0) { - gboolean handled = FALSE; - - g_signal_emit ( - web_view, signals[PROCESS_MAILTO], 0, uri, &handled); - - if (handled) - return; - } - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - e_show_uri (parent, uri); -} - -static void -web_view_load_string (EWebView *web_view, - const gchar *string) -{ - if (string == NULL) - string = ""; - - webkit_web_view_load_string ( - WEBKIT_WEB_VIEW (web_view), - string, "text/html", "UTF-8", "evo-file:///"); -} - -static void -web_view_load_uri (EWebView *web_view, - const gchar *uri) -{ - if (uri == NULL) - uri = "about:blank"; - - webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri); -} - -static void -web_view_frame_load_string (EWebView *web_view, - const gchar *frame_name, - const gchar *string) -{ - WebKitWebFrame *main_frame; - - if (string == NULL) - string = ""; - - main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view)); - if (main_frame != NULL) { - WebKitWebFrame *frame; - - frame = webkit_web_frame_find_frame (main_frame, frame_name); - - if (frame != NULL) - webkit_web_frame_load_string ( - frame, string, "text/html", - "UTF-8", "evo-file:///"); - } -} - -static void -web_view_frame_load_uri (EWebView *web_view, - const gchar *frame_name, - const gchar *uri) -{ - WebKitWebFrame *main_frame; - - if (uri == NULL) - uri = "about:blank"; - - main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view)); - if (main_frame != NULL) { - WebKitWebFrame *frame; - - frame = webkit_web_frame_find_frame (main_frame, frame_name); - - if (frame != NULL) - webkit_web_frame_load_uri (frame, uri); - } -} - -static gboolean -web_view_popup_event (EWebView *web_view, - const gchar *uri) -{ - e_web_view_set_selected_uri (web_view, uri); - e_web_view_show_popup_menu (web_view); - - return TRUE; -} - -static void -web_view_stop_loading (EWebView *web_view) -{ - webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view)); -} - -static void -web_view_update_actions (EWebView *web_view) -{ - GtkActionGroup *action_group; - gboolean can_copy; - gboolean scheme_is_http = FALSE; - gboolean scheme_is_mailto = FALSE; - gboolean uri_is_valid = FALSE; - gboolean has_cursor_image; - gboolean visible; - const gchar *group_name; - const gchar *uri; - - uri = e_web_view_get_selected_uri (web_view); - can_copy = webkit_web_view_can_copy_clipboard (WEBKIT_WEB_VIEW (web_view)); - has_cursor_image = e_web_view_get_cursor_image_src (web_view) || - e_web_view_get_cursor_image (web_view); - - /* Parse the URI early so we know if the actions will work. */ - if (uri != NULL) { - CamelURL *curl; - - curl = camel_url_new (uri, NULL); - uri_is_valid = (curl != NULL); - camel_url_free (curl); - - scheme_is_http = - (g_ascii_strncasecmp (uri, "http:", 5) == 0) || - (g_ascii_strncasecmp (uri, "https:", 6) == 0); - - scheme_is_mailto = - (g_ascii_strncasecmp (uri, "mailto:", 7) == 0); - } - - /* Allow copying the URI even if it's malformed. */ - group_name = "uri"; - visible = (uri != NULL) && !scheme_is_mailto; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "http"; - visible = uri_is_valid && scheme_is_http; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "mailto"; - visible = uri_is_valid && scheme_is_mailto; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "image"; - visible = has_cursor_image; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "selection"; - visible = can_copy; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "standard"; - visible = (uri == NULL); - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-printing"; - visible = (uri == NULL) && !web_view->priv->disable_printing; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-save-to-disk"; - visible = (uri == NULL) && !web_view->priv->disable_save_to_disk; - action_group = e_web_view_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); -} - -static void -web_view_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - EWebView *web_view; - GtkWidget *dialog; - GString *buffer; - const gchar *icon_name = NULL; - gpointer parent; - - web_view = E_WEB_VIEW (alert_sink); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - icon_name = GTK_STOCK_DIALOG_INFO; - break; - - case GTK_MESSAGE_WARNING: - icon_name = GTK_STOCK_DIALOG_WARNING; - break; - - case GTK_MESSAGE_ERROR: - icon_name = GTK_STOCK_DIALOG_ERROR; - break; - - default: - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - return; - } - - buffer = g_string_sized_new (512); - - g_string_append ( - buffer, - "<html>" - "<head>" - "<meta http-equiv=\"content-type\"" - " content=\"text/html; charset=utf-8\">" - "</head>" - "<body>"); - - g_string_append ( - buffer, - "<table bgcolor='#000000' width='100%'" - " cellpadding='1' cellspacing='0'>" - "<tr>" - "<td>" - "<table bgcolor='#dddddd' width='100%' cellpadding='6'>" - "<tr>"); - - g_string_append_printf ( - buffer, - "<tr>" - "<td valign='top'>" - "<img src='gtk-stock://%s/?size=%d'/>" - "</td>" - "<td align='left' width='100%%'>" - "<h3>%s</h3>" - "%s" - "</td>" - "</tr>", - icon_name, - GTK_ICON_SIZE_DIALOG, - e_alert_get_primary_text (alert), - e_alert_get_secondary_text (alert)); - - g_string_append ( - buffer, - "</table>" - "</td>" - "</tr>" - "</table>" - "</body>" - "</html>"); - - e_web_view_load_string (web_view, buffer->str); - - g_string_free (buffer, TRUE); -} - -static void -web_view_selectable_update_actions (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets) -{ - WebKitWebView *web_view; - GtkAction *action; - gboolean sensitive; - const gchar *tooltip; - - web_view = WEBKIT_WEB_VIEW (selectable); - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - sensitive = webkit_web_view_can_cut_clipboard (web_view); - tooltip = _("Cut the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - sensitive = webkit_web_view_can_copy_clipboard (web_view); - tooltip = _("Copy the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - sensitive = webkit_web_view_can_paste_clipboard (web_view); - tooltip = _("Paste the clipboard"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_select_all_action (focus_tracker); - sensitive = TRUE; - tooltip = _("Select all text and images"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); -} - -static void -web_view_selectable_cut_clipboard (ESelectable *selectable) -{ - e_web_view_cut_clipboard (E_WEB_VIEW (selectable)); -} - -static void -web_view_selectable_copy_clipboard (ESelectable *selectable) -{ - e_web_view_copy_clipboard (E_WEB_VIEW (selectable)); -} - -static void -web_view_selectable_paste_clipboard (ESelectable *selectable) -{ - e_web_view_paste_clipboard (E_WEB_VIEW (selectable)); -} - -static void -web_view_selectable_select_all (ESelectable *selectable) -{ - e_web_view_select_all (E_WEB_VIEW (selectable)); -} - -static gboolean -web_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_) -{ - return FALSE; -} - -static void -e_web_view_class_init (EWebViewClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (EWebViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = web_view_set_property; - object_class->get_property = web_view_get_property; - object_class->dispose = web_view_dispose; - object_class->finalize = web_view_finalize; - object_class->constructed = web_view_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->scroll_event = web_view_scroll_event; - widget_class->drag_motion = web_view_drag_motion; - -#if 0 /* WEBKIT */ - html_class = GTK_HTML_CLASS (class); - html_class->url_requested = web_view_url_requested; -#endif - - class->create_plugin_widget = web_view_create_plugin_widget; - class->extract_uri = web_view_extract_uri; - class->hovering_over_link = web_view_hovering_over_link; - class->link_clicked = web_view_link_clicked; - class->load_string = web_view_load_string; - class->load_uri = web_view_load_uri; - class->frame_load_string = web_view_frame_load_string; - class->frame_load_uri = web_view_frame_load_uri; - class->popup_event = web_view_popup_event; - class->stop_loading = web_view_stop_loading; - class->update_actions = web_view_update_actions; - - g_object_class_install_property ( - object_class, - PROP_CARET_MODE, - g_param_spec_boolean ( - "caret-mode", - "Caret Mode", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_IMAGE, - g_param_spec_object ( - "cursor-image", - "Image animation at the mouse cursor", - NULL, - GDK_TYPE_PIXBUF_ANIMATION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_IMAGE_SRC, - g_param_spec_string ( - "cursor-image-src", - "Image source uri at the mouse cursor", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_PRINTING, - g_param_spec_boolean ( - "disable-printing", - "Disable Printing", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_SAVE_TO_DISK, - g_param_spec_boolean ( - "disable-save-to-disk", - "Disable Save-to-Disk", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_INLINE_SPELLING, - g_param_spec_boolean ( - "inline-spelling", - "Inline Spelling", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_LINKS, - g_param_spec_boolean ( - "magic-links", - "Magic Links", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_SMILEYS, - g_param_spec_boolean ( - "magic-smileys", - "Magic Smileys", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_OPEN_PROXY, - g_param_spec_object ( - "open-proxy", - "Open Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_PRINT_PROXY, - g_param_spec_object ( - "print-proxy", - "Print Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SAVE_AS_PROXY, - g_param_spec_object ( - "save-as-proxy", - "Save As Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTED_URI, - g_param_spec_string ( - "selected-uri", - "Selected URI", - NULL, - NULL, - G_PARAM_READWRITE)); - - signals[POPUP_EVENT] = g_signal_new ( - "popup-event", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewClass, popup_event), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, G_TYPE_STRING); - - signals[STATUS_MESSAGE] = g_signal_new ( - "status-message", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewClass, status_message), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - signals[STOP_LOADING] = g_signal_new ( - "stop-loading", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewClass, stop_loading), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UPDATE_ACTIONS] = g_signal_new ( - "update-actions", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewClass, update_actions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* return TRUE when a signal handler processed the mailto URI */ - signals[PROCESS_MAILTO] = g_signal_new ( - "process-mailto", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewClass, process_mailto), - NULL, NULL, - e_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, G_TYPE_STRING); -} - -static void -e_web_view_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = web_view_submit_alert; -} - -static void -e_web_view_selectable_init (ESelectableInterface *interface) -{ - interface->update_actions = web_view_selectable_update_actions; - interface->cut_clipboard = web_view_selectable_cut_clipboard; - interface->copy_clipboard = web_view_selectable_copy_clipboard; - interface->paste_clipboard = web_view_selectable_paste_clipboard; - interface->select_all = web_view_selectable_select_all; -} - -static void -e_web_view_init (EWebView *web_view) -{ - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - EPopupAction *popup_action; - WebKitWebSettings *web_settings; - GSettingsSchema *settings_schema; - GSettings *settings; - const gchar *domain = GETTEXT_PACKAGE; - const gchar *id; - GError *error = NULL; - - web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view); - - web_view->priv->highlights = NULL; - - g_signal_connect ( - web_view, "create-plugin-widget", - G_CALLBACK (web_view_create_plugin_widget_cb), NULL); - - g_signal_connect ( - web_view, "hovering-over-link", - G_CALLBACK (web_view_hovering_over_link_cb), NULL); - - g_signal_connect ( - web_view, "navigation-policy-decision-requested", - G_CALLBACK (web_view_navigation_policy_decision_requested_cb), - NULL); - - g_signal_connect ( - web_view, "new-window-policy-decision-requested", - G_CALLBACK (web_view_navigation_policy_decision_requested_cb), - NULL); - - g_signal_connect ( - web_view, "context-menu", - G_CALLBACK (web_view_context_menu_cb), NULL); - - g_signal_connect ( - web_view, "notify::load-status", - G_CALLBACK (web_view_load_status_changed_cb), NULL); - - ui_manager = gtk_ui_manager_new (); - web_view->priv->ui_manager = ui_manager; - - g_signal_connect_swapped ( - ui_manager, "connect-proxy", - G_CALLBACK (web_view_connect_proxy_cb), web_view); - - web_settings = e_web_view_get_default_settings (); - e_web_view_set_settings (web_view, web_settings); - g_object_unref (web_settings); - - e_web_view_install_request_handler (web_view, E_TYPE_FILE_REQUEST); - e_web_view_install_request_handler (web_view, E_TYPE_STOCK_REQUEST); - - settings = g_settings_new ("org.gnome.desktop.interface"); - g_signal_connect_swapped ( - settings, "changed::font-name", - G_CALLBACK (e_web_view_update_fonts), web_view); - g_signal_connect_swapped ( - settings, "changed::monospace-font-name", - G_CALLBACK (e_web_view_update_fonts), web_view); - web_view->priv->font_settings = settings; - - /* This schema is optional. Use if available. */ - id = "org.gnome.settings-daemon.plugins.xsettings"; - settings_schema = g_settings_schema_source_lookup ( - g_settings_schema_source_get_default (), id, FALSE); - if (settings_schema != NULL) { - settings = g_settings_new (id); - g_signal_connect_swapped ( - settings, "changed::antialiasing", - G_CALLBACK (e_web_view_update_fonts), web_view); - web_view->priv->aliasing_settings = settings; - } - - e_web_view_update_fonts (web_view); - - action_group = gtk_action_group_new ("uri"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, uri_entries, - G_N_ELEMENTS (uri_entries), web_view); - - action_group = gtk_action_group_new ("http"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, http_entries, - G_N_ELEMENTS (http_entries), web_view); - - action_group = gtk_action_group_new ("mailto"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, mailto_entries, - G_N_ELEMENTS (mailto_entries), web_view); - - action_group = gtk_action_group_new ("image"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, image_entries, - G_N_ELEMENTS (image_entries), web_view); - - action_group = gtk_action_group_new ("selection"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, selection_entries, - G_N_ELEMENTS (selection_entries), web_view); - - action_group = gtk_action_group_new ("standard"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), web_view); - - popup_action = e_popup_action_new ("open"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "open-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Support lockdown. */ - - action_group = gtk_action_group_new ("lockdown-printing"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("print"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "print-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - action_group = gtk_action_group_new ("lockdown-save-to-disk"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("save-as"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "save-as-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here implies a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); - - id = "org.gnome.evolution.webview"; - e_plugin_ui_register_manager (ui_manager, id, web_view); - e_plugin_ui_enable_manager (ui_manager, id); -} - -GtkWidget * -e_web_view_new (void) -{ - return g_object_new (E_TYPE_WEB_VIEW, NULL); -} - -void -e_web_view_clear (EWebView *web_view) -{ - GtkStyle *style; - gchar *html; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - style = gtk_widget_get_style (GTK_WIDGET (web_view)); - - html = g_strdup_printf ( - "<html><head></head><body bgcolor=\"#%06x\"></body></html>", - e_color_to_value (&style->base[GTK_STATE_NORMAL])); - - webkit_web_view_load_html_string ( - WEBKIT_WEB_VIEW (web_view), html, NULL); - - g_free (html); -} - -void -e_web_view_load_string (EWebView *web_view, - const gchar *string) -{ - EWebViewClass *class; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_if_fail (class->load_string != NULL); - - class->load_string (web_view, string); -} - -void -e_web_view_load_uri (EWebView *web_view, - const gchar *uri) -{ - EWebViewClass *class; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_if_fail (class->load_uri != NULL); - - class->load_uri (web_view, uri); -} - -void -e_web_view_reload (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view)); -} - -const gchar * -e_web_view_get_uri (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return webkit_web_view_get_uri (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_frame_load_string (EWebView *web_view, - const gchar *frame_name, - const gchar *string) -{ - EWebViewClass *class; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - g_return_if_fail (frame_name != NULL); - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_if_fail (class->frame_load_string != NULL); - - class->frame_load_string (web_view, frame_name, string); -} - -void -e_web_view_frame_load_uri (EWebView *web_view, - const gchar *frame_name, - const gchar *uri) -{ - EWebViewClass *class; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - g_return_if_fail (frame_name != NULL); - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_if_fail (class->frame_load_uri != NULL); - - class->frame_load_uri (web_view, frame_name, uri); -} - -const gchar * -e_web_view_frame_get_uri (EWebView *web_view, - const gchar *frame_name) -{ - WebKitWebFrame *main_frame; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - g_return_val_if_fail (frame_name != NULL, NULL); - - main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view)); - if (main_frame != NULL) { - WebKitWebFrame *frame; - - frame = webkit_web_frame_find_frame (main_frame, frame_name); - - if (frame != NULL) - return webkit_web_frame_get_uri (frame); - } - - return NULL; -} - -gchar * -e_web_view_get_html (EWebView *web_view) -{ - WebKitDOMDocument *document; - WebKitDOMElement *element; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view)); - element = webkit_dom_document_get_document_element (document); - - return webkit_dom_html_element_get_outer_html ( - WEBKIT_DOM_HTML_ELEMENT (element)); -} - -gboolean -e_web_view_get_caret_mode (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->caret_mode; -} - -void -e_web_view_set_caret_mode (EWebView *web_view, - gboolean caret_mode) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->caret_mode == caret_mode) - return; - - web_view->priv->caret_mode = caret_mode; - - g_object_notify (G_OBJECT (web_view), "caret-mode"); -} - -GtkTargetList * -e_web_view_get_copy_target_list (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return webkit_web_view_get_copy_target_list ( - WEBKIT_WEB_VIEW (web_view)); -} - -gboolean -e_web_view_get_disable_printing (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->disable_printing; -} - -void -e_web_view_set_disable_printing (EWebView *web_view, - gboolean disable_printing) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->disable_printing == disable_printing) - return; - - web_view->priv->disable_printing = disable_printing; - - g_object_notify (G_OBJECT (web_view), "disable-printing"); -} - -gboolean -e_web_view_get_disable_save_to_disk (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->disable_save_to_disk; -} - -void -e_web_view_set_disable_save_to_disk (EWebView *web_view, - gboolean disable_save_to_disk) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->disable_save_to_disk == disable_save_to_disk) - return; - - web_view->priv->disable_save_to_disk = disable_save_to_disk; - - g_object_notify (G_OBJECT (web_view), "disable-save-to-disk"); -} - -gboolean -e_web_view_get_enable_frame_flattening (EWebView *web_view) -{ - WebKitWebSettings *settings; - gboolean flattening; - - /* Return TRUE with fail since it's default value we set in _init(). */ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), TRUE); - - settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view)); - g_return_val_if_fail (settings != NULL, TRUE); - - g_object_get ( - G_OBJECT (settings), - "enable-frame-flattening", &flattening, NULL); - - return flattening; -} - -void -e_web_view_set_enable_frame_flattening (EWebView *web_view, - gboolean enable_frame_flattening) -{ - WebKitWebSettings *settings; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view)); - g_return_if_fail (settings != NULL); - - g_object_set ( - G_OBJECT (settings), "enable-frame-flattening", - enable_frame_flattening, NULL); -} - -gboolean -e_web_view_get_editable (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return webkit_web_view_get_editable (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_set_editable (EWebView *web_view, - gboolean editable) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_set_editable (WEBKIT_WEB_VIEW (web_view), editable); -} - -gboolean -e_web_view_get_inline_spelling (EWebView *web_view) -{ -#if 0 /* WEBKIT - XXX No equivalent property? */ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_inline_spelling(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return gtk_html_get_inline_spelling (GTK_HTML (web_view)); -#endif - - return FALSE; -} - -void -e_web_view_set_inline_spelling (EWebView *web_view, - gboolean inline_spelling) -{ -#if 0 /* WEBKIT - XXX No equivalent property? */ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_inline_spelling() - * so we get a "notify::inline-spelling" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - gtk_html_set_inline_spelling (GTK_HTML (web_view), inline_spelling); - - g_object_notify (G_OBJECT (web_view), "inline-spelling"); -#endif -} - -gboolean -e_web_view_get_magic_links (EWebView *web_view) -{ -#if 0 /* WEBKIT - XXX No equivalent property? */ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_links(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return gtk_html_get_magic_links (GTK_HTML (web_view)); -#endif - - return FALSE; -} - -void -e_web_view_set_magic_links (EWebView *web_view, - gboolean magic_links) -{ -#if 0 /* WEBKIT - XXX No equivalent property? */ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_links() - * so we can get a "notify::magic-links" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - gtk_html_set_magic_links (GTK_HTML (web_view), magic_links); - - g_object_notify (G_OBJECT (web_view), "magic-links"); -#endif -} - -gboolean -e_web_view_get_magic_smileys (EWebView *web_view) -{ -#if 0 /* WEBKIT - No equivalent property? */ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_smileys(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return gtk_html_get_magic_smileys (GTK_HTML (web_view)); -#endif - - return FALSE; -} - -void -e_web_view_set_magic_smileys (EWebView *web_view, - gboolean magic_smileys) -{ -#if 0 /* WEBKIT - No equivalent property? */ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_smileys() - * so we can get a "notify::magic-smileys" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - gtk_html_set_magic_smileys (GTK_HTML (web_view), magic_smileys); - - g_object_notify (G_OBJECT (web_view), "magic-smileys"); -#endif -} - -const gchar * -e_web_view_get_selected_uri (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return web_view->priv->selected_uri; -} - -void -e_web_view_set_selected_uri (EWebView *web_view, - const gchar *selected_uri) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (g_strcmp0 (web_view->priv->selected_uri, selected_uri) == 0) - return; - - g_free (web_view->priv->selected_uri); - web_view->priv->selected_uri = g_strdup (selected_uri); - - g_object_notify (G_OBJECT (web_view), "selected-uri"); -} - -GdkPixbufAnimation * -e_web_view_get_cursor_image (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return web_view->priv->cursor_image; -} - -void -e_web_view_set_cursor_image (EWebView *web_view, - GdkPixbufAnimation *image) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->cursor_image == image) - return; - - if (image != NULL) - g_object_ref (image); - - if (web_view->priv->cursor_image != NULL) - g_object_unref (web_view->priv->cursor_image); - - web_view->priv->cursor_image = image; - - g_object_notify (G_OBJECT (web_view), "cursor-image"); -} - -const gchar * -e_web_view_get_cursor_image_src (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return web_view->priv->cursor_image_src; -} - -void -e_web_view_set_cursor_image_src (EWebView *web_view, - const gchar *src_uri) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (g_strcmp0 (web_view->priv->cursor_image_src, src_uri) == 0) - return; - - g_free (web_view->priv->cursor_image_src); - web_view->priv->cursor_image_src = g_strdup (src_uri); - - g_object_notify (G_OBJECT (web_view), "cursor-image-src"); -} - -GtkAction * -e_web_view_get_open_proxy (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->open_proxy; -} - -void -e_web_view_set_open_proxy (EWebView *web_view, - GtkAction *open_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->open_proxy == open_proxy) - return; - - if (open_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (open_proxy)); - g_object_ref (open_proxy); - } - - if (web_view->priv->open_proxy != NULL) - g_object_unref (web_view->priv->open_proxy); - - web_view->priv->open_proxy = open_proxy; - - g_object_notify (G_OBJECT (web_view), "open-proxy"); -} - -GtkTargetList * -e_web_view_get_paste_target_list (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return webkit_web_view_get_paste_target_list ( - WEBKIT_WEB_VIEW (web_view)); -} - -GtkAction * -e_web_view_get_print_proxy (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->print_proxy; -} - -void -e_web_view_set_print_proxy (EWebView *web_view, - GtkAction *print_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->print_proxy == print_proxy) - return; - - if (print_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (print_proxy)); - g_object_ref (print_proxy); - } - - if (web_view->priv->print_proxy != NULL) - g_object_unref (web_view->priv->print_proxy); - - web_view->priv->print_proxy = print_proxy; - - g_object_notify (G_OBJECT (web_view), "print-proxy"); -} - -GtkAction * -e_web_view_get_save_as_proxy (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return web_view->priv->save_as_proxy; -} - -void -e_web_view_set_save_as_proxy (EWebView *web_view, - GtkAction *save_as_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (web_view->priv->save_as_proxy == save_as_proxy) - return; - - if (save_as_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (save_as_proxy)); - g_object_ref (save_as_proxy); - } - - if (web_view->priv->save_as_proxy != NULL) - g_object_unref (web_view->priv->save_as_proxy); - - web_view->priv->save_as_proxy = save_as_proxy; - - g_object_notify (G_OBJECT (web_view), "save-as-proxy"); -} - -GSList * -e_web_view_get_highlights (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return web_view->priv->highlights; -} - -void -e_web_view_add_highlight (EWebView *web_view, - const gchar *highlight) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - g_return_if_fail (highlight && *highlight); - - web_view->priv->highlights = g_slist_append ( - web_view->priv->highlights, g_strdup (highlight)); - - web_view_update_document_highlights (web_view); -} - -void e_web_view_clear_highlights (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (!web_view->priv->highlights) - return; - - g_slist_free_full (web_view->priv->highlights, g_free); - web_view->priv->highlights = NULL; - - web_view_update_document_highlights (web_view); -} - -GtkAction * -e_web_view_get_action (EWebView *web_view, - const gchar *action_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - g_return_val_if_fail (action_name != NULL, NULL); - - ui_manager = e_web_view_get_ui_manager (web_view); - - return e_lookup_action (ui_manager, action_name); -} - -GtkActionGroup * -e_web_view_get_action_group (EWebView *web_view, - const gchar *group_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_web_view_get_ui_manager (web_view); - - return e_lookup_action_group (ui_manager, group_name); -} - -gchar * -e_web_view_extract_uri (EWebView *web_view, - GdkEventButton *event) -{ - EWebViewClass *class; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - class = E_WEB_VIEW_GET_CLASS (web_view); - g_return_val_if_fail (class->extract_uri != NULL, NULL); - - return class->extract_uri (web_view, event); -} - -void -e_web_view_copy_clipboard (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_copy_clipboard (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_cut_clipboard (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_cut_clipboard (WEBKIT_WEB_VIEW (web_view)); -} - -gboolean -e_web_view_is_selection_active (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - return webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_paste_clipboard (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_paste_clipboard (WEBKIT_WEB_VIEW (web_view)); -} - -gboolean -e_web_view_scroll_forward (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - webkit_web_view_move_cursor ( - WEBKIT_WEB_VIEW (web_view), GTK_MOVEMENT_PAGES, 1); - - return TRUE; /* XXX This means nothing. */ -} - -gboolean -e_web_view_scroll_backward (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE); - - webkit_web_view_move_cursor ( - WEBKIT_WEB_VIEW (web_view), GTK_MOVEMENT_PAGES, -1); - - return TRUE; /* XXX This means nothing. */ -} - -void -e_web_view_select_all (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_select_all (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_unselect_all (EWebView *web_view) -{ -#if 0 /* WEBKIT */ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - gtk_html_command (GTK_HTML (web_view), "unselect-all"); -#endif -} - -void -e_web_view_zoom_100 (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), 1.0); -} - -void -e_web_view_zoom_in (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (web_view)); -} - -void -e_web_view_zoom_out (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (web_view)); -} - -GtkUIManager * -e_web_view_get_ui_manager (EWebView *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - return web_view->priv->ui_manager; -} - -GtkWidget * -e_web_view_get_popup_menu (EWebView *web_view) -{ - GtkUIManager *ui_manager; - GtkWidget *menu; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - ui_manager = e_web_view_get_ui_manager (web_view); - menu = gtk_ui_manager_get_widget (ui_manager, "/context"); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu; -} - -void -e_web_view_show_popup_menu (EWebView *web_view) -{ - GtkWidget *menu; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - e_web_view_update_actions (web_view); - - menu = e_web_view_get_popup_menu (web_view); - - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, - 0, gtk_get_current_event_time ()); -} - -void -e_web_view_status_message (EWebView *web_view, - const gchar *status_message) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - g_signal_emit (web_view, signals[STATUS_MESSAGE], 0, status_message); -} - -void -e_web_view_stop_loading (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - g_signal_emit (web_view, signals[STOP_LOADING], 0); -} - -void -e_web_view_update_actions (EWebView *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - g_signal_emit (web_view, signals[UPDATE_ACTIONS], 0); -} - -static gchar * -web_view_get_frame_selection_html (WebKitDOMElement *iframe) -{ - WebKitDOMDocument *document; - WebKitDOMDOMWindow *window; - WebKitDOMDOMSelection *selection; - WebKitDOMNodeList *frames; - gulong ii, length; - - document = webkit_dom_html_iframe_element_get_content_document ( - WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe)); - window = webkit_dom_document_get_default_view (document); - selection = webkit_dom_dom_window_get_selection (window); - if (selection && (webkit_dom_dom_selection_get_range_count (selection) > 0)) { - WebKitDOMRange *range; - WebKitDOMElement *element; - WebKitDOMDocumentFragment *fragment; - - range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL); - if (range != NULL) { - fragment = webkit_dom_range_clone_contents ( - range, NULL); - - element = webkit_dom_document_create_element ( - document, "DIV", NULL); - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (element), - WEBKIT_DOM_NODE (fragment), NULL); - - return webkit_dom_html_element_get_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (element)); - } - } - - frames = webkit_dom_document_get_elements_by_tag_name ( - document, "IFRAME"); - length = webkit_dom_node_list_get_length (frames); - for (ii = 0; ii < length; ii++) { - WebKitDOMNode *node; - gchar *text; - - node = webkit_dom_node_list_item (frames, ii); - - text = web_view_get_frame_selection_html ( - WEBKIT_DOM_ELEMENT (node)); - - if (text != NULL) - return text; - } - - return NULL; -} - -gchar * -e_web_view_get_selection_html (EWebView *web_view) -{ - WebKitDOMDocument *document; - WebKitDOMNodeList *frames; - gulong ii, length; - - g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); - - if (!webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view))) - return NULL; - - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view)); - frames = webkit_dom_document_get_elements_by_tag_name (document, "IFRAME"); - length = webkit_dom_node_list_get_length (frames); - - for (ii = 0; ii < length; ii++) { - gchar *text; - WebKitDOMNode *node; - - node = webkit_dom_node_list_item (frames, ii); - - text = web_view_get_frame_selection_html ( - WEBKIT_DOM_ELEMENT (node)); - - if (text != NULL) - return text; - } - - return NULL; -} - -void -e_web_view_set_settings (EWebView *web_view, - WebKitWebSettings *settings) -{ - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - if (settings == webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view))) - return; - - g_object_bind_property ( - settings, "enable-caret-browsing", - web_view, "caret-mode", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - webkit_web_view_set_settings (WEBKIT_WEB_VIEW (web_view), settings); -} - -WebKitWebSettings * -e_web_view_get_default_settings (void) -{ - WebKitWebSettings *settings; - - settings = webkit_web_settings_new (); - - g_object_set ( - G_OBJECT (settings), - "enable-frame-flattening", TRUE, - "enable-java-applet", FALSE, - "enable-html5-database", FALSE, - "enable-html5-local-storage", FALSE, - "enable-offline-web-application-cache", FALSE, - "enable-site-specific-quirks", TRUE, - "enable-scripts", FALSE, - NULL); - - return settings; -} - -void -e_web_view_update_fonts (EWebView *web_view) -{ - EWebViewClass *class; - GString *stylesheet; - gchar *base64; - gchar *aa = NULL; - WebKitWebSettings *settings; - PangoFontDescription *min_size, *ms, *vw; - const gchar *styles[] = { "normal", "oblique", "italic" }; - const gchar *smoothing = NULL; - GtkStyleContext *context; - GdkColor *link = NULL; - GdkColor *visited = NULL; - - g_return_if_fail (E_IS_WEB_VIEW (web_view)); - - ms = NULL; - vw = NULL; - - class = E_WEB_VIEW_GET_CLASS (web_view); - if (class->set_fonts != NULL) - class->set_fonts (web_view, &ms, &vw); - - if (ms == NULL) { - gchar *font; - - font = g_settings_get_string ( - web_view->priv->font_settings, - "monospace-font-name"); - - ms = pango_font_description_from_string ( - (font != NULL) ? font : "monospace 10"); - - g_free (font); - } - - if (vw == NULL) { - gchar *font; - - font = g_settings_get_string ( - web_view->priv->font_settings, - "font-name"); - - vw = pango_font_description_from_string ( - (font != NULL) ? font : "serif 10"); - - g_free (font); - } - - if (pango_font_description_get_size (ms) < pango_font_description_get_size (vw)) { - min_size = ms; - } else { - min_size = vw; - } - - stylesheet = g_string_new (""); - g_string_append_printf ( - stylesheet, - "body {\n" - " font-family: '%s';\n" - " font-size: %dpt;\n" - " font-weight: %d;\n" - " font-style: %s;\n", - pango_font_description_get_family (vw), - pango_font_description_get_size (vw) / PANGO_SCALE, - pango_font_description_get_weight (vw), - styles[pango_font_description_get_style (vw)]); - - if (web_view->priv->aliasing_settings != NULL) - aa = g_settings_get_string ( - web_view->priv->aliasing_settings, "antialiasing"); - - if (g_strcmp0 (aa, "none") == 0) - smoothing = "none"; - else if (g_strcmp0 (aa, "grayscale") == 0) - smoothing = "antialiased"; - else if (g_strcmp0 (aa, "rgba") == 0) - smoothing = "subpixel-antialiased"; - - if (smoothing != NULL) - g_string_append_printf ( - stylesheet, - " -webkit-font-smoothing: %s;\n", - smoothing); - - g_free (aa); - - g_string_append (stylesheet, "}\n"); - - g_string_append_printf ( - stylesheet, - "pre,code,.pre {\n" - " font-family: '%s';\n" - " font-size: %dpt;\n" - " font-weight: %d;\n" - " font-style: %s;\n" - "}", - pango_font_description_get_family (ms), - pango_font_description_get_size (ms) / PANGO_SCALE, - pango_font_description_get_weight (ms), - styles[pango_font_description_get_style (ms)]); - - context = gtk_widget_get_style_context (GTK_WIDGET (web_view)); - gtk_style_context_get_style ( - context, - "link-color", &link, - "visited-link-color", &visited, - NULL); - - if (link == NULL) { - link = g_slice_new0 (GdkColor); - link->blue = G_MAXINT16; - } - - if (visited == NULL) { - visited = g_slice_new0 (GdkColor); - visited->red = G_MAXINT16; - } - - g_string_append_printf ( - stylesheet, - "a {\n" - " color: #%06x;\n" - "}\n" - "a:visited {\n" - " color: #%06x;\n" - "}\n", - e_color_to_value (link), - e_color_to_value (visited)); - - gdk_color_free (link); - gdk_color_free (visited); - - base64 = g_base64_encode ((guchar *) stylesheet->str, stylesheet->len); - g_string_free (stylesheet, TRUE); - - stylesheet = g_string_new ("data:text/css;charset=utf-8;base64,"); - g_string_append (stylesheet, base64); - g_free (base64); - - settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view)); - g_object_set ( - G_OBJECT (settings), - "default-font-size", pango_font_description_get_size (vw) / PANGO_SCALE, - "default-font-family", pango_font_description_get_family (vw), - "monospace-font-family", pango_font_description_get_family (ms), - "default-monospace-font-size", (pango_font_description_get_size (ms) / PANGO_SCALE), - "minimum-font-size", (pango_font_description_get_size (min_size) / PANGO_SCALE), - "user-stylesheet-uri", stylesheet->str, - NULL); - - g_string_free (stylesheet, TRUE); - - pango_font_description_free (ms); - pango_font_description_free (vw); -} - -void -e_web_view_install_request_handler (EWebView *web_view, - GType handler_type) -{ - SoupSession *session; - SoupSessionFeature *feature; - gboolean new; - - session = webkit_get_default_session (); - - feature = soup_session_get_feature (session, SOUP_TYPE_REQUESTER); - new = FALSE; - if (feature == NULL) { - feature = SOUP_SESSION_FEATURE (soup_requester_new ()); - soup_session_add_feature (session, feature); - new = TRUE; - } - - soup_session_feature_add_feature (feature, handler_type); - - if (new) { - g_object_unref (feature); - } -} - diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h deleted file mode 100644 index fe17d621c0..0000000000 --- a/widgets/misc/e-web-view.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * e-web-view.h - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -/* This is intended to serve as a common base class for all HTML viewing - * needs in Evolution. Currently based on GtkHTML, the idea is to wrap - * the GtkHTML API enough that we no longer have to make direct calls to - * it. This should help smooth the transition to WebKit/GTK+. - * - * This class handles basic tasks like mouse hovers over links, clicked - * links, and servicing URI requests asynchronously via GIO. */ - -#ifndef E_WEB_VIEW_H -#define E_WEB_VIEW_H - -#include <webkit/webkit.h> - -/* Standard GObject macros */ -#define E_TYPE_WEB_VIEW \ - (e_web_view_get_type ()) -#define E_WEB_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_WEB_VIEW, EWebView)) -#define E_WEB_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_WEB_VIEW, EWebViewClass)) -#define E_IS_WEB_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_WEB_VIEW)) -#define E_IS_WEB_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_WEB_VIEW)) -#define E_WEB_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_WEB_VIEW, EWebViewClass)) - -G_BEGIN_DECLS - -typedef struct _EWebView EWebView; -typedef struct _EWebViewClass EWebViewClass; -typedef struct _EWebViewPrivate EWebViewPrivate; -struct PangoFontDescription; - -struct _EWebView { - WebKitWebView parent; - EWebViewPrivate *priv; -}; - -typedef void (*EWebViewJSFunctionCallback) (EWebView *web_view, - size_t arg_count, - const JSValueRef args[], - gpointer user_data); - -struct _EWebViewClass { - WebKitWebViewClass parent_class; - - /* Methods */ - GtkWidget * (*create_plugin_widget) (EWebView *web_view, - const gchar *mime_type, - const gchar *uri, - GHashTable *param); - gchar * (*extract_uri) (EWebView *web_view, - GdkEventButton *event); - void (*hovering_over_link) (EWebView *web_view, - const gchar *title, - const gchar *uri); - void (*link_clicked) (EWebView *web_view, - const gchar *uri); - void (*load_string) (EWebView *web_view, - const gchar *load_string); - void (*load_uri) (EWebView *web_view, - const gchar *load_uri); - void (*frame_load_string) (EWebView *web_view, - const gchar *frame_name, - const gchar *string); - void (*frame_load_uri) (EWebView *web_view, - const gchar *frame_name, - const gchar *uri); - void (*set_fonts) (EWebView *web_view, - PangoFontDescription **monospace, - PangoFontDescription **variable_width); - - /* Signals */ - gboolean (*popup_event) (EWebView *web_view, - const gchar *uri); - void (*status_message) (EWebView *web_view, - const gchar *status_message); - void (*stop_loading) (EWebView *web_view); - void (*update_actions) (EWebView *web_view); - gboolean (*process_mailto) (EWebView *web_view, - const gchar *mailto_uri); -}; - -GType e_web_view_get_type (void); -GtkWidget * e_web_view_new (void); -void e_web_view_clear (EWebView *web_view); -void e_web_view_load_string (EWebView *web_view, - const gchar *string); -void e_web_view_load_uri (EWebView *web_view, - const gchar *uri); -const gchar * e_web_view_get_uri (EWebView *web_view); -void e_web_view_reload (EWebView *web_view); -void e_web_view_frame_load_string (EWebView *web_view, - const gchar *frame_name, - const gchar *string); -void e_web_view_frame_load_uri (EWebView *web_view, - const gchar *frame_name, - const gchar *uri); -const gchar * e_web_view_frame_get_uri (EWebView *web_view, - const gchar *frame_name); -gchar * e_web_view_get_html (EWebView *web_view); -gboolean e_web_view_get_caret_mode (EWebView *web_view); -void e_web_view_set_caret_mode (EWebView *web_view, - gboolean caret_mode); -GtkTargetList * e_web_view_get_copy_target_list (EWebView *web_view); -gboolean e_web_view_get_disable_printing (EWebView *web_view); -void e_web_view_set_disable_printing (EWebView *web_view, - gboolean disable_printing); -gboolean e_web_view_get_disable_save_to_disk - (EWebView *web_view); -void e_web_view_set_disable_save_to_disk - (EWebView *web_view, - gboolean disable_save_to_disk); -gboolean e_web_view_get_enable_frame_flattening - (EWebView *web_view); -void e_web_view_set_enable_frame_flattening - (EWebView *web_view, - gboolean enable_frame_flattening); -gboolean e_web_view_get_editable (EWebView *web_view); -void e_web_view_set_editable (EWebView *web_view, - gboolean editable); -gboolean e_web_view_get_inline_spelling (EWebView *web_view); -void e_web_view_set_inline_spelling (EWebView *web_view, - gboolean inline_spelling); -gboolean e_web_view_get_magic_links (EWebView *web_view); -void e_web_view_set_magic_links (EWebView *web_view, - gboolean magic_links); -gboolean e_web_view_get_magic_smileys (EWebView *web_view); -void e_web_view_set_magic_smileys (EWebView *web_view, - gboolean magic_smileys); -const gchar * e_web_view_get_selected_uri (EWebView *web_view); -void e_web_view_set_selected_uri (EWebView *web_view, - const gchar *selected_uri); -GdkPixbufAnimation * - e_web_view_get_cursor_image (EWebView *web_view); -void e_web_view_set_cursor_image (EWebView *web_view, - GdkPixbufAnimation *animation); -const gchar * e_web_view_get_cursor_image_src (EWebView *web_view); -void e_web_view_set_cursor_image_src (EWebView *web_view, - const gchar *src_uri); -GtkAction * e_web_view_get_open_proxy (EWebView *web_view); -void e_web_view_set_open_proxy (EWebView *web_view, - GtkAction *open_proxy); -GtkTargetList * e_web_view_get_paste_target_list - (EWebView *web_view); -GtkAction * e_web_view_get_print_proxy (EWebView *web_view); -void e_web_view_set_print_proxy (EWebView *web_view, - GtkAction *print_proxy); -GtkAction * e_web_view_get_save_as_proxy (EWebView *web_view); -void e_web_view_set_save_as_proxy (EWebView *web_view, - GtkAction *save_as_proxy); -GSList * e_web_view_get_highlights (EWebView *web_view); -void e_web_view_add_highlight (EWebView *web_view, - const gchar *highlight); -void e_web_view_clear_highlights (EWebView *web_view); -GtkAction * e_web_view_get_action (EWebView *web_view, - const gchar *action_name); -GtkActionGroup *e_web_view_get_action_group (EWebView *web_view, - const gchar *group_name); -gchar * e_web_view_extract_uri (EWebView *web_view, - GdkEventButton *event); -void e_web_view_copy_clipboard (EWebView *web_view); -void e_web_view_cut_clipboard (EWebView *web_view); -gboolean e_web_view_is_selection_active (EWebView *web_view); -void e_web_view_paste_clipboard (EWebView *web_view); -gboolean e_web_view_scroll_forward (EWebView *web_view); -gboolean e_web_view_scroll_backward (EWebView *web_view); -void e_web_view_select_all (EWebView *web_view); -void e_web_view_unselect_all (EWebView *web_view); -void e_web_view_zoom_100 (EWebView *web_view); -void e_web_view_zoom_in (EWebView *web_view); -void e_web_view_zoom_out (EWebView *web_view); -GtkUIManager * e_web_view_get_ui_manager (EWebView *web_view); -GtkWidget * e_web_view_get_popup_menu (EWebView *web_view); -void e_web_view_show_popup_menu (EWebView *web_view); -void e_web_view_status_message (EWebView *web_view, - const gchar *status_message); -void e_web_view_stop_loading (EWebView *web_view); -void e_web_view_update_actions (EWebView *web_view); -gchar * e_web_view_get_selection_html (EWebView *web_view); - -void e_web_view_set_settings (EWebView *web_view, - WebKitWebSettings *settings); - -void e_web_view_update_fonts (EWebView *web_view); - -WebKitWebSettings * - e_web_view_get_default_settings (void); - -void e_web_view_install_request_handler - (EWebView *web_view, - GType handler_type); - -G_END_DECLS - -#endif /* E_WEB_VIEW_H */ diff --git a/widgets/misc/ea-calendar-cell.c b/widgets/misc/ea-calendar-cell.c deleted file mode 100644 index 90a889ef18..0000000000 --- a/widgets/misc/ea-calendar-cell.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <e-util/e-util.h> -#include "ea-calendar-cell.h" -#include "ea-calendar-item.h" -#include "a11y/ea-factory.h" - -/* ECalendarCell */ - -static void e_calendar_cell_class_init (ECalendarCellClass *class); - -EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new) - -GType -e_calendar_cell_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (ECalendarCellClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) e_calendar_cell_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (ECalendarCell), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) NULL, /* instance init */ - NULL /* value table */ - }; - - type = g_type_register_static ( - G_TYPE_OBJECT, - "ECalendarCell", &tinfo, 0); - } - - return type; -} - -static void -e_calendar_cell_class_init (ECalendarCellClass *class) -{ - EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell); -} - -ECalendarCell * -e_calendar_cell_new (ECalendarItem *calitem, - gint row, - gint column) -{ - GObject *object; - ECalendarCell *cell; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL); - - object = g_object_new (E_TYPE_CALENDAR_CELL, NULL); - cell = E_CALENDAR_CELL (object); - cell->calitem = calitem; - cell->row = row; - cell->column = column; - -#ifdef ACC_DEBUG - g_print ("EvoAcc: e_calendar_cell created %p\n", (gpointer) cell); -#endif - - return cell; -} - -/* EaCalendarCell */ - -static void ea_calendar_cell_class_init (EaCalendarCellClass *klass); -static void ea_calendar_cell_init (EaCalendarCell *a11y); - -static const gchar * ea_calendar_cell_get_name (AtkObject *accessible); -static const gchar * ea_calendar_cell_get_description (AtkObject *accessible); -static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible); -static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible); -static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible); - -/* component interface */ -static void atk_component_interface_init (AtkComponentIface *iface); -static void component_interface_get_extents (AtkComponent *component, - gint *x, gint *y, - gint *width, gint *height, - AtkCoordType coord_type); -static gboolean component_interface_grab_focus (AtkComponent *component); - -static gpointer parent_class = NULL; - -#ifdef ACC_DEBUG -static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0; -static void ea_calendar_cell_finalize (GObject *object); -#endif - -GType -ea_calendar_cell_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (EaCalendarCellClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) ea_calendar_cell_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (EaCalendarCell), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) ea_calendar_cell_init, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) atk_component_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static ( - ATK_TYPE_GOBJECT_ACCESSIBLE, - "EaCalendarCell", &tinfo, 0); - g_type_add_interface_static ( - type, ATK_TYPE_COMPONENT, - &atk_component_info); - } - - return type; -} - -static void -ea_calendar_cell_class_init (EaCalendarCellClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - -#ifdef ACC_DEBUG - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = ea_calendar_cell_finalize; -#endif - - parent_class = g_type_class_peek_parent (klass); - - class->get_name = ea_calendar_cell_get_name; - class->get_description = ea_calendar_cell_get_description; - - class->get_parent = ea_calendar_cell_get_parent; - class->get_index_in_parent = ea_calendar_cell_get_index_in_parent; - class->ref_state_set = ea_calendar_cell_ref_state_set; -} - -static void -ea_calendar_cell_init (EaCalendarCell *a11y) -{ - a11y->state_set = atk_state_set_new (); - atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); - atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); - atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); -} - -AtkObject * -ea_calendar_cell_new (GObject *obj) -{ - gpointer object; - AtkObject *atk_object; - - g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL); - object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL); - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, obj); - atk_object->role = ATK_ROLE_TABLE_CELL; - -#ifdef ACC_DEBUG - ++n_ea_calendar_cell_created; - g_print ( - "ACC_DEBUG: n_ea_calendar_cell_created = %d\n", - n_ea_calendar_cell_created); -#endif - return atk_object; -} - -#ifdef ACC_DEBUG -static void ea_calendar_cell_finalize (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->finalize (object); - - ++n_ea_calendar_cell_destroyed; - g_print ( - "ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n", - n_ea_calendar_cell_destroyed); -} -#endif - -static const gchar * -ea_calendar_cell_get_name (AtkObject *accessible) -{ - GObject *g_obj; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); - if (!g_obj) - /* defunct object*/ - return NULL; - - if (!accessible->name) { - AtkObject *atk_obj; - EaCalendarItem *ea_calitem; - ECalendarCell *cell; - gint day_index; - gint year, month, day; - gchar buffer[128]; - - cell = E_CALENDAR_CELL (g_obj); - atk_obj = ea_calendar_cell_get_parent (accessible); - ea_calitem = EA_CALENDAR_ITEM (atk_obj); - day_index = atk_table_get_index_at ( - ATK_TABLE (ea_calitem), - cell->row, cell->column); - e_calendar_item_get_date_for_offset (cell->calitem, day_index, - &year, &month, &day); - - g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day); - ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer); - } - return accessible->name; -} - -static const gchar * -ea_calendar_cell_get_description (AtkObject *accessible) -{ - return ea_calendar_cell_get_name (accessible); -} - -static AtkObject * -ea_calendar_cell_get_parent (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarCell *cell; - ECalendarItem *calitem; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); - if (!g_obj) - /* defunct object*/ - return NULL; - - cell = E_CALENDAR_CELL (g_obj); - calitem = cell->calitem; - return atk_gobject_accessible_for_object (G_OBJECT (calitem)); -} - -static gint -ea_calendar_cell_get_index_in_parent (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarCell *cell; - AtkObject *parent; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); - if (!g_obj) - return -1; - cell = E_CALENDAR_CELL (g_obj); - parent = atk_object_get_parent (accessible); - return atk_table_get_index_at ( - ATK_TABLE (parent), - cell->row, cell->column); -} - -static AtkStateSet * -ea_calendar_cell_ref_state_set (AtkObject *accessible) -{ - EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible); - - g_return_val_if_fail (atk_cell->state_set, NULL); - - g_object_ref (atk_cell->state_set); - - return atk_cell->state_set; - -} - -/* Atk Component Interface */ - -static void -atk_component_interface_init (AtkComponentIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_extents = component_interface_get_extents; - iface->grab_focus = component_interface_grab_focus; -} - -static void -component_interface_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - GObject *g_obj; - AtkObject *atk_obj, *atk_canvas; - ECalendarCell *cell; - ECalendarItem *calitem; - EaCalendarItem *ea_calitem; - gint day_index; - gint year, month, day; - gint canvas_x, canvas_y, canvas_width, canvas_height; - - *x = *y = *width = *height = 0; - - g_return_if_fail (EA_IS_CALENDAR_CELL (component)); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component)); - if (!g_obj) - /* defunct object*/ - return; - - cell = E_CALENDAR_CELL (g_obj); - calitem = cell->calitem; - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calitem = EA_CALENDAR_ITEM (atk_obj); - day_index = atk_table_get_index_at ( - ATK_TABLE (ea_calitem), - cell->row, cell->column); - e_calendar_item_get_date_for_offset (calitem, day_index, - &year, &month, &day); - - if (!e_calendar_item_get_day_extents (calitem, - year, month, day, - x, y, width, height)) - return; - atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem)); - atk_component_get_extents ( - ATK_COMPONENT (atk_canvas), - &canvas_x, &canvas_y, - &canvas_width, &canvas_height, - coord_type); - *x += canvas_x; - *y += canvas_y; -} - -static gboolean -component_interface_grab_focus (AtkComponent *component) -{ - GObject *g_obj; - GtkWidget *toplevel; - AtkObject *ea_calitem; - ECalendarItem *calitem; - EaCalendarCell *a11y; - gint index; - - a11y = EA_CALENDAR_CELL (component); - ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y)); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem)); - calitem = E_CALENDAR_ITEM (g_obj); - - index = atk_object_get_index_in_parent (ATK_OBJECT (a11y)); - - atk_selection_clear_selection (ATK_SELECTION (ea_calitem)); - atk_selection_add_selection (ATK_SELECTION (ea_calitem), index); - - gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); - toplevel = gtk_widget_get_toplevel ( - GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); - if (toplevel && gtk_widget_is_toplevel (toplevel)) - gtk_window_present (GTK_WINDOW (toplevel)); - - return TRUE; - -} diff --git a/widgets/misc/ea-calendar-cell.h b/widgets/misc/ea-calendar-cell.h deleted file mode 100644 index 2fd2051538..0000000000 --- a/widgets/misc/ea-calendar-cell.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __EA_CALENDAR_CELL_H__ -#define __EA_CALENDAR_CELL_H__ - -#include <atk/atkgobjectaccessible.h> -#include "misc/e-calendar-item.h" - -G_BEGIN_DECLS - -#define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ()) -#define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell)) -#define E_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) -#define E_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CALENDAR_CELL)) -#define E_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CALENDAR_CELL)) -#define E_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) - -typedef struct _ECalendarCell ECalendarCell; -typedef struct _ECalendarCellClass ECalendarCellClass; - -struct _ECalendarCell -{ - GObject parent; - ECalendarItem *calitem; - gint row; - gint column; -}; - -GType e_calendar_cell_get_type (void); - -struct _ECalendarCellClass -{ - GObjectClass parent_class; -}; - -ECalendarCell * e_calendar_cell_new (ECalendarItem *calitem, - gint row, gint column); - -#define EA_TYPE_CALENDAR_CELL (ea_calendar_cell_get_type ()) -#define EA_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCell)) -#define EA_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) -#define EA_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_CELL)) -#define EA_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_CELL)) -#define EA_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) - -typedef struct _EaCalendarCell EaCalendarCell; -typedef struct _EaCalendarCellClass EaCalendarCellClass; - -struct _EaCalendarCell -{ - AtkGObjectAccessible parent; - AtkStateSet *state_set; -}; - -GType ea_calendar_cell_get_type (void); - -struct _EaCalendarCellClass -{ - AtkGObjectAccessibleClass parent_class; -}; - -AtkObject * ea_calendar_cell_new (GObject *gobj); - -G_END_DECLS - -#endif /* __EA_CALENDAR_CELL_H__ */ diff --git a/widgets/misc/ea-calendar-item.c b/widgets/misc/ea-calendar-item.c deleted file mode 100644 index dc878c4e1d..0000000000 --- a/widgets/misc/ea-calendar-item.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <libgnomecanvas/gnome-canvas.h> -#include <e-util/e-util.h> -#include <glib/gi18n.h> - -#include <libedataserver/libedataserver.h> - -#include "ea-calendar-item.h" -#include "ea-calendar-cell.h" -#include "ea-cell-table.h" - -#define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH - -/* EaCalendarItem */ -static void ea_calendar_item_class_init (EaCalendarItemClass *class); -static void ea_calendar_item_finalize (GObject *object); - -static const gchar * ea_calendar_item_get_name (AtkObject *accessible); -static const gchar * ea_calendar_item_get_description (AtkObject *accessible); -static gint ea_calendar_item_get_n_children (AtkObject *accessible); -static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index); -static AtkStateSet * ea_calendar_item_ref_state_set (AtkObject *accessible); - -/* atk table interface */ -static void atk_table_interface_init (AtkTableIface *iface); -static gint table_interface_get_index_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_column_at_index (AtkTable *table, - gint index); -static gint table_interface_get_row_at_index (AtkTable *table, - gint index); -static AtkObject * table_interface_ref_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_n_rows (AtkTable *table); -static gint table_interface_get_n_columns (AtkTable *table); -static gint table_interface_get_column_extent_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_row_extent_at (AtkTable *table, - gint row, - gint column); - -static gboolean table_interface_is_row_selected (AtkTable *table, - gint row); -static gboolean table_interface_is_column_selected (AtkTable *table, - gint row); -static gboolean table_interface_is_selected (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_selected_rows (AtkTable *table, - gint **rows_selected); -static gint table_interface_get_selected_columns (AtkTable *table, - gint **columns_selected); -static gboolean table_interface_add_row_selection (AtkTable *table, gint row); -static gboolean table_interface_remove_row_selection (AtkTable *table, - gint row); -static gboolean table_interface_add_column_selection (AtkTable *table, - gint column); -static gboolean table_interface_remove_column_selection (AtkTable *table, - gint column); -static AtkObject * table_interface_get_row_header (AtkTable *table, gint row); -static AtkObject * table_interface_get_column_header (AtkTable *table, - gint in_col); -static AtkObject * table_interface_get_caption (AtkTable *table); - -static const gchar * -table_interface_get_column_description (AtkTable *table, - gint in_col); - -static const gchar * -table_interface_get_row_description (AtkTable *table, - gint row); - -static AtkObject *table_interface_get_summary (AtkTable *table); - -/* atk selection interface */ -static void atk_selection_interface_init (AtkSelectionIface *iface); -static gboolean selection_interface_add_selection (AtkSelection *selection, - gint i); -static gboolean selection_interface_clear_selection (AtkSelection *selection); -static AtkObject *selection_interface_ref_selection (AtkSelection *selection, - gint i); -static gint selection_interface_get_selection_count (AtkSelection *selection); -static gboolean selection_interface_is_child_selected (AtkSelection *selection, - gint i); - -/* callbacks */ -static void selection_preview_change_cb (ECalendarItem *calitem); -static void date_range_changed_cb (ECalendarItem *calitem); - -/* helpers */ -static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem); -static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem); -static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, - gint column, - gchar *buffer, - gint buffer_size); -static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, - gint row, - gchar *buffer, - gint buffer_size); -static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint *offset); -static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, - AtkObject *item_cell); - -#ifdef ACC_DEBUG -static gint n_ea_calendar_item_created = 0; -static gint n_ea_calendar_item_destroyed = 0; -#endif - -static gpointer parent_class = NULL; - -GType -ea_calendar_item_get_type (void) -{ - static GType type = 0; - AtkObjectFactory *factory; - GTypeQuery query; - GType derived_atk_type; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (EaCalendarItemClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) ea_calendar_item_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (EaCalendarItem), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) NULL, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_table_info = { - (GInterfaceInitFunc) atk_table_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - static const GInterfaceInfo atk_selection_info = { - (GInterfaceInitFunc) atk_selection_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - /* - * Figure out the size of the class and instance - * we are run-time deriving from (GailCanvasItem, in this case) - */ - - factory = atk_registry_get_factory ( - atk_get_default_registry (), - GNOME_TYPE_CANVAS_ITEM); - derived_atk_type = atk_object_factory_get_accessible_type (factory); - g_type_query (derived_atk_type, &query); - - tinfo.class_size = query.class_size; - tinfo.instance_size = query.instance_size; - - type = g_type_register_static ( - derived_atk_type, - "EaCalendarItem", &tinfo, 0); - g_type_add_interface_static ( - type, ATK_TYPE_TABLE, - &atk_table_info); - g_type_add_interface_static ( - type, ATK_TYPE_SELECTION, - &atk_selection_info); - } - - return type; -} - -static void -ea_calendar_item_class_init (EaCalendarItemClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - gobject_class->finalize = ea_calendar_item_finalize; - parent_class = g_type_class_peek_parent (klass); - - class->get_name = ea_calendar_item_get_name; - class->get_description = ea_calendar_item_get_description; - class->ref_state_set = ea_calendar_item_ref_state_set; - - class->get_n_children = ea_calendar_item_get_n_children; - class->ref_child = ea_calendar_item_ref_child; -} - -AtkObject * -ea_calendar_item_new (GObject *obj) -{ - gpointer object; - AtkObject *atk_object; - AtkObject *item_cell; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL); - object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL); - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, obj); - atk_object->role = ATK_ROLE_CALENDAR; - - item_cell = atk_selection_ref_selection ( - ATK_SELECTION (atk_object), 0); - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell); - -#ifdef ACC_DEBUG - ++n_ea_calendar_item_created; - g_print ( - "ACC_DEBUG: n_ea_calendar_item_created = %d\n", - n_ea_calendar_item_created); -#endif - /* connect signal handlers */ - g_signal_connect ( - obj, "selection_preview_changed", - G_CALLBACK (selection_preview_change_cb), atk_object); - g_signal_connect ( - obj, "date_range_changed", - G_CALLBACK (date_range_changed_cb), atk_object); - - return atk_object; -} - -static void -ea_calendar_item_finalize (GObject *object) -{ - EaCalendarItem *ea_calitem; - - g_return_if_fail (EA_IS_CALENDAR_ITEM (object)); - - ea_calitem = EA_CALENDAR_ITEM (object); - - /* Free the allocated cell data */ - ea_calendar_item_destory_cell_data (ea_calitem); - - G_OBJECT_CLASS (parent_class)->finalize (object); -#ifdef ACC_DEBUG - ++n_ea_calendar_item_destroyed; - printf ( - "ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n", - n_ea_calendar_item_destroyed); -#endif -} - -static const gchar * -ea_calendar_item_get_name (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarItem *calitem; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - gchar *name_str = NULL; - gchar buffer_start[128] = ""; - gchar buffer_end[128] = ""; - struct tm day_start = { 0 }; - struct tm day_end = { 0 }; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); - if (!g_obj) - return NULL; - g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL); - - calitem = E_CALENDAR_ITEM (g_obj); - if (e_calendar_item_get_date_range ( - calitem, - &start_year, &start_month, &start_day, - &end_year, &end_month, &end_day)) { - - day_start.tm_year = start_year - 1900; - day_start.tm_mon = start_month; - day_start.tm_mday = start_day; - day_start.tm_isdst = -1; - - e_utf8_strftime ( - buffer_start, sizeof (buffer_start), - _("%d %B %Y"), &day_start); - - day_end.tm_year = end_year - 1900; - day_end.tm_mon = end_month; - day_end.tm_mday = end_day; - day_end.tm_isdst = -1; - - e_utf8_strftime ( - buffer_end, sizeof (buffer_end), - _("%d %B %Y"), &day_end); - - name_str = g_strdup_printf ( - _("Calendar: from %s to %s"), - buffer_start, buffer_end); - } - -#if 0 - if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) { - GDate select_start, select_end; - gint year1, year2, month1, month2, day1, day2; - - year1 = g_date_get_year (&select_start); - month1 = g_date_get_month (&select_start); - day1 = g_date_get_day (&select_start); - - year2 = g_date_get_year (&select_end); - month2 = g_date_get_month (&select_end); - day2 = g_date_get_day (&select_end); - - sprintf ( - new_name + strlen (new_name), - " : current selection: from %d-%d-%d to %d-%d-%d.", - year1, month1, day1, - year2, month2, day2); - } -#endif - - ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); - g_free (name_str); - - return accessible->name; -} - -static const gchar * -ea_calendar_item_get_description (AtkObject *accessible) -{ - if (accessible->description) - return accessible->description; - - return _("evolution calendar item"); -} - -static AtkStateSet * -ea_calendar_item_ref_state_set (AtkObject *accessible) -{ - AtkStateSet *state_set; - GObject *g_obj; - - state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible); - g_obj = atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (accessible)); - if (!g_obj) - return state_set; - - atk_state_set_add_state (state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); - - return state_set; -} - -static gint -ea_calendar_item_get_n_children (AtkObject *accessible) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint n_children = 0; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date, *end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return 0; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - end_date = g_date_new_dmy (end_day, end_month + 1, end_year); - - n_children = g_date_days_between (start_date, end_date) + 1; - g_free (start_date); - g_free (end_date); - return n_children; -} - -static AtkObject * -ea_calendar_item_ref_child (AtkObject *accessible, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint n_children; - ECalendarCell *cell; - EaCellTable *cell_data; - EaCalendarItem *ea_calitem; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - calitem = E_CALENDAR_ITEM (g_obj); - - n_children = ea_calendar_item_get_n_children (accessible); - if (index < 0 || index >= n_children) - return NULL; - - ea_calitem = EA_CALENDAR_ITEM (accessible); - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - cell = ea_cell_table_get_cell_at_index (cell_data, index); - if (!cell) { - cell = e_calendar_cell_new ( - calitem, - index / EA_CALENDAR_COLUMN_NUM, - index % EA_CALENDAR_COLUMN_NUM); - ea_cell_table_set_cell_at_index (cell_data, index, cell); - g_object_unref (cell); - } - -#ifdef ACC_DEBUG - g_print ( - "AccDebug: ea_calendar_item children[%d]=%p\n", index, - (gpointer) cell); -#endif - return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT (cell))); -} - -/* atk table interface */ - -static void -atk_table_interface_init (AtkTableIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->ref_at = table_interface_ref_at; - - iface->get_n_rows = table_interface_get_n_rows; - iface->get_n_columns = table_interface_get_n_columns; - iface->get_index_at = table_interface_get_index_at; - iface->get_column_at_index = table_interface_get_column_at_index; - iface->get_row_at_index = table_interface_get_row_at_index; - iface->get_column_extent_at = table_interface_get_column_extent_at; - iface->get_row_extent_at = table_interface_get_row_extent_at; - - iface->is_selected = table_interface_is_selected; - iface->get_selected_rows = table_interface_get_selected_rows; - iface->get_selected_columns = table_interface_get_selected_columns; - iface->is_row_selected = table_interface_is_row_selected; - iface->is_column_selected = table_interface_is_column_selected; - iface->add_row_selection = table_interface_add_row_selection; - iface->remove_row_selection = table_interface_remove_row_selection; - iface->add_column_selection = table_interface_add_column_selection; - iface->remove_column_selection = table_interface_remove_column_selection; - - iface->get_row_header = table_interface_get_row_header; - iface->get_column_header = table_interface_get_column_header; - iface->get_caption = table_interface_get_caption; - iface->get_summary = table_interface_get_summary; - iface->get_row_description = table_interface_get_row_description; - iface->get_column_description = table_interface_get_column_description; -} - -static AtkObject * -table_interface_ref_at (AtkTable *table, - gint row, - gint column) -{ - gint index; - - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - index = EA_CALENDAR_COLUMN_NUM * row + column; - return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index); -} - -static gint -table_interface_get_n_rows (AtkTable *table) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1; -} - -static gint -table_interface_get_n_columns (AtkTable *table) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - return EA_CALENDAR_COLUMN_NUM; -} - -static gint -table_interface_get_index_at (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - return row * EA_CALENDAR_COLUMN_NUM + column; -} - -static gint -table_interface_get_column_at_index (AtkTable *table, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - if (index >= 0 && index < n_children) - return index % EA_CALENDAR_COLUMN_NUM; - return -1; -} - -static gint -table_interface_get_row_at_index (AtkTable *table, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - if (index >= 0 && index < n_children) - return index / EA_CALENDAR_COLUMN_NUM; - return -1; -} - -static gint -table_interface_get_column_extent_at (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - return calitem->cell_width; -} - -static gint -table_interface_get_row_extent_at (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - return calitem->cell_height; -} - -/* any day in the row is selected, the row is selected */ -static gboolean -table_interface_is_row_selected (AtkTable *table, - gint row) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - gint n_rows; - ECalendarItem *calitem; - gint row_index_start, row_index_end; - gint sel_index_start, sel_index_end; - - GDate start_date, end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return FALSE; - - row_index_start = row * EA_CALENDAR_COLUMN_NUM; - row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return FALSE; - - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date), - g_date_get_day (&start_date), - &sel_index_start); - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&end_date), - g_date_get_month (&end_date), - g_date_get_day (&end_date), - &sel_index_end); - - if ((sel_index_start < row_index_start && - sel_index_end >= row_index_start) || - (sel_index_start >= row_index_start && - sel_index_start <= row_index_end)) - return TRUE; - return FALSE; -} - -static gboolean -table_interface_is_selected (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - gint n_rows, n_columns; - ECalendarItem *calitem; - gint index; - gint sel_index_start, sel_index_end; - - GDate start_date, end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return FALSE; - n_columns = table_interface_get_n_columns (table); - if (column < 0 || column >= n_columns) - return FALSE; - - index = table_interface_get_index_at (table, row, column); - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return FALSE; - - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date), - g_date_get_day (&start_date), - &sel_index_start); - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&end_date), - g_date_get_month (&end_date), - g_date_get_day (&end_date), &sel_index_end); - - if (sel_index_start <= index && sel_index_end >= index) - return TRUE; - return FALSE; -} - -static gboolean -table_interface_is_column_selected (AtkTable *table, - gint column) -{ - return FALSE; -} - -static gint -table_interface_get_selected_rows (AtkTable *table, - gint **rows_selected) -{ - *rows_selected = NULL; - return -1; -} - -static gint -table_interface_get_selected_columns (AtkTable *table, - gint **columns_selected) -{ - *columns_selected = NULL; - return -1; -} - -static gboolean -table_interface_add_row_selection (AtkTable *table, - gint row) -{ - return FALSE; -} - -static gboolean -table_interface_remove_row_selection (AtkTable *table, - gint row) -{ - return FALSE; -} - -static gboolean -table_interface_add_column_selection (AtkTable *table, - gint column) -{ - return FALSE; -} - -static gboolean -table_interface_remove_column_selection (AtkTable *table, - gint column) -{ - /* FIXME: NOT IMPLEMENTED */ - return FALSE; -} - -static AtkObject * -table_interface_get_row_header (AtkTable *table, - gint row) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static AtkObject * -table_interface_get_column_header (AtkTable *table, - gint in_col) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static AtkObject * -table_interface_get_caption (AtkTable *table) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static const gchar * -table_interface_get_column_description (AtkTable *table, - gint in_col) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - const gchar *description = NULL; - EaCellTable *cell_data; - gint n_columns; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - n_columns = table_interface_get_n_columns (table); - if (in_col < 0 || in_col >= n_columns) - return NULL; - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - description = ea_cell_table_get_column_label (cell_data, in_col); - if (!description) { - gchar buffer[128] = "column description"; - ea_calendar_item_get_column_label ( - ea_calitem, in_col, - buffer, sizeof (buffer)); - ea_cell_table_set_column_label (cell_data, in_col, buffer); - description = ea_cell_table_get_column_label ( - cell_data, in_col); - } - return description; -} - -static const gchar * -table_interface_get_row_description (AtkTable *table, - gint row) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table); - const gchar *description = NULL; - EaCellTable *cell_data; - gint n_rows; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return NULL; - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - description = ea_cell_table_get_row_label (cell_data, row); - if (!description) { - gchar buffer[128] = "row description"; - ea_calendar_item_get_row_label ( - ea_calitem, row, - buffer, sizeof (buffer)); - ea_cell_table_set_row_label (cell_data, row, buffer); - description = ea_cell_table_get_row_label ( - cell_data, - row); - } - return description; -} - -static AtkObject * -table_interface_get_summary (AtkTable *table) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -/* atkselection interface */ - -static void -atk_selection_interface_init (AtkSelectionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->add_selection = selection_interface_add_selection; - iface->clear_selection = selection_interface_clear_selection; - iface->ref_selection = selection_interface_ref_selection; - iface->get_selection_count = selection_interface_get_selection_count; - iface->is_child_selected = selection_interface_is_child_selected; -} - -static gboolean -selection_interface_add_selection (AtkSelection *selection, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection); - gint year, month, day; - GDate start_date, end_date; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_date_for_offset (calitem, index, - &year, &month, &day)) - return FALSE; - - /* FIXME: not support mulit-selection */ - g_date_set_dmy (&start_date, day, month + 1, year); - end_date = start_date; - e_calendar_item_set_selection (calitem, &start_date, &end_date); - return TRUE; -} - -static gboolean -selection_interface_clear_selection (AtkSelection *selection) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - e_calendar_item_set_selection (calitem, NULL, NULL); - - return TRUE; -} - -static AtkObject * -selection_interface_ref_selection (AtkSelection *selection, - gint i) -{ - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection); - gint count, sel_offset; - GDate start_date, end_date; - - count = selection_interface_get_selection_count (selection); - if (i < 0 || i >= count) - return NULL; - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem)); - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return NULL; - if (!e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date) - 1, - g_date_get_day (&start_date), - &sel_offset)) - return NULL; - - return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i); -} - -static gint -selection_interface_get_selection_count (AtkSelection *selection) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection); - GDate start_date, end_date; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return 0; - - calitem = E_CALENDAR_ITEM (g_obj); - if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return g_date_days_between (&start_date, &end_date) + 1; - else - return 0; -} - -static gboolean -selection_interface_is_child_selected (AtkSelection *selection, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection); - gint row, column, n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection)); - if (index < 0 || index >= n_children) - return FALSE; - - row = index / EA_CALENDAR_COLUMN_NUM; - column = index % EA_CALENDAR_COLUMN_NUM; - - return table_interface_is_selected (ATK_TABLE (selection), row, column); -} - -/* callbacks */ - -static void -selection_preview_change_cb (ECalendarItem *calitem) -{ - AtkObject *atk_obj; - AtkObject *item_cell; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); - - /* only deal with the first selected child, for now */ - item_cell = atk_selection_ref_selection ( - ATK_SELECTION (atk_obj), 0); - - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); - - g_signal_emit_by_name ( - atk_obj, - "active-descendant-changed", - item_cell); - g_signal_emit_by_name (atk_obj, "selection_changed"); -} - -static void -date_range_changed_cb (ECalendarItem *calitem) -{ - AtkObject *atk_obj; - AtkObject *item_cell; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); - - item_cell = atk_selection_ref_selection ( - ATK_SELECTION (atk_obj), 0); - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); - - g_signal_emit_by_name (atk_obj, "model_changed"); -} - -/* helpers */ - -static EaCellTable * -ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCellTable *cell_data; - - g_return_val_if_fail (ea_calitem, NULL); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - cell_data = g_object_get_data ( - G_OBJECT (ea_calitem), - "ea-calendar-cell-table"); - - if (!cell_data) { - gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - cell_data = ea_cell_table_create ( - n_cells / EA_CALENDAR_COLUMN_NUM, - EA_CALENDAR_COLUMN_NUM, - FALSE); - g_object_set_data ( - G_OBJECT (ea_calitem), - "ea-calendar-cell-table", cell_data); - } - return cell_data; -} - -static void -ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem) -{ - EaCellTable *cell_data; - - g_return_if_fail (ea_calitem); - - cell_data = g_object_get_data ( - G_OBJECT (ea_calitem), - "ea-calendar-cell-table"); - if (cell_data) { - g_object_set_data ( - G_OBJECT (ea_calitem), - "ea-calendar-cell-table", NULL); - ea_cell_table_destroy (cell_data); - } -} - -static gboolean -ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, - gint row, - gchar *buffer, - gint buffer_size) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint index, week_num; - gint year, month, day; - - g_return_val_if_fail (ea_calitem, FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - - index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0); - if (!e_calendar_item_get_date_for_offset (calitem, index, - &year, &month, &day)) - return FALSE; - - week_num = e_calendar_item_get_week_number ( - calitem, day, month, year); - - g_snprintf (buffer, buffer_size, "week number : %d", week_num); - return TRUE; -} - -static gboolean -ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, - gint column, - gchar *buffer, - gint buffer_size) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - const gchar *abbr_name; - - g_return_val_if_fail (ea_calitem, FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - /* Columns are 0 = Monday ... 6 = Sunday */ - abbr_name = e_get_weekday_name (column + 1, TRUE); - g_strlcpy (buffer, abbr_name, buffer_size); - - return TRUE; -} - -/* the coordinate the e-calendar canvas coord */ -gboolean -e_calendar_item_get_day_extents (ECalendarItem *calitem, - gint year, - gint month, - gint date, - gint *x, - gint *y, - gint *width, - gint *height) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - gint char_height, xthickness, ythickness, text_y; - gint new_year, new_month, num_months, months_offset; - gint month_x, month_y, month_cell_x, month_cell_y; - gint month_row, month_col; - gint day_row, day_col; - gint days_from_week_start; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = gtk_widget_get_style (widget); - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - xthickness = style->xthickness; - ythickness = style->ythickness; - - new_year = year; - new_month = month; - e_calendar_item_normalize_date (calitem, &new_year, &new_month); - num_months = calitem->rows * calitem->cols; - months_offset = (new_year - calitem->year) * 12 - + new_month - calitem->month; - - if (months_offset > num_months || months_offset < 0) - return FALSE; - - month_row = months_offset / calitem->cols; - month_col = months_offset % calitem->cols; - - month_x = item->x1 + xthickness + calitem->x_offset - + month_col * calitem->month_width; - month_y = item->y1 + ythickness + month_row * calitem->month_height; - - month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS - + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - text_y = month_y + ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; - - month_cell_y = text_y + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - - days_from_week_start = e_calendar_item_get_n_days_from_week_start ( - calitem, new_year, new_month); - day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM; - day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM; - - *x = month_cell_x + day_col * calitem->cell_width; - *y = month_cell_y + day_row * calitem->cell_height; - *width = calitem->cell_width; - *height = calitem->cell_height; - - return TRUE; -} - -/* month is from 0 to 11 */ -gboolean -e_calendar_item_get_date_for_offset (ECalendarItem *calitem, - gint day_offset, - gint *year, - gint *month, - gint *day) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return FALSE; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - - g_date_add_days (start_date, day_offset); - - *year = g_date_get_year (start_date); - *month = g_date_get_month (start_date) - 1; - *day = g_date_get_day (start_date); - - return TRUE; -} - -/* the arg month is from 0 to 11 */ -static gboolean -e_calendar_item_get_offset_for_date (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint *offset) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date, *end_date; - - *offset = 0; - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return FALSE; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - end_date = g_date_new_dmy (day, month + 1, year); - - *offset = g_date_days_between (start_date, end_date); - g_free (start_date); - g_free (end_date); - - return TRUE; -} - -gint -e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, - gint year, - gint month) -{ - struct tm tmp_tm; - gint start_weekday, days_from_week_start; - - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */ - days_from_week_start = (start_weekday + 7 - calitem->week_start_day) - % 7; - return days_from_week_start; -} - -static void -ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, - AtkObject *item_cell) -{ - AtkStateSet *state_set, *old_state_set; - AtkObject *old_cell; - - old_cell = (AtkObject *) g_object_get_data ( - G_OBJECT (ea_calitem), "gail-focus-object"); - if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) { - old_state_set = atk_object_ref_state_set (old_cell); - atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED); - g_object_unref (old_state_set); - } - if (old_cell) - g_object_unref (old_cell); - - state_set = atk_object_ref_state_set (item_cell); - atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); - g_object_set_data (G_OBJECT (ea_calitem), "gail-focus-object", item_cell); - g_object_unref (state_set); -} diff --git a/widgets/misc/ea-calendar-item.h b/widgets/misc/ea-calendar-item.h deleted file mode 100644 index b5271a9f8b..0000000000 --- a/widgets/misc/ea-calendar-item.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __EA_CALENDAR_ITEM_H__ -#define __EA_CALENDAR_ITEM_H__ - -#include <atk/atkgobjectaccessible.h> -#include <misc/e-calendar-item.h> - -G_BEGIN_DECLS - -#define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ()) -#define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem)) -#define EA_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) -#define EA_IS_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_ITEM)) -#define EA_IS_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_ITEM)) -#define EA_CALENDAR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) - -typedef struct _EaCalendarItem EaCalendarItem; -typedef struct _EaCalendarItemClass EaCalendarItemClass; - -struct _EaCalendarItem -{ - AtkGObjectAccessible parent; -}; - -GType ea_calendar_item_get_type (void); - -struct _EaCalendarItemClass -{ - AtkGObjectAccessibleClass parent_class; -}; - -AtkObject *ea_calendar_item_new (GObject *obj); -gboolean e_calendar_item_get_day_extents (ECalendarItem *calitem, - gint year, gint month, gint date, - gint *x, gint *y, - gint *width, gint *height); -gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem, - gint day_offset, - gint *year, gint *month, - gint *day); -gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, - gint year, gint month); - -G_END_DECLS - -#endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/ea-cell-table.c b/widgets/misc/ea-cell-table.c deleted file mode 100644 index bbdef0aea1..0000000000 --- a/widgets/misc/ea-cell-table.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "ea-cell-table.h" - -EaCellTable * -ea_cell_table_create (gint rows, - gint columns, - gboolean column_first) -{ - EaCellTable *cell_data; - gint index; - - g_return_val_if_fail (((columns > 0) && (rows > 0)), NULL); - - cell_data = g_new0 (EaCellTable, 1); - - cell_data->column_first = column_first; - cell_data->columns = columns; - cell_data->rows = rows; - - cell_data->column_labels = g_new0 (gchar *, columns); - for (index = columns -1; index >= 0; --index) - cell_data->column_labels[index] = NULL; - - cell_data->row_labels = g_new0 (gchar *, rows); - for (index = rows -1; index >= 0; --index) - cell_data->row_labels[index] = NULL; - - cell_data->cells = g_new0 (gpointer, (columns * rows)); - for (index = (columns * rows) -1; index >= 0; --index) - cell_data->cells[index] = NULL; - return cell_data; -} - -void -ea_cell_table_destroy (EaCellTable *cell_data) -{ - gint index; - g_return_if_fail (cell_data); - - for (index = 0; index < cell_data->columns; ++index) - if (cell_data->column_labels[index]) - g_free (cell_data->column_labels[index]); - g_free (cell_data->column_labels); - - for (index = 0; index < cell_data->rows; ++index) - if (cell_data->row_labels[index]) - g_free (cell_data->row_labels[index]); - g_free (cell_data->row_labels); - - for (index = (cell_data->columns * cell_data->rows) -1; - index >= 0; --index) - if (cell_data->cells[index] && - G_IS_OBJECT (cell_data->cells[index])) - g_object_unref (cell_data->cells[index]); - - g_free (cell_data->cells); -} - -gpointer -ea_cell_table_get_cell (EaCellTable *cell_data, - gint row, - gint column) -{ - gint index; - - g_return_val_if_fail (cell_data, NULL); - - index = ea_cell_table_get_index (cell_data, column, row); - if (index == -1) - return NULL; - - return cell_data->cells[index]; -} - -gboolean -ea_cell_table_set_cell (EaCellTable *cell_data, - gint row, - gint column, - gpointer cell) -{ - gint index; - - g_return_val_if_fail (cell_data, FALSE); - - index = ea_cell_table_get_index (cell_data, column, row); - if (index == -1) - return FALSE; - - if (cell && G_IS_OBJECT (cell)) - g_object_ref (cell); - if (cell_data->cells[index] && - G_IS_OBJECT (cell_data->cells[index])) - g_object_unref (cell_data->cells[index]); - cell_data->cells[index] = cell; - - return TRUE; -} - -gpointer -ea_cell_table_get_cell_at_index (EaCellTable *cell_data, - gint index) -{ - g_return_val_if_fail (cell_data, NULL); - - if (index >=0 && index < (cell_data->columns * cell_data->rows)) - return cell_data->cells[index]; - return NULL; -} - -gboolean -ea_cell_table_set_cell_at_index (EaCellTable *cell_data, - gint index, - gpointer cell) -{ - g_return_val_if_fail (cell_data, FALSE); - - if (index < 0 || index >=cell_data->columns * cell_data->rows) - return FALSE; - - if (cell && G_IS_OBJECT (cell)) - g_object_ref (cell); - if (cell_data->cells[index] && - G_IS_OBJECT (cell_data->cells[index])) - g_object_unref (cell_data->cells[index]); - cell_data->cells[index] = cell; - - return TRUE; -} - -const gchar * -ea_cell_table_get_column_label (EaCellTable *cell_data, - gint column) -{ - g_return_val_if_fail (cell_data, NULL); - g_return_val_if_fail ((column >= 0 && column < cell_data->columns), NULL); - - return cell_data->column_labels[column]; -} - -void -ea_cell_table_set_column_label (EaCellTable *cell_data, - gint column, - const gchar *label) -{ - g_return_if_fail (cell_data); - g_return_if_fail ((column >= 0 && column < cell_data->columns)); - - if (cell_data->column_labels[column]) - g_free (cell_data->column_labels[column]); - cell_data->column_labels[column] = g_strdup (label); -} - -const gchar * -ea_cell_table_get_row_label (EaCellTable *cell_data, - gint row) -{ - g_return_val_if_fail (cell_data, NULL); - g_return_val_if_fail ((row >= 0 && row < cell_data->rows), NULL); - - return cell_data->row_labels[row]; -} - -void -ea_cell_table_set_row_label (EaCellTable *cell_data, - gint row, - const gchar *label) -{ - g_return_if_fail (cell_data); - g_return_if_fail ((row >= 0 && row < cell_data->rows)); - - if (cell_data->row_labels[row]) - g_free (cell_data->row_labels[row]); - cell_data->row_labels[row] = g_strdup (label); -} - -gint -ea_cell_table_get_index (EaCellTable *cell_data, - gint row, - gint column) -{ - g_return_val_if_fail (cell_data, -1); - if (row < 0 || row >= cell_data->rows || - column < 0 || column >= cell_data->columns) - return -1; - - if (cell_data->column_first) - return column * cell_data->rows + row; - else - return row * cell_data->columns + column; -} diff --git a/widgets/misc/ea-cell-table.h b/widgets/misc/ea-cell-table.h deleted file mode 100644 index a13d7a52c7..0000000000 --- a/widgets/misc/ea-cell-table.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* EaCellTable */ - -#include <glib-object.h> - -struct _EaCellTable { - gint columns; - gint rows; - gboolean column_first; /* index order */ - gchar **column_labels; - gchar **row_labels; - gpointer *cells; -}; - -typedef struct _EaCellTable EaCellTable; - -EaCellTable * ea_cell_table_create (gint rows, gint columns, - gboolean column_first); -void ea_cell_table_destroy (EaCellTable * cell_data); -gpointer ea_cell_table_get_cell (EaCellTable * cell_data, - gint row, gint column); -gboolean ea_cell_table_set_cell (EaCellTable * cell_data, - gint row, gint column, gpointer cell); -gpointer ea_cell_table_get_cell_at_index (EaCellTable * cell_data, - gint index); -gboolean ea_cell_table_set_cell_at_index (EaCellTable * cell_data, - gint index, gpointer cell); - -const gchar * -ea_cell_table_get_column_label (EaCellTable * cell_data, gint column); -void ea_cell_table_set_column_label (EaCellTable * cell_data, - gint column, const gchar *label); -const gchar * -ea_cell_table_get_row_label (EaCellTable * cell_data, gint row); -void ea_cell_table_set_row_label (EaCellTable * cell_data, - gint row, const gchar *label); -gint ea_cell_table_get_index (EaCellTable *cell_data, - gint row, gint column); diff --git a/widgets/misc/ea-widgets.c b/widgets/misc/ea-widgets.c deleted file mode 100644 index 1b74d44fd2..0000000000 --- a/widgets/misc/ea-widgets.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "a11y/ea-factory.h" -#include "ea-calendar-item.h" -#include "ea-widgets.h" - -EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new) - -void e_calendar_item_a11y_init (void) -{ - EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item); -} diff --git a/widgets/misc/ea-widgets.h b/widgets/misc/ea-widgets.h deleted file mode 100644 index 495222ae05..0000000000 --- a/widgets/misc/ea-widgets.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* Evolution Accessibility -*/ - -#ifndef _EA_WIDGETS_H__ -#define _EA_WIDGETS_H__ - -void e_calendar_item_a11y_init (void); - -#endif /* _EA_WIDGETS_H__ */ diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c deleted file mode 100644 index 7d3584a424..0000000000 --- a/widgets/misc/test-calendar.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * test-calendar - tests the ECalendar widget. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "e-calendar.h" - -/* Drag and Drop stuff. */ -enum { - TARGET_SHORTCUT -}; - -static GtkTargetEntry target_table[] = { - { (gchar *) "E-SHORTCUT", 0, TARGET_SHORTCUT } -}; - -static void on_date_range_changed (ECalendarItem *calitem); -static void on_selection_changed (ECalendarItem *calitem); - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); -} - -gint -main (gint argc, - gchar **argv) -{ - GtkWidget *window; - GtkWidget *cal; - GtkWidget *vbox; - ECalendarItem *calitem; - - gtk_init (&argc, &argv); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "ECalendar Test"); - gtk_window_set_default_size (GTK_WINDOW (window), 400, 400); - gtk_window_set_resizable (GTK_WINDOW (window), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); - - g_signal_connect ( - window, "delete_event", - G_CALLBACK (delete_event_cb), NULL); - - cal = e_calendar_new (); - e_calendar_set_minimum_size (E_CALENDAR (cal), 1, 1); - calitem = E_CALENDAR (cal)->calitem; - gtk_widget_show (cal); - - g_signal_connect ( - calitem, "date_range_changed", - G_CALLBACK (on_date_range_changed), NULL); - g_signal_connect ( - calitem, "selection_changed", - G_CALLBACK (on_selection_changed), NULL); - - gtk_drag_dest_set ( - cal, - GTK_DEST_DEFAULT_ALL, - target_table, G_N_ELEMENTS (target_table), - GDK_ACTION_COPY | GDK_ACTION_MOVE); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), cal, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - gtk_container_add (GTK_CONTAINER (window), vbox); - gtk_widget_show (window); - - gtk_main (); - - return 0; -} - -static void -on_date_range_changed (ECalendarItem *calitem) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - - e_calendar_item_get_date_range ( - calitem, - &start_year, &start_month, &start_day, - &end_year, &end_month, &end_day); - - g_print ( - "Date range changed (D/M/Y): %i/%i/%i - %i/%i/%i\n", - start_day, start_month + 1, start_year, - end_day, end_month + 1, end_year); - - /* These days should windowear bold. Remember month is 0 to 11. */ - e_calendar_item_mark_day ( - calitem, 2000, 7, 26, /* 26th Aug 2000. */ - E_CALENDAR_ITEM_MARK_BOLD, FALSE); - e_calendar_item_mark_day ( - calitem, 2000, 8, 13, /* 13th Sep 2000. */ - E_CALENDAR_ITEM_MARK_BOLD, FALSE); -} - -static void -on_selection_changed (ECalendarItem *calitem) -{ - GDate start_date, end_date; - - e_calendar_item_get_selection (calitem, &start_date, &end_date); - - g_print ( - "Selection changed (D/M/Y): %i/%i/%i - %i/%i/%i\n", - g_date_get_day (&start_date), - g_date_get_month (&start_date), - g_date_get_year (&start_date), - g_date_get_day (&end_date), - g_date_get_month (&end_date), - g_date_get_year (&end_date)); -} diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c deleted file mode 100644 index 5592afbc70..0000000000 --- a/widgets/misc/test-dateedit.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * test-dateedit - tests the EDateEdit widget. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include "e-dateedit.h" - -static void delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - GtkWidget *window); -static void on_get_date_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_toggle_24_hour_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_changed (EDateEdit *dedit, - gchar *name); -#if 0 -static void on_date_changed (EDateEdit *dedit, - gchar *name); -static void on_time_changed (EDateEdit *dedit, - gchar *name); -#endif - -gint -main (gint argc, - gchar **argv) -{ - GtkWidget *window; - EDateEdit *dedit; - GtkWidget *table, *button; - - gtk_init (&argc, &argv); - - puts ("here"); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "EDateEdit Test"); - gtk_window_set_default_size (GTK_WINDOW (window), 300, 200); - gtk_window_set_resizable (GTK_WINDOW (window), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); - - g_signal_connect ( - window, "delete_event", - G_CALLBACK (delete_event_cb), window); - - table = gtk_table_new (3, 3, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - gtk_widget_show (table); - - gtk_container_add (GTK_CONTAINER (window), table); - - /* EDateEdit 1. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach ( - GTK_TABLE (table), GTK_WIDGET (dedit), - 0, 1, 0, 1, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show (GTK_WIDGET (dedit)); - -#if 0 - g_signal_connect ( - dedit, "date_changed", - G_CALLBACK (on_date_changed), (gpointer) "1"); - g_signal_connect ( - dedit, "time_changed", - G_CALLBACK (on_time_changed), (gpointer) "1"); -#else - g_signal_connect ( - dedit, "changed", - G_CALLBACK (on_changed), (gpointer) "1"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach ( - GTK_TABLE (table), button, - 1, 2, 0, 1, 0, 0, 0, 0); - gtk_widget_show (button); - g_signal_connect ( - button, "clicked", - G_CALLBACK (on_get_date_clicked), dedit); - - /* EDateEdit 2. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach ( - GTK_TABLE (table), (GtkWidget *) dedit, - 0, 1, 1, 2, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show ((GtkWidget *) (dedit)); - e_date_edit_set_week_start_day (dedit, 1); - e_date_edit_set_show_week_numbers (dedit, TRUE); - e_date_edit_set_use_24_hour_format (dedit, FALSE); - e_date_edit_set_time_popup_range (dedit, 8, 18); - e_date_edit_set_show_time (dedit, FALSE); - -#if 0 - g_signal_connect ( - dedit, "date_changed", - G_CALLBACK (on_date_changed), (gpointer) "2"); - g_signal_connect ( - dedit, "time_changed", - G_CALLBACK (on_time_changed), (gpointer) "2"); -#else - g_signal_connect ( - dedit, "changed", - G_CALLBACK (on_changed), (gpointer) "2"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach ( - GTK_TABLE (table), button, - 1, 2, 1, 2, 0, 0, 0, 0); - gtk_widget_show (button); - g_signal_connect ( - button, "clicked", - G_CALLBACK (on_get_date_clicked), dedit); - - /* EDateEdit 3. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach ( - GTK_TABLE (table), (GtkWidget *) dedit, - 0, 1, 2, 3, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show ((GtkWidget *) (dedit)); - e_date_edit_set_week_start_day (dedit, 1); - e_date_edit_set_show_week_numbers (dedit, TRUE); - e_date_edit_set_use_24_hour_format (dedit, FALSE); - e_date_edit_set_time_popup_range (dedit, 8, 18); - e_date_edit_set_allow_no_date_set (dedit, TRUE); - -#if 0 - g_signal_connect ( - dedit, "date_changed", - G_CALLBACK (on_date_changed), (gpointer) "3"); - g_signal_connect ( - dedit, "time_changed", - G_CALLBACK (on_time_changed), (gpointer) "3"); -#else - g_signal_connect ( - dedit, "changed", - G_CALLBACK (on_changed), (gpointer) "3"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach ( - GTK_TABLE (table), button, - 1, 2, 2, 3, 0, 0, 0, 0); - gtk_widget_show (button); - g_signal_connect ( - button, "clicked", - G_CALLBACK (on_get_date_clicked), dedit); - - button = gtk_button_new_with_label ("Toggle 24-hour"); - gtk_table_attach ( - GTK_TABLE (table), button, - 2, 3, 2, 3, 0, 0, 0, 0); - gtk_widget_show (button); - g_signal_connect ( - button, "clicked", - G_CALLBACK (on_toggle_24_hour_clicked), dedit); - - gtk_widget_show (window); - - gtk_main (); - - return 0; -} - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - GtkWidget *window) -{ - gtk_widget_destroy (window); - - gtk_main_quit (); -} - -static void -on_get_date_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - time_t t; - - t = e_date_edit_get_time (dedit); - if (t == -1) - g_print ("Time: None\n"); - else - g_print ("Time: %s", ctime (&t)); - - if (!e_date_edit_date_is_valid (dedit)) - g_print (" Date invalid\n"); - - if (!e_date_edit_time_is_valid (dedit)) - g_print (" Time invalid\n"); -} - -static void -on_toggle_24_hour_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - gboolean use_24_hour_format; - - use_24_hour_format = e_date_edit_get_use_24_hour_format (dedit); - e_date_edit_set_use_24_hour_format (dedit, !use_24_hour_format); -} - -#if 0 -static void -on_date_changed (EDateEdit *dedit, - gchar *name) -{ - gint year, month, day; - - if (e_date_edit_date_is_valid (dedit)) { - if (e_date_edit_get_date (dedit, &year, &month, &day)) { - g_print ( - "Date %s changed to: %i/%i/%i (M/D/Y)\n", - name, month, day, year); - } else { - g_print ("Date %s changed to: None\n", name); - } - } else { - g_print ("Date %s changed to: Not Valid\n", name); - } -} - -static void -on_time_changed (EDateEdit *dedit, - gchar *name) -{ - gint hour, minute; - - if (e_date_edit_time_is_valid (dedit)) { - if (e_date_edit_get_time_of_day (dedit, &hour, &minute)) { - g_print ( - "Time %s changed to: %02i:%02i\n", name, - hour, minute); - } else { - g_print ("Time %s changed to: None\n", name); - } - } else { - g_print ("Time %s changed to: Not Valid\n", name); - } -} -#endif - -static void -on_changed (EDateEdit *dedit, - gchar *name) -{ - gint year, month, day, hour, minute; - - g_print ("Date %s changed ", name); - - if (e_date_edit_date_is_valid (dedit)) { - if (e_date_edit_get_date (dedit, &year, &month, &day)) { - g_print ("M/D/Y: %i/%i/%i", month, day, year); - } else { - g_print ("None"); - } - } else { - g_print ("Date Invalid"); - } - - if (e_date_edit_time_is_valid (dedit)) { - if (e_date_edit_get_time_of_day (dedit, &hour, &minute)) { - g_print (" %02i:%02i\n", hour, minute); - } else { - g_print (" None\n"); - } - } else { - g_print (" Time Invalid\n"); - } -} - diff --git a/widgets/misc/test-mail-signatures.c b/widgets/misc/test-mail-signatures.c deleted file mode 100644 index 597e77effb..0000000000 --- a/widgets/misc/test-mail-signatures.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * test-mail-signatures.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include <stdlib.h> - -#include <libedataserver/libedataserver.h> - -#include <libevolution-utils/e-alert-sink.h> -#include <misc/e-mail-identity-combo-box.h> -#include <misc/e-mail-signature-combo-box.h> -#include <misc/e-mail-signature-manager.h> -#include <misc/e-mail-signature-preview.h> - -static GCancellable *cancellable = NULL; - -static void -signature_loaded_cb (EMailSignatureComboBox *combo_box, - GAsyncResult *result, - EWebView *web_view) -{ - gchar *contents = NULL; - gboolean is_html; - GError *error = NULL; - - e_mail_signature_combo_box_load_selected_finish ( - combo_box, result, &contents, NULL, &is_html, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (contents == NULL); - g_object_unref (web_view); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (contents == NULL); - e_alert_submit ( - E_ALERT_SINK (web_view), - "widgets:no-load-signature", - error->message, NULL); - g_object_unref (web_view); - g_error_free (error); - return; - } - - if (contents == NULL) - e_web_view_clear (web_view); - else if (is_html) - e_web_view_load_string (web_view, contents); - else { - gchar *string; - - string = g_markup_printf_escaped ("<pre>%s</pre>", contents); - e_web_view_load_string (web_view, string); - g_free (string); - } - - g_free (contents); - - g_object_unref (web_view); -} - -static void -signature_combo_changed_cb (EMailSignatureComboBox *combo_box, - EWebView *web_view) -{ - if (cancellable != NULL) { - g_cancellable_cancel (cancellable); - g_object_unref (cancellable); - } - - cancellable = g_cancellable_new (); - - e_mail_signature_combo_box_load_selected ( - combo_box, G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) signature_loaded_cb, - g_object_ref (web_view)); -} - -gint -main (gint argc, - gchar **argv) -{ - ESourceRegistry *registry; - GtkWidget *container; - GtkWidget *widget; - GtkWidget *vbox; - GtkWidget *identity_combo; - GtkWidget *signature_combo; - GError *error = NULL; - - gtk_init (&argc, &argv); - - registry = e_source_registry_new_sync (NULL, &error); - - if (error != NULL) { - g_printerr ("%s\n", error->message); - exit (EXIT_FAILURE); - } - - /* Construct the widgets. */ - - widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (widget), "Mail Signatures"); - gtk_window_set_default_size (GTK_WINDOW (widget), 400, 400); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - gtk_widget_show (widget); - - g_signal_connect ( - widget, "delete-event", - G_CALLBACK (gtk_main_quit), NULL); - - container = widget; - - widget = gtk_vbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = vbox = widget; - - widget = gtk_label_new ("<b>EMailSignatureComboBox</b>"); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = gtk_vbox_new (FALSE, 6); - gtk_widget_set_margin_left (widget, 12); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = e_mail_signature_combo_box_new (registry); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - signature_combo = widget; - gtk_widget_show (widget); - - widget = e_mail_identity_combo_box_new (registry); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - identity_combo = 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_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - widget = e_web_view_new (); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - g_signal_connect ( - signature_combo, "changed", - G_CALLBACK (signature_combo_changed_cb), widget); - - container = vbox; - - widget = gtk_label_new ("<b>EMailSignatureManager</b>"); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - widget = e_mail_signature_manager_new (registry); - gtk_widget_set_margin_left (widget, 12); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - g_object_bind_property ( - identity_combo, "active-id", - signature_combo, "identity-uid", - G_BINDING_SYNC_CREATE); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c deleted file mode 100644 index 4ad30e2245..0000000000 --- a/widgets/misc/test-preferences-window.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * test-preferences-window.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "e-preferences-window.c" - -#include <gtk/gtk.h> - -static GtkWidget * -create_page_number (gint i) -{ - gchar *caption; - GtkWidget *widget; - - caption = g_strdup_printf ("Title of page %d", i); - - widget = gtk_label_new (caption); - gtk_widget_show (widget); - - g_free (caption); - - return widget; -} - -static GtkWidget * -create_page_zero (EPreferencesWindow *preferences_window) -{ - return create_page_number (0); -} -static GtkWidget * -create_page_one (EPreferencesWindow *preferences_window) -{ - return create_page_number (1); -} -static GtkWidget * -create_page_two (EPreferencesWindow *preferences_window) -{ - return create_page_number (2); -} - -static void -add_pages (EPreferencesWindow *preferences_window) -{ - e_preferences_window_add_page ( - preferences_window, "page-0", - "gtk-properties", "title 0", NULL, - create_page_zero, 0); - e_preferences_window_add_page ( - preferences_window, "page-1", - "gtk-properties", "title 1", NULL, - create_page_one, 1); - e_preferences_window_add_page ( - preferences_window, "page-2", - "gtk-properties", "title 2", NULL, - create_page_two, 2); -} - -static gint -delete_event_callback (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); - - return TRUE; -} - -gint -main (gint argc, - gchar **argv) -{ - GtkWidget *window; - - gtk_init (&argc, &argv); - - window = e_preferences_window_new (NULL); - gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); - - g_signal_connect ( - window, "delete-event", - G_CALLBACK (delete_event_callback), NULL); - - add_pages (E_PREFERENCES_WINDOW (window)); - e_preferences_window_setup (E_PREFERENCES_WINDOW (window)); - - gtk_widget_show (window); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/test-source-config.c b/widgets/misc/test-source-config.c deleted file mode 100644 index 4a5ce30d91..0000000000 --- a/widgets/misc/test-source-config.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <stdlib.h> -#include <gtk/gtk.h> - -#include <libedataserver/libedataserver.h> - -#include "e-source-config-dialog.h" - -static void -dialog_response (GtkDialog *dialog, - gint response_id) -{ - gtk_main_quit (); -} - -gint -main (gint argc, - gchar **argv) -{ - ESourceRegistry *registry; - ESource *source = NULL; - GtkWidget *config; - GtkWidget *dialog; - GError *error = NULL; - - gtk_init (&argc, &argv); - - registry = e_source_registry_new_sync (NULL, &error); - - if (error != NULL) { - g_printerr ("%s\n", error->message); - exit (EXIT_FAILURE); - } - - if (argc > 1) { - source = e_source_registry_ref_source (registry, argv[1]); - if (source == NULL) { - g_printerr ("No such UID: %s\n", argv[1]); - exit (EXIT_FAILURE); - } - } - - config = e_source_config_new (registry, source); - dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config)); - - g_signal_connect ( - dialog, "response", - G_CALLBACK (dialog_response), NULL); - - gtk_widget_show (config); - gtk_widget_show (dialog); - - g_object_unref (source); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/widgets.error.xml b/widgets/misc/widgets.error.xml deleted file mode 100644 index efaa41c42e..0000000000 --- a/widgets/misc/widgets.error.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<error-list domain="widgets"> - - <error id="ask-signature-changed" type="question" default="GTK_RESPONSE_YES"> - <_primary>Do you wish to save your changes?</_primary> - <_secondary xml:space="preserve">This signature has been changed, but has not been saved.</_secondary> - <button _label="_Discard changes" response="GTK_RESPONSE_NO"/> - <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/> - <button stock="gtk-save" response="GTK_RESPONSE_YES"/> - </error> - - <error id="blank-signature" type="error"> - <_primary>Blank Signature</_primary> - <_secondary>Please provide an unique name to identify this signature.</_secondary> - </error> - - <error id="no-load-signature" type="error"> - <_primary>Could not load signature.</_primary> - <secondary xml:space="preserve">{0}</secondary> - </error> - - <error id="no-save-signature" type="error"> - <_primary>Could not save signature.</_primary> - <secondary xml:space="preserve">{0}</secondary> - </error> - -</error-list> - diff --git a/widgets/table/Makefile.am b/widgets/table/Makefile.am deleted file mode 100644 index 216a9fee98..0000000000 --- a/widgets/table/Makefile.am +++ /dev/null @@ -1,193 +0,0 @@ -ui_DATA = \ - e-table-config.ui - -privsolib_LTLIBRARIES = libetable.la - -libetable_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - -DEVOLUTION_UIDIR=\"$(uidir)\" \ - -DG_LOG_DOMAIN=\"e-table\" - -libetable_la_SOURCES = \ - e-cell.c \ - e-cell-checkbox.c \ - e-cell-combo.c \ - e-cell-date.c \ - e-cell-date-edit.c \ - e-cell-number.c \ - e-cell-percent.c \ - e-cell-pixbuf.c \ - e-cell-popup.c \ - e-cell-size.c \ - e-cell-text.c \ - e-cell-toggle.c \ - e-cell-tree.c \ - e-cell-vbox.c \ - e-cell-hbox.c \ - e-popup-menu.c \ - e-table-click-to-add.c \ - e-table-col.c \ - e-table-column-specification.c \ - e-table-config.c \ - e-table-extras.c \ - e-table-field-chooser-dialog.c \ - e-table-field-chooser-item.c \ - e-table-field-chooser.c \ - e-table-group.c \ - e-table-group-container.c \ - e-table-group-leaf.c \ - e-table-header.c \ - e-table-header-item.c \ - e-table-header-utils.c \ - e-table-item.c \ - e-table-memory-callbacks.c \ - e-table-memory-store.c \ - e-table-memory.c \ - e-table-model.c \ - e-table-one.c \ - e-table-search.c \ - e-table-selection-model.c \ - e-table-sort-info.c \ - e-table-sorted.c \ - e-table-sorted-variable.c \ - e-table-sorter.c \ - e-table-sorting-utils.c \ - e-table-specification.c \ - e-table-state.c \ - e-table-subset.c \ - e-table-subset-variable.c \ - e-table-utils.c \ - e-table-without.c \ - e-table.c \ - e-tree-memory-callbacks.c \ - e-tree-memory.c \ - e-tree-model.c \ - e-tree-selection-model.c \ - e-tree-sorted.c \ - e-tree-table-adapter.c \ - e-tree.c \ - gal-a11y-e-cell.c \ - gal-a11y-e-cell-popup.c \ - gal-a11y-e-cell-registry.c \ - gal-a11y-e-cell-toggle.c \ - gal-a11y-e-cell-tree.c \ - gal-a11y-e-cell-vbox.c \ - gal-a11y-e-table.c \ - gal-a11y-e-table-click-to-add.c \ - gal-a11y-e-table-click-to-add-factory.c \ - gal-a11y-e-table-column-header.c \ - gal-a11y-e-table-factory.c \ - gal-a11y-e-table-item.c \ - gal-a11y-e-table-item-factory.c \ - gal-a11y-e-tree.c \ - gal-a11y-e-tree-factory.c - -libetableincludedir = $(privincludedir)/table - -libetableinclude_HEADERS = \ - e-cell.h \ - e-cell-checkbox.h \ - e-cell-combo.h \ - e-cell-date.h \ - e-cell-date-edit.h \ - e-cell-number.h \ - e-cell-percent.h \ - e-cell-pixbuf.h \ - e-cell-popup.h \ - e-cell-size.h \ - e-cell-text.h \ - e-cell-toggle.h \ - e-cell-tree.h \ - e-cell-vbox.h \ - e-cell-hbox.h \ - e-popup-menu.h \ - e-table-click-to-add.h \ - e-table-col-dnd.h \ - e-table-col.h \ - e-table-column-specification.h \ - e-table-config.h \ - e-table-defines.h \ - e-table-extras.h \ - e-table-field-chooser-dialog.h \ - e-table-field-chooser-item.h \ - e-table-field-chooser.h \ - e-table-group.h \ - e-table-group-container.h \ - e-table-group-leaf.h \ - e-table-header.h \ - e-table-header-item.h \ - e-table-header-utils.h \ - e-table-item.h \ - e-table-memory-callbacks.h \ - e-table-memory-store.h \ - e-table-memory.h \ - e-table-model.h \ - e-table-one.h \ - e-table-search.h \ - e-table-selection-model.h \ - e-table-sort-info.h \ - e-table-sorted.h \ - e-table-sorted-variable.h \ - e-table-sorter.h \ - e-table-sorting-utils.h \ - e-table-specification.h \ - e-table-state.h \ - e-table-subset.h \ - e-table-subset-variable.h \ - e-table-utils.h \ - e-table-without.h \ - e-table.h \ - e-tree-memory-callbacks.h \ - e-tree-memory.h \ - e-tree-model.h \ - e-tree-selection-model.h \ - e-tree-sorted.h \ - e-tree-table-adapter.h \ - e-tree.h \ - gal-a11y-e-cell.h \ - gal-a11y-e-cell-popup.h \ - gal-a11y-e-cell-registry.h \ - gal-a11y-e-cell-toggle.h \ - gal-a11y-e-cell-tree.h \ - gal-a11y-e-cell-vbox.h \ - gal-a11y-e-table.h \ - gal-a11y-e-table-click-to-add.h \ - gal-a11y-e-table-click-to-add-factory.h \ - gal-a11y-e-table-column-header.h \ - gal-a11y-e-table-factory.h \ - gal-a11y-e-table-item.h \ - gal-a11y-e-table-item-factory.h \ - gal-a11y-e-tree.h \ - gal-a11y-e-tree-factory.h - -libetable_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libetable_la_LIBADD = \ - $(top_builddir)/a11y/libevolution-a11y.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/widgets/text/libetext.la \ - $(top_builddir)/libgnomecanvas/libgnomecanvas.la \ - $(top_builddir)/libemail-utils/libemail-utils.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(MATH_LIB) - -icons = \ - arrow-down.xpm \ - arrow-up.xpm \ - check-empty.xpm \ - check-filled.xpm \ - tree-expanded.xpm \ - tree-unexpanded.xpm - -EXTRA_DIST = \ - $(icons) \ - $(ui_DATA) - --include $(top_srcdir)/git.mk diff --git a/widgets/table/arrow-down.xpm b/widgets/table/arrow-down.xpm deleted file mode 100644 index f1e6cb4b3c..0000000000 --- a/widgets/table/arrow-down.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * arrow_down_xpm[] = { -"13 16 2 1", -" c None", -". c #FF0000", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -".............", -" ........... ", -" ......... ", -" ....... ", -" ..... ", -" ... ", -" . "}; diff --git a/widgets/table/arrow-up.xpm b/widgets/table/arrow-up.xpm deleted file mode 100644 index 0cc5b9a00c..0000000000 --- a/widgets/table/arrow-up.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * arrow_up_xpm[] = { -"13 16 2 1", -" c None", -". c #FF0000", -" . ", -" ... ", -" ..... ", -" ....... ", -" ......... ", -" ........... ", -".............", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... ", -" ... "}; diff --git a/widgets/table/check-empty.xpm b/widgets/table/check-empty.xpm deleted file mode 100644 index 746b20234e..0000000000 --- a/widgets/table/check-empty.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * check_empty_xpm[] = { -"16 16 2 1", -" c None", -". c #000000", -" ", -" ", -" ............ ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" ............ ", -" ", -" "}; diff --git a/widgets/table/check-filled.xpm b/widgets/table/check-filled.xpm deleted file mode 100644 index c0468fc25b..0000000000 --- a/widgets/table/check-filled.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * check_filled_xpm[] = { -"16 16 2 1", -" c None", -". c #000000", -" ", -" ", -" ............ ", -" . . ", -" . . . ", -" . .. . ", -" . ... . ", -" . . ... . ", -" . .. ... . ", -" . ..... . ", -" . ... . ", -" . . . ", -" . . ", -" ............ ", -" ", -" "}; diff --git a/widgets/table/e-cell-checkbox.c b/widgets/table/e-cell-checkbox.c deleted file mode 100644 index 0d30031397..0000000000 --- a/widgets/table/e-cell-checkbox.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "e-util/e-util.h" - -#include "e-table-item.h" -#include "e-cell-checkbox.h" - -#include "check-empty.xpm" -#include "check-filled.xpm" - -G_DEFINE_TYPE (ECellCheckbox, e_cell_checkbox, E_TYPE_CELL_TOGGLE) - -static GdkPixbuf *checks[2]; - -static void -ecc_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - cairo_t *cr = gtk_print_context_get_cairo_context (context); - const gint value = GPOINTER_TO_INT ( - e_table_model_value_at ( - ecell_view->e_table_model, model_col, row)); - cairo_save (cr); - - if (value == 1) { - cairo_set_line_width (cr, 2); - cairo_move_to (cr, 3, 11); - cairo_line_to (cr, 7, 14); - cairo_line_to (cr, 11, 5); - cairo_stroke (cr); - } - - cairo_restore (cr); -} - -static void -e_cell_checkbox_class_init (ECellCheckboxClass *class) -{ - ECellClass *ecc = E_CELL_CLASS (class); - - ecc->print = ecc_print; - checks[0] = gdk_pixbuf_new_from_xpm_data (check_empty_xpm); - checks[1] = gdk_pixbuf_new_from_xpm_data (check_filled_xpm); -} - -static void -e_cell_checkbox_init (ECellCheckbox *eccb) -{ - GPtrArray *pixbufs; - - pixbufs = e_cell_toggle_get_pixbufs (E_CELL_TOGGLE (eccb)); - - g_ptr_array_add (pixbufs, g_object_ref (checks[0])); - g_ptr_array_add (pixbufs, g_object_ref (checks[1])); -} - -/** - * e_cell_checkbox_new: - * - * Creates a new ECell renderer that can be used to render check - * boxes. the data provided from the model is cast to an integer. - * zero is used for the off display, and non-zero for checked status. - * - * Returns: an ECell object that can be used to render checkboxes. - */ -ECell * -e_cell_checkbox_new (void) -{ - return g_object_new (E_TYPE_CELL_CHECKBOX, NULL); -} diff --git a/widgets/table/e-cell-checkbox.h b/widgets/table/e-cell-checkbox.h deleted file mode 100644 index 8306b2d29a..0000000000 --- a/widgets/table/e-cell-checkbox.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CELL_CHECKBOX_H_ -#define _E_CELL_CHECKBOX_H_ - -#include <table/e-cell-toggle.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_CHECKBOX \ - (e_cell_checkbox_get_type ()) -#define E_CELL_CHECKBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_CHECKBOX, ECellCheckbox)) -#define E_CELL_CHECKBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_CHECKBOX, ECellCheckboxClass)) -#define E_IS_CELL_CHECKBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_CHECKBOX)) -#define E_IS_CELL_CHECKBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_CHECKBOX)) -#define E_CELL_CHECKBOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_CHECKBOX, ECellCheckboxClass)) - -G_BEGIN_DECLS - -typedef struct _ECellCheckbox ECellCheckbox; -typedef struct _ECellCheckboxClass ECellCheckboxClass; - -struct _ECellCheckbox { - ECellToggle parent; -}; - -struct _ECellCheckboxClass { - ECellToggleClass parent_class; -}; - -GType e_cell_checkbox_get_type (void) G_GNUC_CONST; -ECell * e_cell_checkbox_new (void); - -G_END_DECLS - -#endif /* _E_CELL_CHECKBOX_H_ */ - diff --git a/widgets/table/e-cell-combo.c b/widgets/table/e-cell-combo.c deleted file mode 100644 index bc82042d7a..0000000000 --- a/widgets/table/e-cell-combo.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - * e-cell-combo.c: Combo cell renderer - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellCombo - a subclass of ECellPopup used to support popup lists like a - * GtkCombo widget. It only supports a basic popup list of strings at present, - * with no auto-completion. - */ - -/* - * Notes: (handling pointer grabs and GTK+ grabs is a nightmare!) - * - * o We must grab the pointer when we show the popup, so that if any buttons - * are pressed outside the application we hide the popup. - * - * o We have to be careful when popping up any widgets which also grab the - * pointer at some point, since we will lose our own pointer grab. - * When we pop up a list it will grab the pointer itself when an item is - * selected, and release the grab when the button is released. - * Fortunately we hide the popup at this point, so it isn't a problem. - * But for other types of widgets in the popup it could cause trouble. - * - I think GTK+ should provide help for this (nested pointer grabs?). - * - * o We must set the 'owner_events' flag of the pointer grab to TRUE so that - * pointer events get reported to all the application windows as normal. - * If we don't do this then the widgets in the popup may not work properly. - * - * o We must do a gtk_grab_add() so that we only allow events to go to the - * widgets within the popup (though some special events still get reported - * to the widget owning the window). Doing th gtk_grab_add() on the toplevel - * popup window should be fine. We can then check for any events that should - * close the popup, like the Escape key, or a button press outside the popup. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-unicode.h" - -#include "e-table-item.h" -#include "e-cell-combo.h" -#include "e-cell-text.h" - -#define d(x) - -/* The height to make the popup list if there aren't any items in it. */ -#define E_CELL_COMBO_LIST_EMPTY_HEIGHT 15 - -static void e_cell_combo_dispose (GObject *object); -static gint e_cell_combo_do_popup (ECellPopup *ecp, - GdkEvent *event, - gint row, - gint view_col); -static void e_cell_combo_select_matching_item - (ECellCombo *ecc); -static void e_cell_combo_show_popup (ECellCombo *ecc, - gint row, - gint view_col); -static void e_cell_combo_get_popup_pos (ECellCombo *ecc, - gint row, - gint view_col, - gint *x, - gint *y, - gint *height, - gint *width); -static void e_cell_combo_selection_changed (GtkTreeSelection *selection, - ECellCombo *ecc); -static gint e_cell_combo_button_press (GtkWidget *popup_window, - GdkEvent *button_event, - ECellCombo *ecc); -static gint e_cell_combo_button_release (GtkWidget *popup_window, - GdkEvent *button_event, - ECellCombo *ecc); -static gint e_cell_combo_key_press (GtkWidget *popup_window, - GdkEvent *key_event, - ECellCombo *ecc); -static void e_cell_combo_update_cell (ECellCombo *ecc); -static void e_cell_combo_restart_edit (ECellCombo *ecc); - -G_DEFINE_TYPE (ECellCombo, e_cell_combo, E_TYPE_CELL_POPUP) - -static void -e_cell_combo_class_init (ECellComboClass *class) -{ - ECellPopupClass *ecpc = E_CELL_POPUP_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = e_cell_combo_dispose; - - ecpc->popup = e_cell_combo_do_popup; -} - -static void -e_cell_combo_init (ECellCombo *ecc) -{ - GtkWidget *frame; - AtkObject *a11y; - GtkListStore *store; - GtkTreeSelection *selection; - GtkScrolledWindow *scrolled_window; - - /* We create one popup window for the ECell, since there will only - * ever be one popup in use at a time. */ - ecc->popup_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_type_hint ( - GTK_WINDOW (ecc->popup_window), GDK_WINDOW_TYPE_HINT_COMBO); - gtk_window_set_resizable (GTK_WINDOW (ecc->popup_window), TRUE); - - frame = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (ecc->popup_window), frame); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_widget_show (frame); - - ecc->popup_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - scrolled_window = GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window); - - gtk_scrolled_window_set_policy ( - scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_widget_set_can_focus ( - gtk_scrolled_window_get_hscrollbar (scrolled_window), FALSE); - gtk_widget_set_can_focus ( - gtk_scrolled_window_get_vscrollbar (scrolled_window), FALSE); - gtk_container_add (GTK_CONTAINER (frame), ecc->popup_scrolled_window); - gtk_widget_show (ecc->popup_scrolled_window); - - store = gtk_list_store_new (1, G_TYPE_STRING); - ecc->popup_tree_view = - gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - g_object_unref (store); - - gtk_tree_view_append_column ( - GTK_TREE_VIEW (ecc->popup_tree_view), - gtk_tree_view_column_new_with_attributes ( - "Text", gtk_cell_renderer_text_new (), - "text", 0, NULL)); - - gtk_tree_view_set_headers_visible ( - GTK_TREE_VIEW (ecc->popup_tree_view), FALSE); - - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (ecc->popup_tree_view)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - gtk_scrolled_window_add_with_viewport ( - GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window), - ecc->popup_tree_view); - gtk_container_set_focus_vadjustment ( - GTK_CONTAINER (ecc->popup_tree_view), - gtk_scrolled_window_get_vadjustment ( - GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window))); - gtk_container_set_focus_hadjustment ( - GTK_CONTAINER (ecc->popup_tree_view), - gtk_scrolled_window_get_hadjustment ( - GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window))); - gtk_widget_show (ecc->popup_tree_view); - - a11y = gtk_widget_get_accessible (ecc->popup_tree_view); - atk_object_set_name (a11y, _("popup list")); - - g_signal_connect ( - selection, "changed", - G_CALLBACK (e_cell_combo_selection_changed), ecc); - g_signal_connect ( - ecc->popup_window, "button_press_event", - G_CALLBACK (e_cell_combo_button_press), ecc); - g_signal_connect ( - ecc->popup_window, "button_release_event", - G_CALLBACK (e_cell_combo_button_release), ecc); - g_signal_connect ( - ecc->popup_window, "key_press_event", - G_CALLBACK (e_cell_combo_key_press), ecc); -} - -/** - * e_cell_combo_new: - * - * Creates a new ECellCombo renderer. - * - * Returns: an ECellCombo object. - */ -ECell * -e_cell_combo_new (void) -{ - return g_object_new (E_TYPE_CELL_COMBO, NULL); -} - -/* - * GObject::dispose method - */ -static void -e_cell_combo_dispose (GObject *object) -{ - ECellCombo *ecc = E_CELL_COMBO (object); - - if (ecc->popup_window != NULL) { - gtk_widget_destroy (ecc->popup_window); - ecc->popup_window = NULL; - } - - if (ecc->grabbed_keyboard != NULL) { - gdk_device_ungrab (ecc->grabbed_keyboard, GDK_CURRENT_TIME); - g_object_unref (ecc->grabbed_keyboard); - ecc->grabbed_keyboard = NULL; - } - - if (ecc->grabbed_pointer != NULL) { - gdk_device_ungrab (ecc->grabbed_pointer, GDK_CURRENT_TIME); - g_object_unref (ecc->grabbed_pointer); - ecc->grabbed_pointer = NULL; - } - - G_OBJECT_CLASS (e_cell_combo_parent_class)->dispose (object); -} - -void -e_cell_combo_set_popdown_strings (ECellCombo *ecc, - GList *strings) -{ - GList *elem; - GtkListStore *store; - - g_return_if_fail (E_IS_CELL_COMBO (ecc)); - g_return_if_fail (strings != NULL); - - store = GTK_LIST_STORE ( - gtk_tree_view_get_model ( - GTK_TREE_VIEW (ecc->popup_tree_view))); - gtk_list_store_clear (store); - - for (elem = strings; elem; elem = elem->next) { - GtkTreeIter iter; - gchar *utf8_text = elem->data; - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, utf8_text, -1); - } -} - -static gint -e_cell_combo_do_popup (ECellPopup *ecp, - GdkEvent *event, - gint row, - gint view_col) -{ - ECellCombo *ecc = E_CELL_COMBO (ecp); - GtkTreeSelection *selection; - GdkGrabStatus grab_status; - GdkWindow *window; - GdkDevice *keyboard; - GdkDevice *pointer; - GdkDevice *event_device; - guint32 event_time; - - g_return_val_if_fail (ecc->grabbed_keyboard == NULL, FALSE); - g_return_val_if_fail (ecc->grabbed_pointer == NULL, FALSE); - - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (ecc->popup_tree_view)); - - g_signal_handlers_block_by_func ( - selection, e_cell_combo_selection_changed, ecc); - - e_cell_combo_show_popup (ecc, row, view_col); - e_cell_combo_select_matching_item (ecc); - - g_signal_handlers_unblock_by_func ( - selection, e_cell_combo_selection_changed, ecc); - - window = gtk_widget_get_window (ecc->popup_tree_view); - - event_device = gdk_event_get_device (event); - event_time = gdk_event_get_time (event); - - if (gdk_device_get_source (event_device) == GDK_SOURCE_KEYBOARD) { - keyboard = event_device; - pointer = gdk_device_get_associated_device (event_device); - } else { - keyboard = gdk_device_get_associated_device (event_device); - pointer = event_device; - } - - if (pointer != NULL) { - grab_status = gdk_device_grab ( - pointer, - window, - GDK_OWNERSHIP_NONE, - TRUE, - GDK_ENTER_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK, - NULL, - event_time); - - if (grab_status != GDK_GRAB_SUCCESS) - return FALSE; - - ecc->grabbed_pointer = g_object_ref (pointer); - } - - gtk_grab_add (ecc->popup_window); - - if (keyboard != NULL) { - grab_status = gdk_device_grab ( - keyboard, - window, - GDK_OWNERSHIP_NONE, - TRUE, - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK, - NULL, - event_time); - - if (grab_status != GDK_GRAB_SUCCESS) { - if (ecc->grabbed_pointer != NULL) { - gdk_device_ungrab ( - ecc->grabbed_pointer, - event_time); - g_object_unref (ecc->grabbed_pointer); - ecc->grabbed_pointer = NULL; - } - return FALSE; - } - - ecc->grabbed_keyboard = g_object_ref (keyboard); - } - - return TRUE; -} - -static void -e_cell_combo_select_matching_item (ECellCombo *ecc) -{ - ECellPopup *ecp = E_CELL_POPUP (ecc); - ECellView *ecv = (ECellView *) ecp->popup_cell_view; - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ETableItem *eti; - ETableCol *ecol; - gboolean found = FALSE; - gchar *cell_text; - gboolean valid; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeModel *model; - - eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - cell_text = e_cell_text_get_text ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (ecc->popup_tree_view)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ecc->popup_tree_view)); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid && !found; - valid = gtk_tree_model_iter_next (model, &iter)) { - gchar *str = NULL; - - gtk_tree_model_get (model, &iter, 0, &str, -1); - - if (str && g_str_equal (str, cell_text)) { - GtkTreePath *path; - - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_view_set_cursor ( - GTK_TREE_VIEW (ecc->popup_tree_view), - path, NULL, FALSE); - gtk_tree_path_free (path); - - found = TRUE; - } - - g_free (str); - } - - if (!found) - gtk_tree_selection_unselect_all (selection); - - e_cell_text_free_text (ecell_text, cell_text); -} - -static void -e_cell_combo_show_popup (ECellCombo *ecc, - gint row, - gint view_col) -{ - GdkWindow *window; - GtkAllocation allocation; - gint x, y, width, height, old_width, old_height; - - gtk_widget_get_allocation (ecc->popup_window, &allocation); - - /* This code is practically copied from GtkCombo. */ - old_width = allocation.width; - old_height = allocation.height; - - e_cell_combo_get_popup_pos (ecc, row, view_col, &x, &y, &height, &width); - - /* workaround for gtk_scrolled_window_size_allocate bug */ - if (old_width != width || old_height != height) { - gtk_widget_hide ( - gtk_scrolled_window_get_hscrollbar ( - GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window))); - gtk_widget_hide ( - gtk_scrolled_window_get_vscrollbar ( - GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window))); - } - - gtk_window_move (GTK_WINDOW (ecc->popup_window), x, y); - gtk_widget_set_size_request (ecc->popup_window, width, height); - gtk_widget_realize (ecc->popup_window); - window = gtk_widget_get_window (ecc->popup_window); - gdk_window_resize (window, width, height); - gtk_widget_show (ecc->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecc), TRUE); - d (g_print ("%s: popup_shown = TRUE\n", __FUNCTION__)); -} - -/* Calculates the size and position of the popup window (like GtkCombo). */ -static void -e_cell_combo_get_popup_pos (ECellCombo *ecc, - gint row, - gint view_col, - gint *x, - gint *y, - gint *height, - gint *width) -{ - ECellPopup *ecp = E_CELL_POPUP (ecc); - ETableItem *eti; - GtkWidget *canvas; - GtkWidget *widget; - GtkWidget *popwin_child; - GtkWidget *popup_child; - GtkStyle *popwin_style; - GtkStyle *popup_style; - GdkWindow *window; - GtkBin *popwin; - GtkScrolledWindow *popup; - GtkRequisition requisition; - GtkRequisition list_requisition; - gboolean show_vscroll = FALSE, show_hscroll = FALSE; - gint avail_height, avail_width, min_height, work_height, screen_width; - gint column_width, row_height, scrollbar_width; - gdouble x1, y1; - gdouble wx, wy; - - eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - - /* This code is practically copied from GtkCombo. */ - popup = GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window); - popwin = GTK_BIN (ecc->popup_window); - - window = gtk_widget_get_window (canvas); - gdk_window_get_origin (window, x, y); - - x1 = e_table_header_col_diff (eti->header, 0, view_col + 1); - y1 = e_table_item_row_diff (eti, 0, row + 1); - column_width = e_table_header_col_diff ( - eti->header, view_col, view_col + 1); - row_height = e_table_item_row_diff (eti, row, row + 1); - gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1); - - gnome_canvas_world_to_window ( - GNOME_CANVAS (canvas), x1, y1, &wx, &wy); - - x1 = wx; - y1 = wy; - - *x += x1; - /* The ETable positions don't include the grid lines, I think, so we add 1. */ - *y += y1 + 1 - (gint) - gtk_adjustment_get_value ( - gtk_scrollable_get_vadjustment ( - GTK_SCROLLABLE (&((GnomeCanvas *) canvas)->layout))) - + ((GnomeCanvas *) canvas)->zoom_yofs; - - widget = gtk_scrolled_window_get_vscrollbar (popup); - gtk_widget_get_preferred_size (widget, &requisition, NULL); - - scrollbar_width = - requisition.width - + GTK_SCROLLED_WINDOW_CLASS (G_OBJECT_GET_CLASS (popup))->scrollbar_spacing; - - avail_height = gdk_screen_height () - *y; - - /* We'll use the entire screen width if needed, but we save space for - * the vertical scrollbar in case we need to show that. */ - screen_width = gdk_screen_width (); - avail_width = screen_width - scrollbar_width; - - widget = gtk_scrolled_window_get_vscrollbar (popup); - gtk_widget_get_preferred_size (widget, &requisition, NULL); - - gtk_widget_get_preferred_size (ecc->popup_tree_view, &list_requisition, NULL); - min_height = MIN (list_requisition.height, requisition.height); - if (!gtk_tree_model_iter_n_children ( - gtk_tree_view_get_model ( - GTK_TREE_VIEW (ecc->popup_tree_view)), NULL)) - list_requisition.height += E_CELL_COMBO_LIST_EMPTY_HEIGHT; - - popwin_child = gtk_bin_get_child (popwin); - popwin_style = gtk_widget_get_style (popwin_child); - - popup_child = gtk_bin_get_child (GTK_BIN (popup)); - popup_style = gtk_widget_get_style (popup_child); - - /* Calculate the desired width. */ - *width = list_requisition.width - + 2 * popwin_style->xthickness - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popwin_child)) - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popup)) - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popup_child)) - + 2 * popup_style->xthickness; - - /* Use at least the same width as the column. */ - if (*width < column_width) - *width = column_width; - - /* If it is larger than the available width, use that instead and show - * the horizontal scrollbar. */ - if (*width > avail_width) { - *width = avail_width; - show_hscroll = TRUE; - } - - /* Calculate all the borders etc. that we need to add to the height. */ - work_height = (2 * popwin_style->ythickness - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popwin_child)) - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popup)) - + 2 * gtk_container_get_border_width (GTK_CONTAINER (popup_child)) - + 2 * popup_style->xthickness); - - widget = gtk_scrolled_window_get_hscrollbar (popup); - gtk_widget_get_preferred_size (widget, &requisition, NULL); - - /* Add on the height of the horizontal scrollbar if we need it. */ - if (show_hscroll) - work_height += - requisition.height + - GTK_SCROLLED_WINDOW_GET_CLASS (popup)->scrollbar_spacing; - - /* Check if it fits in the available height. */ - if (work_height + list_requisition.height > avail_height) { - /* It doesn't fit, so we see if we have the minimum space - * needed. */ - if (work_height + min_height > avail_height - && *y - row_height > avail_height) { - /* We don't, so we show the popup above the cell - * instead of below it. */ - avail_height = *y - row_height; - *y -= (work_height + list_requisition.height - + row_height); - if (*y < 0) - *y = 0; - } - } - - /* Check if we still need the vertical scrollbar. */ - if (work_height + list_requisition.height > avail_height) { - *width += scrollbar_width; - show_vscroll = TRUE; - } - - /* We try to line it up with the right edge of the column, but we don't - * want it to go off the edges of the screen. */ - if (*x > screen_width) - *x = screen_width; - *x -= *width; - if (*x < 0) - *x = 0; - - if (show_vscroll) - *height = avail_height; - else - *height = work_height + list_requisition.height; -} - -static void -e_cell_combo_selection_changed (GtkTreeSelection *selection, - ECellCombo *ecc) -{ - GtkTreeIter iter; - GtkTreeModel *model; - - if (!gtk_widget_get_realized (ecc->popup_window) || - !gtk_tree_selection_get_selected (selection, &model, &iter)) - return; - - e_cell_combo_update_cell (ecc); - e_cell_combo_restart_edit (ecc); -} - -/* This handles button press events in the popup window. - * Note that since we have a pointer grab on this window, we also get button - * press events for windows outside the application here, so we hide the popup - * window if that happens. We also get propagated events from child widgets - * which we ignore. */ -static gint -e_cell_combo_button_press (GtkWidget *popup_window, - GdkEvent *button_event, - ECellCombo *ecc) -{ - GtkWidget *event_widget; - guint32 event_time; - - event_time = gdk_event_get_time (button_event); - event_widget = gtk_get_event_widget (button_event); - - /* If the button press was for a widget inside the popup list, but - * not the popup window itself, then we ignore the event and return - * FALSE. Otherwise we will hide the popup. - * Note that since we have a pointer grab on the popup list, button - * presses outside the application will be reported to this window, - * which is why we hide the popup in this case. */ - while (event_widget) { - event_widget = gtk_widget_get_parent (event_widget); - if (event_widget == ecc->popup_tree_view) - return FALSE; - } - - gtk_grab_remove (ecc->popup_window); - - if (ecc->grabbed_keyboard != NULL) { - gdk_device_ungrab (ecc->grabbed_keyboard, event_time); - g_object_unref (ecc->grabbed_keyboard); - ecc->grabbed_keyboard = NULL; - } - - if (ecc->grabbed_pointer != NULL) { - gdk_device_ungrab (ecc->grabbed_pointer, event_time); - g_object_unref (ecc->grabbed_pointer); - ecc->grabbed_pointer = NULL; - } - - gtk_widget_hide (ecc->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE); - d (g_print ("%s: popup_shown = FALSE\n", __FUNCTION__)); - - /* We don't want to update the cell here. Since the list is in browse - * mode there will always be one item selected, so when we popup the - * list one item is selected even if it doesn't match the current text - * in the cell. So if you click outside the popup (which is what has - * happened here) it is better to not update the cell. */ - /*e_cell_combo_update_cell (ecc);*/ - e_cell_combo_restart_edit (ecc); - - return TRUE; -} - -/* This handles button release events in the popup window. If the button is - * released inside the list, we want to hide the popup window and update the - * cell with the new selection. */ -static gint -e_cell_combo_button_release (GtkWidget *popup_window, - GdkEvent *button_event, - ECellCombo *ecc) -{ - GtkWidget *event_widget; - guint32 event_time; - - event_time = gdk_event_get_time (button_event); - event_widget = gtk_get_event_widget (button_event); - - /* See if the button was released in the list (or its children). */ - while (event_widget && event_widget != ecc->popup_tree_view) - event_widget = gtk_widget_get_parent (event_widget); - - /* If it wasn't, then we just ignore the event. */ - if (event_widget != ecc->popup_tree_view) - return FALSE; - - /* The button was released inside the list, so we hide the popup and - * update the cell to reflect the new selection. */ - - gtk_grab_remove (ecc->popup_window); - - if (ecc->grabbed_keyboard != NULL) { - gdk_device_ungrab (ecc->grabbed_keyboard, event_time); - g_object_unref (ecc->grabbed_keyboard); - ecc->grabbed_keyboard = NULL; - } - - if (ecc->grabbed_pointer != NULL) { - gdk_device_ungrab (ecc->grabbed_pointer, event_time); - g_object_unref (ecc->grabbed_pointer); - ecc->grabbed_pointer = NULL; - } - - gtk_widget_hide (ecc->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE); - d (g_print ("%s: popup_shown = FALSE\n", __FUNCTION__)); - - e_cell_combo_update_cell (ecc); - e_cell_combo_restart_edit (ecc); - - return TRUE; -} - -/* This handles key press events in the popup window. If the Escape key is - * pressed we hide the popup, and do not change the cell contents. */ -static gint -e_cell_combo_key_press (GtkWidget *popup_window, - GdkEvent *key_event, - ECellCombo *ecc) -{ - guint event_keyval = 0; - guint32 event_time; - - gdk_event_get_keyval (key_event, &event_keyval); - event_time = gdk_event_get_time (key_event); - - /* If the Escape key is pressed we hide the popup. */ - if (event_keyval != GDK_KEY_Escape - && event_keyval != GDK_KEY_Return - && event_keyval != GDK_KEY_KP_Enter - && event_keyval != GDK_KEY_ISO_Enter - && event_keyval != GDK_KEY_3270_Enter) - return FALSE; - - if (event_keyval == GDK_KEY_Escape && - (!ecc->popup_window || !gtk_widget_get_visible (ecc->popup_window))) - return FALSE; - - gtk_grab_remove (ecc->popup_window); - - if (ecc->grabbed_keyboard != NULL) { - gdk_device_ungrab (ecc->grabbed_keyboard, event_time); - g_object_unref (ecc->grabbed_keyboard); - ecc->grabbed_keyboard = NULL; - } - - if (ecc->grabbed_pointer != NULL) { - gdk_device_ungrab (ecc->grabbed_pointer, event_time); - g_object_unref (ecc->grabbed_pointer); - ecc->grabbed_pointer = NULL; - } - - gtk_widget_hide (ecc->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE); - d (g_print ("%s: popup_shown = FALSE\n", __FUNCTION__)); - - if (event_keyval != GDK_KEY_Escape) - e_cell_combo_update_cell (ecc); - - e_cell_combo_restart_edit (ecc); - - return TRUE; -} - -static void -e_cell_combo_update_cell (ECellCombo *ecc) -{ - ECellPopup *ecp = E_CELL_POPUP (ecc); - ECellView *ecv = (ECellView *) ecp->popup_cell_view; - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - ETableCol *ecol; - GtkTreeSelection *selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (ecc->popup_tree_view)); - GtkTreeModel *model; - GtkTreeIter iter; - gchar *text = NULL, *old_text; - - /* Return if no item is selected. */ - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return; - - /* Get the text of the selected item. */ - gtk_tree_model_get (model, &iter, 0, &text, -1); - g_return_if_fail (text != NULL); - - /* Compare it with the existing cell contents. */ - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - - old_text = e_cell_text_get_text ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* If they are different, update the cell contents. */ - if (old_text && strcmp (old_text, text)) { - e_cell_text_set_value ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row, text); - } - - e_cell_text_free_text (ecell_text, old_text); - g_free (text); -} - -static void -e_cell_combo_restart_edit (ECellCombo *ecc) -{ - /* This doesn't work. ETable stops the edit straight-away again. */ -#if 0 - ECellView *ecv = (ECellView *) ecc->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - - e_table_item_enter_edit (eti, ecc->popup_view_col, ecc->popup_row); -#endif -} - diff --git a/widgets/table/e-cell-combo.h b/widgets/table/e-cell-combo.h deleted file mode 100644 index 3d2fb339de..0000000000 --- a/widgets/table/e-cell-combo.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellCombo - a subclass of ECellPopup used to support popup lists like a - * GtkCombo widget. It only supports a basic popup list of strings at present, - * with no auto-completion. The child ECell of the ECellPopup must be an - * ECellText or subclass. - */ - -#ifndef _E_CELL_COMBO_H_ -#define _E_CELL_COMBO_H_ - -#include <table/e-cell-popup.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_COMBO \ - (e_cell_combo_get_type ()) -#define E_CELL_COMBO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_COMBO, ECellCombo)) -#define E_CELL_COMBO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_COMBO, ECellComboClass)) -#define E_IS_CELL_COMBO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_COMBO)) -#define E_IS_CELL_COMBO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_COMBO)) -#define E_CELL_COMBO_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_COMBO, ECellComboClass)) - -G_BEGIN_DECLS - -typedef struct _ECellCombo ECellCombo; -typedef struct _ECellComboClass ECellComboClass; - -struct _ECellCombo { - ECellPopup parent; - - GtkWidget *popup_window; - GtkWidget *popup_scrolled_window; - GtkWidget *popup_tree_view; - - GdkDevice *grabbed_keyboard; - GdkDevice *grabbed_pointer; -}; - -struct _ECellComboClass { - ECellPopupClass parent_class; -}; - -GType e_cell_combo_get_type (void) G_GNUC_CONST; -ECell * e_cell_combo_new (void); - -/* These must be UTF-8. */ -void e_cell_combo_set_popdown_strings - (ECellCombo *ecc, - GList *strings); - -G_END_DECLS - -#endif /* _E_CELL_COMBO_H_ */ diff --git a/widgets/table/e-cell-date-edit.c b/widgets/table/e-cell-date-edit.c deleted file mode 100644 index be834f5686..0000000000 --- a/widgets/table/e-cell-date-edit.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-cell-date-edit.h" - -#include <string.h> -#include <time.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "e-table-item.h" -#include "e-cell-text.h" - -#include <glib/gi18n.h> - -#include <libedataserver/libedataserver.h> - -/* This depends on ECalendar which is why I didn't put it in gal. */ -#include <misc/e-calendar.h> - -static void e_cell_date_edit_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void e_cell_date_edit_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void e_cell_date_edit_dispose (GObject *object); - -static gint e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event, - gint row, - gint view_col); -static void e_cell_date_edit_set_popup_values (ECellDateEdit *ecde); -static void e_cell_date_edit_select_matching_time (ECellDateEdit *ecde, - gchar *time); -static void e_cell_date_edit_show_popup (ECellDateEdit *ecde, - gint row, - gint view_col); -static void e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - gint row, - gint view_col, - gint *x, - gint *y, - gint *height, - gint *width); - -static void e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde); - -static gint e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde); -static gint e_cell_date_edit_button_press (GtkWidget *popup_window, - GdkEvent *button_event, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde); -static void e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_update_cell (ECellDateEdit *ecde, - const gchar *text); -static void e_cell_date_edit_on_time_selected (GtkTreeSelection *selection, - ECellDateEdit *ecde); -static void e_cell_date_edit_hide_popup (ECellDateEdit *ecde); - -/* Our arguments. */ -enum { - PROP_0, - PROP_SHOW_TIME, - PROP_SHOW_NOW_BUTTON, - PROP_SHOW_TODAY_BUTTON, - PROP_ALLOW_NO_DATE_SET, - PROP_USE_24_HOUR_FORMAT, - PROP_LOWER_HOUR, - PROP_UPPER_HOUR -}; - -G_DEFINE_TYPE (ECellDateEdit, e_cell_date_edit, E_TYPE_CELL_POPUP) - -static void -e_cell_date_edit_class_init (ECellDateEditClass *class) -{ - GObjectClass *object_class; - ECellPopupClass *ecpc; - - object_class = G_OBJECT_CLASS (class); - object_class->get_property = e_cell_date_edit_get_property; - object_class->set_property = e_cell_date_edit_set_property; - object_class->dispose = e_cell_date_edit_dispose; - - ecpc = E_CELL_POPUP_CLASS (class); - ecpc->popup = e_cell_date_edit_do_popup; - - g_object_class_install_property ( - object_class, - PROP_SHOW_TIME, - g_param_spec_boolean ( - "show_time", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_NOW_BUTTON, - g_param_spec_boolean ( - "show_now_button", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_TODAY_BUTTON, - g_param_spec_boolean ( - "show_today_button", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ALLOW_NO_DATE_SET, - g_param_spec_boolean ( - "allow_no_date_set", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_USE_24_HOUR_FORMAT, - g_param_spec_boolean ( - "use_24_hour_format", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_LOWER_HOUR, - g_param_spec_int ( - "lower_hour", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UPPER_HOUR, - g_param_spec_int ( - "upper_hour", - NULL, - NULL, - G_MININT, - G_MAXINT, - 24, - G_PARAM_READWRITE)); -} - -static void -e_cell_date_edit_init (ECellDateEdit *ecde) -{ - GtkWidget *frame, *vbox, *hbox, *vbox2; - GtkWidget *scrolled_window, *bbox, *tree_view; - GtkWidget *now_button, *today_button, *none_button, *ok_button; - GtkListStore *store; - - ecde->lower_hour = 0; - ecde->upper_hour = 24; - ecde->use_24_hour_format = TRUE; - ecde->need_time_list_rebuild = TRUE; - ecde->freeze_count = 0; - ecde->time_callback = NULL; - ecde->time_callback_data = NULL; - ecde->time_callback_destroy = NULL; - - /* We create one popup window for the ECell, since there will only - * ever be one popup in use at a time. */ - ecde->popup_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_type_hint ( - GTK_WINDOW (ecde->popup_window), - GDK_WINDOW_TYPE_HINT_COMBO); - gtk_window_set_resizable (GTK_WINDOW (ecde->popup_window), TRUE); - - frame = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (ecde->popup_window), frame); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_widget_show (vbox); - - hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - ecde->calendar = e_calendar_new (); - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem), - "move_selection_when_moving", FALSE, - NULL); - gtk_box_pack_start (GTK_BOX (hbox), ecde->calendar, TRUE, TRUE, 0); - gtk_widget_show (ecde->calendar); - - vbox2 = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); - gtk_widget_show (vbox2); - - ecde->time_entry = gtk_entry_new (); - gtk_widget_set_size_request (ecde->time_entry, 50, -1); - gtk_box_pack_start ( - GTK_BOX (vbox2), ecde->time_entry, - FALSE, FALSE, 0); - gtk_widget_show (ecde->time_entry); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_widget_show (scrolled_window); - - store = gtk_list_store_new (1, G_TYPE_STRING); - tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - g_object_unref (store); - - gtk_tree_view_append_column ( - GTK_TREE_VIEW (tree_view), - gtk_tree_view_column_new_with_attributes ( - "Text", gtk_cell_renderer_text_new (), "text", 0, NULL)); - - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); - - gtk_scrolled_window_add_with_viewport ( - GTK_SCROLLED_WINDOW (scrolled_window), tree_view); - gtk_container_set_focus_vadjustment ( - GTK_CONTAINER (tree_view), - gtk_scrolled_window_get_vadjustment ( - GTK_SCROLLED_WINDOW (scrolled_window))); - gtk_container_set_focus_hadjustment ( - GTK_CONTAINER (tree_view), - gtk_scrolled_window_get_hadjustment ( - GTK_SCROLLED_WINDOW (scrolled_window))); - gtk_widget_show (tree_view); - ecde->time_tree_view = tree_view; - g_signal_connect ( - gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), "changed", - G_CALLBACK (e_cell_date_edit_on_time_selected), ecde); - - bbox = gtk_hbutton_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (bbox), 4); - gtk_box_set_spacing (GTK_BOX (bbox), 2); - gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - now_button = gtk_button_new_with_label (_("Now")); - gtk_container_add (GTK_CONTAINER (bbox), now_button); - gtk_widget_show (now_button); - g_signal_connect ( - now_button, "clicked", - G_CALLBACK (e_cell_date_edit_on_now_clicked), ecde); - ecde->now_button = now_button; - - today_button = gtk_button_new_with_label (_("Today")); - gtk_container_add (GTK_CONTAINER (bbox), today_button); - gtk_widget_show (today_button); - g_signal_connect ( - today_button, "clicked", - G_CALLBACK (e_cell_date_edit_on_today_clicked), ecde); - ecde->today_button = today_button; - - /* Translators: "None" as a label of a button to unset date in a - * date table cell. */ - none_button = gtk_button_new_with_label (C_("table-date", "None")); - gtk_container_add (GTK_CONTAINER (bbox), none_button); - gtk_widget_show (none_button); - g_signal_connect ( - none_button, "clicked", - G_CALLBACK (e_cell_date_edit_on_none_clicked), ecde); - ecde->none_button = none_button; - - ok_button = gtk_button_new_with_label (_("OK")); - gtk_container_add (GTK_CONTAINER (bbox), ok_button); - gtk_widget_show (ok_button); - g_signal_connect ( - ok_button, "clicked", - G_CALLBACK (e_cell_date_edit_on_ok_clicked), ecde); - - g_signal_connect ( - ecde->popup_window, "key_press_event", - G_CALLBACK (e_cell_date_edit_key_press), ecde); - g_signal_connect ( - ecde->popup_window, "button_press_event", - G_CALLBACK (e_cell_date_edit_button_press), ecde); -} - -/** - * e_cell_date_edit_new: - * - * Creates a new ECellDateEdit renderer. - * - * Returns: an ECellDateEdit object. - */ -ECell * -e_cell_date_edit_new (void) -{ - return g_object_new (e_cell_date_edit_get_type (), NULL); -} - -static void -e_cell_date_edit_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECellDateEdit *ecde; - - ecde = E_CELL_DATE_EDIT (object); - - switch (property_id) { - case PROP_SHOW_TIME: - g_value_set_boolean (value, gtk_widget_get_visible (ecde->time_entry)); - return; - case PROP_SHOW_NOW_BUTTON: - g_value_set_boolean (value, gtk_widget_get_visible (ecde->now_button)); - return; - case PROP_SHOW_TODAY_BUTTON: - g_value_set_boolean (value, gtk_widget_get_visible (ecde->today_button)); - return; - case PROP_ALLOW_NO_DATE_SET: - g_value_set_boolean (value, gtk_widget_get_visible (ecde->none_button)); - return; - case PROP_USE_24_HOUR_FORMAT: - g_value_set_boolean (value, ecde->use_24_hour_format); - return; - case PROP_LOWER_HOUR: - g_value_set_int (value, ecde->lower_hour); - return; - case PROP_UPPER_HOUR: - g_value_set_int (value, ecde->upper_hour); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_cell_date_edit_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ECellDateEdit *ecde; - gint ivalue; - gboolean bvalue; - - ecde = E_CELL_DATE_EDIT (object); - - switch (property_id) { - case PROP_SHOW_TIME: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->time_entry); - gtk_widget_show (ecde->time_tree_view); - } else { - gtk_widget_hide (ecde->time_entry); - gtk_widget_hide (ecde->time_tree_view); - } - return; - case PROP_SHOW_NOW_BUTTON: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->now_button); - } else { - gtk_widget_hide (ecde->now_button); - } - return; - case PROP_SHOW_TODAY_BUTTON: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->today_button); - } else { - gtk_widget_hide (ecde->today_button); - } - return; - case PROP_ALLOW_NO_DATE_SET: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->none_button); - } else { - /* FIXME: What if we have no date set now. */ - gtk_widget_hide (ecde->none_button); - } - return; - case PROP_USE_24_HOUR_FORMAT: - bvalue = g_value_get_boolean (value); - if (ecde->use_24_hour_format != bvalue) { - ecde->use_24_hour_format = bvalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - case PROP_LOWER_HOUR: - ivalue = g_value_get_int (value); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->lower_hour != ivalue) { - ecde->lower_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - case PROP_UPPER_HOUR: - ivalue = g_value_get_int (value); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->upper_hour != ivalue) { - ecde->upper_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_cell_date_edit_dispose (GObject *object) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (object); - - e_cell_date_edit_set_get_time_callback (ecde, NULL, NULL, NULL); - - if (ecde->popup_window != NULL) { - gtk_widget_destroy (ecde->popup_window); - ecde->popup_window = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_cell_date_edit_parent_class)->dispose (object); -} - -static gint -e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event, - gint row, - gint view_col) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (ecp); - GdkWindow *window; - - e_cell_date_edit_show_popup (ecde, row, view_col); - e_cell_date_edit_set_popup_values (ecde); - - gtk_grab_add (ecde->popup_window); - - /* Set the focus to the first widget. */ - gtk_widget_grab_focus (ecde->time_entry); - window = gtk_widget_get_window (ecde->popup_window); - gdk_window_focus (window, GDK_CURRENT_TIME); - - return TRUE; -} - -static void -e_cell_date_edit_set_popup_values (ECellDateEdit *ecde) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ECellView *ecv = (ECellView *) ecp->popup_cell_view; - ETableItem *eti; - ETableCol *ecol; - gchar *cell_text; - ETimeParseStatus status; - struct tm date_tm; - GDate date; - ECalendarItem *calitem; - gchar buffer[64]; - gboolean is_date = TRUE; - - eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - - cell_text = e_cell_text_get_text ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* Try to parse just a date first. If the value is only a date, we - * use a DATE value. */ - status = e_time_parse_date (cell_text, &date_tm); - if (status == E_TIME_PARSE_INVALID) { - is_date = FALSE; - status = e_time_parse_date_and_time (cell_text, &date_tm); - } - - /* If there is no date and time set, or the date is invalid, we clear - * the selections, else we select the appropriate date & time. */ - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - if (status == E_TIME_PARSE_NONE || status == E_TIME_PARSE_INVALID) { - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), ""); - e_calendar_item_set_selection (calitem, NULL, NULL); - gtk_tree_selection_unselect_all ( - gtk_tree_view_get_selection ( - GTK_TREE_VIEW (ecde->time_tree_view))); - } else { - if (is_date) { - buffer[0] = '\0'; - } else { - e_time_format_time ( - &date_tm, ecde->use_24_hour_format, - FALSE, buffer, sizeof (buffer)); - } - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), buffer); - - g_date_clear (&date, 1); - g_date_set_dmy ( - &date, - date_tm.tm_mday, - date_tm.tm_mon + 1, - date_tm.tm_year + 1900); - e_calendar_item_set_selection (calitem, &date, &date); - - if (is_date) { - gtk_tree_selection_unselect_all ( - gtk_tree_view_get_selection ( - GTK_TREE_VIEW (ecde->time_tree_view))); - } else { - e_cell_date_edit_select_matching_time (ecde, buffer); - } - } - - e_cell_text_free_text (ecell_text, cell_text); -} - -static void -e_cell_date_edit_select_matching_time (ECellDateEdit *ecde, - gchar *time) -{ - gboolean found = FALSE; - gboolean valid; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeModel *model; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (ecde->time_tree_view)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ecde->time_tree_view)); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid && !found; - valid = gtk_tree_model_iter_next (model, &iter)) { - gchar *str = NULL; - - gtk_tree_model_get (model, &iter, 0, &str, -1); - - if (g_str_equal (str, time)) { - GtkTreePath *path = gtk_tree_model_get_path (model, &iter); - - gtk_tree_view_set_cursor ( - GTK_TREE_VIEW (ecde->time_tree_view), - path, NULL, FALSE); - gtk_tree_view_scroll_to_cell ( - GTK_TREE_VIEW (ecde->time_tree_view), - path, NULL, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - found = TRUE; - } - - g_free (str); - } - - if (!found) { - gtk_tree_selection_unselect_all (selection); - gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (ecde->time_tree_view), 0, 0); - } -} - -static void -e_cell_date_edit_show_popup (ECellDateEdit *ecde, - gint row, - gint view_col) -{ - GdkWindow *window; - gint x, y, width, height; - - if (ecde->need_time_list_rebuild) - e_cell_date_edit_rebuild_time_list (ecde); - - /* This code is practically copied from GtkCombo. */ - - e_cell_date_edit_get_popup_pos (ecde, row, view_col, &x, &y, &height, &width); - - window = gtk_widget_get_window (ecde->popup_window); - gtk_window_move (GTK_WINDOW (ecde->popup_window), x, y); - gtk_widget_set_size_request (ecde->popup_window, width, height); - gtk_widget_realize (ecde->popup_window); - gdk_window_resize (window, width, height); - gtk_widget_show (ecde->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecde), TRUE); -} - -/* Calculates the size and position of the popup window (like GtkCombo). */ -static void -e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - gint row, - gint view_col, - gint *x, - gint *y, - gint *height, - gint *width) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ETableItem *eti; - GtkWidget *canvas; - GtkRequisition popup_requisition; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - GdkWindow *window; - gint avail_height, screen_width, column_width, row_height; - gdouble x1, y1, wx, wy; - gint value; - - eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - - window = gtk_widget_get_window (canvas); - gdk_window_get_origin (window, x, y); - - x1 = e_table_header_col_diff (eti->header, 0, view_col + 1); - y1 = e_table_item_row_diff (eti, 0, row + 1); - column_width = e_table_header_col_diff ( - eti->header, view_col, view_col + 1); - row_height = e_table_item_row_diff (eti, row, row + 1); - gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1); - - gnome_canvas_world_to_window ( - GNOME_CANVAS (canvas), x1, y1, &wx, &wy); - - x1 = wx; - y1 = wy; - - *x += x1; - /* The ETable positions don't include the grid lines, I think, so we - * add 1. */ - scrollable = GTK_SCROLLABLE (&GNOME_CANVAS (canvas)->layout); - adjustment = gtk_scrollable_get_vadjustment (scrollable); - value = (gint) gtk_adjustment_get_value (adjustment); - *y += y1 + 1 - value + ((GnomeCanvas *)canvas)->zoom_yofs; - - avail_height = gdk_screen_height () - *y; - - /* We'll use the entire screen width if needed, but we save space for - * the vertical scrollbar in case we need to show that. */ - screen_width = gdk_screen_width (); - - gtk_widget_get_preferred_size (ecde->popup_window, &popup_requisition, NULL); - - /* Calculate the desired width. */ - *width = popup_requisition.width; - - /* Use at least the same width as the column. */ - if (*width < column_width) - *width = column_width; - - /* Check if it fits in the available height. */ - if (popup_requisition.height > avail_height) { - /* It doesn't fit, so we see if we have the minimum space - * needed. */ - if (*y - row_height > avail_height) { - /* We don't, so we show the popup above the cell - * instead of below it. */ - *y -= (popup_requisition.height + row_height); - if (*y < 0) - *y = 0; - } - } - - /* We try to line it up with the right edge of the column, but we don't - * want it to go off the edges of the screen. */ - if (*x > screen_width) - *x = screen_width; - *x -= *width; - if (*x < 0) - *x = 0; - - *height = popup_requisition.height; -} - -/* This handles key press events in the popup window. If the Escape key is - * pressed we hide the popup, and do not change the cell contents. */ -static gint -e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde) -{ - /* If the Escape key is pressed we hide the popup. */ - if (event->keyval != GDK_KEY_Escape) - return FALSE; - - e_cell_date_edit_hide_popup (ecde); - - return TRUE; -} - -/* This handles button press events in the popup window. If the button is - * pressed outside the popup, we hide it and do not change the cell contents. -*/ -static gint -e_cell_date_edit_button_press (GtkWidget *popup_window, - GdkEvent *button_event, - ECellDateEdit *ecde) -{ - GtkWidget *event_widget; - - event_widget = gtk_get_event_widget (button_event); - - if (gtk_widget_get_toplevel (event_widget) != popup_window) - e_cell_date_edit_hide_popup (ecde); - - return TRUE; -} - -/* Clears the time list and rebuilds it using the lower_hour, upper_hour - * and use_24_hour_format settings. */ -static void -e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde) -{ - GtkListStore *store; - gchar buffer[40]; - struct tm tmp_tm; - gint hour, min; - - store = GTK_LIST_STORE (gtk_tree_view_get_model ( - GTK_TREE_VIEW (ecde->time_tree_view))); - gtk_list_store_clear (store); - - /* Fill the struct tm with some sane values. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = 0; - - for (hour = ecde->lower_hour; hour <= ecde->upper_hour; hour++) { - /* We don't want to display midnight at the end, since that is - * really in the next day. */ - if (hour == 24) - break; - - /* We want to finish on upper_hour, with min == 0. */ - for (min = 0; - min == 0 || (min < 60 && hour != ecde->upper_hour); - min += 30) { - GtkTreeIter iter; - - tmp_tm.tm_hour = hour; - tmp_tm.tm_min = min; - e_time_format_time (&tmp_tm, ecde->use_24_hour_format, - FALSE, buffer, sizeof (buffer)); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, buffer, -1); - } - } - - ecde->need_time_list_rebuild = FALSE; -} - -static void -e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - ECalendarItem *calitem; - GDate start_date, end_date; - gboolean day_selected; - struct tm date_tm; - gchar buffer[64]; - const gchar *text; - ETimeParseStatus status; - gboolean is_date = FALSE; - - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - day_selected = e_calendar_item_get_selection ( - calitem, &start_date, &end_date); - - text = gtk_entry_get_text (GTK_ENTRY (ecde->time_entry)); - status = e_time_parse_time (text, &date_tm); - if (status == E_TIME_PARSE_INVALID) { - e_cell_date_edit_show_time_invalid_warning (ecde); - return; - } else if (status == E_TIME_PARSE_NONE) { - is_date = TRUE; - } - - if (day_selected) { - date_tm.tm_year = g_date_get_year (&start_date) - 1900; - date_tm.tm_mon = g_date_get_month (&start_date) - 1; - date_tm.tm_mday = g_date_get_day (&start_date); - /* We need to call this to set the weekday. */ - mktime (&date_tm); - e_time_format_date_and_time (&date_tm, - ecde->use_24_hour_format, - !is_date, FALSE, - buffer, sizeof (buffer)); - } else { - buffer[0] = '\0'; - } - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - -static void -e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde) -{ - GtkWidget *dialog; - struct tm date_tm; - gchar buffer[64]; - - /* Create a useful error message showing the correct format. */ - date_tm.tm_year = 100; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = 1; - date_tm.tm_min = 30; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - e_time_format_time (&date_tm, ecde->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - /* FIXME: Fix transient settings - I'm not sure it works with popup - * windows. Maybe we need to use a normal window without decorations.*/ - dialog = gtk_message_dialog_new ( - GTK_WINDOW (ecde->popup_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("The time must be in the format: %s"), - buffer); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - -static void -e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm tmp_tm; - time_t t; - gchar buffer[64]; - - if (ecde->time_callback) { - tmp_tm = ecde->time_callback ( - ecde, ecde->time_callback_data); - } else { - t = time (NULL); - tmp_tm = *localtime (&t); - } - - e_time_format_date_and_time ( - &tmp_tm, ecde->use_24_hour_format, - TRUE, FALSE, buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - -static void -e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - e_cell_date_edit_update_cell (ecde, ""); - e_cell_date_edit_hide_popup (ecde); -} - -static void -e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm tmp_tm; - time_t t; - gchar buffer[64]; - - if (ecde->time_callback) { - tmp_tm = ecde->time_callback ( - ecde, ecde->time_callback_data); - } else { - t = time (NULL); - tmp_tm = *localtime (&t); - } - - tmp_tm.tm_hour = 0; - tmp_tm.tm_min = 0; - tmp_tm.tm_sec = 0; - - e_time_format_date_and_time ( - &tmp_tm, ecde->use_24_hour_format, - FALSE, FALSE, buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - -static void -e_cell_date_edit_update_cell (ECellDateEdit *ecde, - const gchar *text) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ECellView *ecv = (ECellView *) ecp->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - ETableCol *ecol; - gchar *old_text; - - /* Compare the new text with the existing cell contents. */ - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - - old_text = e_cell_text_get_text ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* If they are different, update the cell contents. */ - if (strcmp (old_text, text)) { - e_cell_text_set_value ( - ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row, text); - e_cell_leave_edit ( - ecv, ecp->popup_view_col, - ecol->col_idx, ecp->popup_row, NULL); - } - - e_cell_text_free_text (ecell_text, old_text); -} - -static void -e_cell_date_edit_on_time_selected (GtkTreeSelection *selection, - ECellDateEdit *ecde) -{ - gchar *list_item_text = NULL; - GtkTreeIter iter; - GtkTreeModel *model; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return; - - gtk_tree_model_get (model, &iter, 0, &list_item_text, -1); - - g_return_if_fail (list_item_text != NULL); - - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), list_item_text); - - g_free (list_item_text); -} - -static void -e_cell_date_edit_hide_popup (ECellDateEdit *ecde) -{ - gtk_grab_remove (ecde->popup_window); - gtk_widget_hide (ecde->popup_window); - e_cell_popup_set_shown (E_CELL_POPUP (ecde), FALSE); -} - -/* These freeze and thaw the rebuilding of the time list. They are useful when - * setting several properties which result in rebuilds of the list, e.g. the - * lower_hour, upper_hour and use_24_hour_format properties. */ -void -e_cell_date_edit_freeze (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - ecde->freeze_count++; -} - -void -e_cell_date_edit_thaw (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - if (ecde->freeze_count > 0) { - ecde->freeze_count--; - - if (ecde->freeze_count == 0) - e_cell_date_edit_rebuild_time_list (ecde); - } -} - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void -e_cell_date_edit_set_get_time_callback (ECellDateEdit *ecde, - ECellDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - if (ecde->time_callback_data && ecde->time_callback_destroy) - (*ecde->time_callback_destroy) (ecde->time_callback_data); - - ecde->time_callback = cb; - ecde->time_callback_data = data; - ecde->time_callback_destroy = destroy; -} diff --git a/widgets/table/e-cell-date-edit.h b/widgets/table/e-cell-date-edit.h deleted file mode 100644 index 186302d79a..0000000000 --- a/widgets/table/e-cell-date-edit.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - -#ifndef _E_CELL_DATE_EDIT_H_ -#define _E_CELL_DATE_EDIT_H_ - -#include <time.h> -#include <table/e-cell-popup.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_DATE_EDIT \ - (e_cell_date_edit_get_type ()) -#define E_CELL_DATE_EDIT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_DATE_EDIT, ECellDateEdit)) -#define E_CELL_DATE_EDIT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_DATE_EDIT, ECellDateEditClass)) -#define E_IS_CELL_DATE_EDIT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_DATE_EDIT)) -#define E_IS_CELL_DATE_EDIT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_DATE_EDIT)) -#define E_CELL_DATE_EDIT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_DATE_EDIT, ECellDateEditClass)) - -G_BEGIN_DECLS - -typedef struct _ECellDateEdit ECellDateEdit; -typedef struct _ECellDateEditClass ECellDateEditClass; - -/* The type of the callback function optionally used to get the current time. - */ -typedef struct tm (*ECellDateEditGetTimeCallback) (ECellDateEdit *ecde, - gpointer data); - -struct _ECellDateEdit { - ECellPopup parent; - - GtkWidget *popup_window; - GtkWidget *calendar; - GtkWidget *time_entry; - GtkWidget *time_tree_view; - - GtkWidget *now_button; - GtkWidget *today_button; - GtkWidget *none_button; - - /* This is the range of hours we show in the time list. */ - gint lower_hour; - gint upper_hour; - - /* TRUE if we use 24-hour format for the time list and entry. */ - gboolean use_24_hour_format; - - /* This is TRUE if we need to rebuild the list of times. */ - gboolean need_time_list_rebuild; - - /* The freeze count for rebuilding the time list. We only rebuild when - * this is 0. */ - gint freeze_count; - - ECellDateEditGetTimeCallback time_callback; - gpointer time_callback_data; - GDestroyNotify time_callback_destroy; -}; - -struct _ECellDateEditClass { - ECellPopupClass parent_class; -}; - -GType e_cell_date_edit_get_type (void) G_GNUC_CONST; -ECell * e_cell_date_edit_new (void); - -/* These freeze and thaw the rebuilding of the time list. They are useful when - * setting several properties which result in rebuilds of the list, e.g. the - * lower_hour, upper_hour and use_24_hour_format properties. */ -void e_cell_date_edit_freeze (ECellDateEdit *ecde); -void e_cell_date_edit_thaw (ECellDateEdit *ecde); - -/* Sets a callback to use to get the current time. This is useful if the - * application needs to use its own timezone data rather than rely on the - * Unix timezone. */ -void e_cell_date_edit_set_get_time_callback - (ECellDateEdit *ecde, - ECellDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy); - -G_END_DECLS - -#endif /* _E_CELL_DATE_EDIT_H_ */ diff --git a/widgets/table/e-cell-date.c b/widgets/table/e-cell-date.c deleted file mode 100644 index 79534aff45..0000000000 --- a/widgets/table/e-cell-date.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/time.h> -#include <time.h> -#include <unistd.h> -#include <string.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-unicode.h" -#include "e-util/e-datetime-format.h" - -#include "e-cell-date.h" - -G_DEFINE_TYPE (ECellDate, e_cell_date, E_TYPE_CELL_TEXT) - -static gchar * -ecd_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - time_t date = GPOINTER_TO_INT (e_table_model_value_at (model, col, row)); - const gchar *fmt_component, *fmt_part = NULL; - - if (date == 0) { - return g_strdup (_("?")); - } - - fmt_component = g_object_get_data ((GObject *) cell, "fmt-component"); - if (!fmt_component || !*fmt_component) - fmt_component = "Default"; - else - fmt_part = "table"; - - return e_datetime_format_format ( - fmt_component, fmt_part, DTFormatKindDateTime, date); -} - -static void -ecd_free_text (ECellText *cell, - gchar *text) -{ - g_free (text); -} - -static void -e_cell_date_class_init (ECellDateClass *class) -{ - ECellTextClass *ectc = E_CELL_TEXT_CLASS (class); - - ectc->get_text = ecd_get_text; - ectc->free_text = ecd_free_text; -} - -static void -e_cell_date_init (ECellDate *ecd) -{ -} - -/** - * e_cell_date_new: - * @fontname: font to be used to render on the screen - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render dates that - * that come from the model. The value returned from the model is - * interpreted as being a time_t. - * - * The ECellDate object support a large set of properties that can be - * configured through the Gtk argument system and allows the user to have - * a finer control of the way the string is displayed. The arguments supported - * allow the control of strikeout, bold, color and a date filter. - * - * The arguments "strikeout_column", "underline_column", "bold_column" - * and "color_column" set and return an integer that points to a - * column in the model that controls these settings. So controlling - * the way things are rendered is achieved by having special columns - * in the model that will be used to flag whether the date should be - * rendered with strikeout, underline, or bolded. In the case of the - * "color_column" argument, the column in the model is expected to - * have a string that can be parsed by gdk_color_parse(). - * - * Returns: an ECell object that can be used to render dates. - */ -ECell * -e_cell_date_new (const gchar *fontname, - GtkJustification justify) -{ - ECellDate *ecd = g_object_new (E_TYPE_CELL_DATE, NULL); - - e_cell_text_construct (E_CELL_TEXT (ecd), fontname, justify); - - return (ECell *) ecd; -} - -void -e_cell_date_set_format_component (ECellDate *ecd, - const gchar *fmt_component) -{ - g_return_if_fail (ecd != NULL); - - g_object_set_data_full ( - G_OBJECT (ecd), "fmt-component", - g_strdup (fmt_component), g_free); -} diff --git a/widgets/table/e-cell-date.h b/widgets/table/e-cell-date.h deleted file mode 100644 index c498095241..0000000000 --- a/widgets/table/e-cell-date.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CELL_DATE_H -#define E_CELL_DATE_H - -#include <table/e-cell-text.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_DATE \ - (e_cell_date_get_type ()) -#define E_CELL_DATE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_DATE, ECellDate)) -#define E_CELL_DATE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_DATE, ECellDateClass)) -#define E_IS_CELL_DATE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_DATE)) -#define E_IS_CELL_DATE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_DATE)) -#define E_CELL_DATE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_DATE, ECellDateClass)) - -G_BEGIN_DECLS - -typedef struct _ECellDate ECellDate; -typedef struct _ECellDateClass ECellDateClass; - -struct _ECellDate { - ECellText parent; -}; - -struct _ECellDateClass { - ECellTextClass parent_class; -}; - -GType e_cell_date_get_type (void) G_GNUC_CONST; -ECell * e_cell_date_new (const gchar *fontname, - GtkJustification justify); -void e_cell_date_set_format_component - (ECellDate *ecd, - const gchar *fmt_component); - -G_END_DECLS - -#endif /* E_CELL_DATE_H */ diff --git a/widgets/table/e-cell-hbox.c b/widgets/table/e-cell-hbox.c deleted file mode 100644 index 74301a773c..0000000000 --- a/widgets/table/e-cell-hbox.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Srinivasa Ragavan <sragavan@novell.com> - * - * A majority of code taken from: - * - * the ECellText renderer. - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <math.h> -#include <stdio.h> - -#include <gtk/gtk.h> - -/* #include "a11y/gal-a11y-e-cell-registry.h" */ -/* #include "a11y/gal-a11y-e-cell-vbox.h" */ -#include "e-util/e-util.h" - -#include "e-cell-hbox.h" -#include "e-table-item.h" - -G_DEFINE_TYPE (ECellHbox, e_cell_hbox, E_TYPE_CELL) - -#define INDENT_AMOUNT 16 -#define MAX_CELL_SIZE 25 - -/* - * ECell::new_view method - */ -static ECellView * -ecv_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellHbox *ecv = E_CELL_HBOX (ecell); - ECellHboxView *hbox_view = g_new0 (ECellHboxView, 1); - gint i; - - hbox_view->cell_view.ecell = ecell; - hbox_view->cell_view.e_table_model = table_model; - hbox_view->cell_view.e_table_item_view = e_table_item_view; - hbox_view->cell_view.kill_view_cb = NULL; - hbox_view->cell_view.kill_view_cb_data = NULL; - - /* create our subcell view */ - hbox_view->subcell_view_count = ecv->subcell_count; - hbox_view->subcell_views = g_new (ECellView *, hbox_view->subcell_view_count); - hbox_view->model_cols = g_new (int, hbox_view->subcell_view_count); - hbox_view->def_size_cols = g_new (int, hbox_view->subcell_view_count); - - for (i = 0; i < hbox_view->subcell_view_count; i++) { - hbox_view->subcell_views[i] = e_cell_new_view (ecv->subcells[i], table_model, e_table_item_view /* XXX */); - hbox_view->model_cols[i] = ecv->model_cols[i]; - hbox_view->def_size_cols[i] = ecv->def_size_cols[i]; - } - - return (ECellView *) hbox_view; -} - -/* - * ECell::kill_view method - */ -static void -ecv_kill_view (ECellView *ecv) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecv; - gint i; - - if (hbox_view->cell_view.kill_view_cb) - (hbox_view->cell_view.kill_view_cb)(ecv, hbox_view->cell_view.kill_view_cb_data); - - if (hbox_view->cell_view.kill_view_cb_data) - g_list_free (hbox_view->cell_view.kill_view_cb_data); - - /* kill our subcell view */ - for (i = 0; i < hbox_view->subcell_view_count; i++) - e_cell_kill_view (hbox_view->subcell_views[i]); - - g_free (hbox_view->model_cols); - g_free (hbox_view->def_size_cols); - g_free (hbox_view->subcell_views); - g_free (hbox_view); -} - -/* - * ECell::realize method - */ -static void -ecv_realize (ECellView *ecell_view) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecell_view; - gint i; - - /* realize our subcell view */ - for (i = 0; i < hbox_view->subcell_view_count; i++) - e_cell_realize (hbox_view->subcell_views[i]); - - if (E_CELL_CLASS (e_cell_hbox_parent_class)->realize) - (* E_CELL_CLASS (e_cell_hbox_parent_class)->realize) (ecell_view); -} - -/* - * ECell::unrealize method - */ -static void -ecv_unrealize (ECellView *ecv) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecv; - gint i; - - /* unrealize our subcell view. */ - for (i = 0; i < hbox_view->subcell_view_count; i++) - e_cell_unrealize (hbox_view->subcell_views[i]); - - if (E_CELL_CLASS (e_cell_hbox_parent_class)->unrealize) - (* E_CELL_CLASS (e_cell_hbox_parent_class)->unrealize) (ecv); -} - -/* - * ECell::draw method - */ -static void -ecv_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecell_view; - - gint subcell_offset = 0; - gint i; - gint allotted_width = x2 - x1; - - for (i = 0; i < hbox_view->subcell_view_count; i++) { - /* Now cause our subcells to draw their contents, - * shifted by subcell_offset pixels */ - gint width = allotted_width * hbox_view->def_size_cols[i] / 100; - /* e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row); - if (width < hbox_view->def_size_cols[i]) - width = hbox_view->def_size_cols[i]; - printf ("width of %d %d of %d\n", width,hbox_view->def_size_cols[i], allotted_width); */ - - e_cell_draw ( - hbox_view->subcell_views[i], cr, - hbox_view->model_cols[i], view_col, row, flags, - x1 + subcell_offset , y1, - x1 + subcell_offset + width, y2); - - subcell_offset += width; /* e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row); */ - } -} - -/* - * ECell::event method - */ -static gint -ecv_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecell_view; - gint y = 0; - gint i; - gint subcell_offset = 0; - - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - y = event->button.y; - break; - case GDK_MOTION_NOTIFY: - y = event->motion.y; - break; - default: - /* nada */ - break; - } - - for (i = 0; i < hbox_view->subcell_view_count; i++) { - gint width = e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row); - if (width < hbox_view->def_size_cols[i]) - width = hbox_view->def_size_cols[i]; - if (y < subcell_offset + width) - return e_cell_event (hbox_view->subcell_views[i], event, hbox_view->model_cols[i], view_col, row, flags, actions); - subcell_offset += width; - } - return 0; -} - -/* - * ECell::height method - */ -static gint -ecv_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecell_view; - gint height = 0, max_height = 0; - gint i; - - for (i = 0; i < hbox_view->subcell_view_count; i++) { - height = e_cell_height (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row); - max_height = MAX (max_height, height); - } - return max_height; -} - -/* - * ECell::max_width method - */ -static gint -ecv_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - ECellHboxView *hbox_view = (ECellHboxView *) ecell_view; - gint width = 0; - gint i; - - for (i = 0; i < hbox_view->subcell_view_count; i++) { - gint cell_width = e_cell_max_width (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col); - - if (cell_width < hbox_view->def_size_cols[i]) - cell_width = hbox_view->def_size_cols[i]; - width += cell_width; - } - - return width; -} - -/* - * GObject::dispose method - */ -static void -ecv_dispose (GObject *object) -{ - ECellHbox *ecv = E_CELL_HBOX (object); - gint i; - - /* destroy our subcell */ - for (i = 0; i < ecv->subcell_count; i++) - if (ecv->subcells[i]) - g_object_unref (ecv->subcells[i]); - g_free (ecv->subcells); - ecv->subcells = NULL; - ecv->subcell_count = 0; - - g_free (ecv->model_cols); - ecv->model_cols = NULL; - - g_free (ecv->def_size_cols); - ecv->def_size_cols = NULL; - - G_OBJECT_CLASS (e_cell_hbox_parent_class)->dispose (object); -} - -static void -e_cell_hbox_class_init (ECellHboxClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ECellClass *ecc = E_CELL_CLASS (class); - - object_class->dispose = ecv_dispose; - - ecc->new_view = ecv_new_view; - ecc->kill_view = ecv_kill_view; - ecc->realize = ecv_realize; - ecc->unrealize = ecv_unrealize; - ecc->draw = ecv_draw; - ecc->event = ecv_event; - ecc->height = ecv_height; - - ecc->max_width = ecv_max_width; - -/* gal_a11y_e_cell_registry_add_cell_type (NULL, E_TYPE_CELL_HBOX, gal_a11y_e_cell_hbox_new); */ -} - -static void -e_cell_hbox_init (ECellHbox *ecv) -{ - ecv->subcells = NULL; - ecv->subcell_count = 0; -} - -/** - * e_cell_hbox_new: - * - * Creates a new ECell renderer that can be used to render multiple - * child cells. - * - * Return value: an ECell object that can be used to render multiple - * child cells. - **/ -ECell * -e_cell_hbox_new (void) -{ - return g_object_new (E_TYPE_CELL_HBOX, NULL); -} - -void -e_cell_hbox_append (ECellHbox *hbox, - ECell *subcell, - gint model_col, - gint size) -{ - hbox->subcell_count++; - - hbox->subcells = g_renew (ECell *, hbox->subcells, hbox->subcell_count); - hbox->model_cols = g_renew (int, hbox->model_cols, hbox->subcell_count); - hbox->def_size_cols = g_renew (int, hbox->def_size_cols, hbox->subcell_count); - - hbox->subcells[hbox->subcell_count - 1] = subcell; - hbox->model_cols[hbox->subcell_count - 1] = model_col; - hbox->def_size_cols[hbox->subcell_count - 1] = size; - - if (subcell) - g_object_ref_sink (subcell); -} diff --git a/widgets/table/e-cell-hbox.h b/widgets/table/e-cell-hbox.h deleted file mode 100644 index 41cc01e6a1..0000000000 --- a/widgets/table/e-cell-hbox.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Srinivasa Ragavan <sragavan@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CELL_HBOX_H_ -#define _E_CELL_HBOX_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_HBOX \ - (e_cell_hbox_get_type ()) -#define E_CELL_HBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_HBOX, ECellHbox)) -#define E_CELL_HBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_HBOX, ECellHboxClass)) -#define E_IS_CELL_HBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_HBOX)) -#define E_IS_CELL_HBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_HBOX)) -#define E_CELL_HBOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_HBOX, ECellHboxClass)) - -G_BEGIN_DECLS - -typedef struct _ECellHbox ECellHbox; -typedef struct _ECellHboxView ECellHboxView; -typedef struct _ECellHboxClass ECellHboxClass; - -struct _ECellHbox { - ECell parent; - - gint subcell_count; - ECell **subcells; - gint *model_cols; - gint *def_size_cols; -}; - -struct _ECellHboxView { - ECellView cell_view; - - gint subcell_view_count; - ECellView **subcell_views; - gint *model_cols; - gint *def_size_cols; -}; - -struct _ECellHboxClass { - ECellClass parent_class; -}; - -GType e_cell_hbox_get_type (void) G_GNUC_CONST; -ECell * e_cell_hbox_new (void); -void e_cell_hbox_append (ECellHbox *vbox, - ECell *subcell, - gint model_col, - gint size); - -G_END_DECLS - -#endif /* _E_CELL_HBOX_H_ */ diff --git a/widgets/table/e-cell-number.c b/widgets/table/e-cell-number.c deleted file mode 100644 index 6e2f685a86..0000000000 --- a/widgets/table/e-cell-number.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/time.h> -#include <unistd.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-cell-number.h" - -G_DEFINE_TYPE (ECellNumber, e_cell_number, E_TYPE_CELL_TEXT) - -static gchar * -ecn_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - gpointer value; - - value = e_table_model_value_at (model, col, row); - - return e_format_number (GPOINTER_TO_INT (value)); -} - -static void -ecn_free_text (ECellText *cell, - gchar *text) -{ - g_free (text); -} - -static void -e_cell_number_class_init (ECellNumberClass *class) -{ - ECellTextClass *ectc = E_CELL_TEXT_CLASS (class); - - ectc->get_text = ecn_get_text; - ectc->free_text = ecn_free_text; -} - -static void -e_cell_number_init (ECellNumber *cell_number) -{ -} - -/** - * e_cell_number_new: - * @fontname: font to be used to render on the screen - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render numbers that - * that come from the model. The value returned from the model is - * interpreted as being an int. - * - * See ECellText for other features. - * - * Returns: an ECell object that can be used to render numbers. - */ -ECell * -e_cell_number_new (const gchar *fontname, - GtkJustification justify) -{ - ECellNumber *ecn = g_object_new (E_TYPE_CELL_NUMBER, NULL); - - e_cell_text_construct (E_CELL_TEXT (ecn), fontname, justify); - - return (ECell *) ecn; -} - diff --git a/widgets/table/e-cell-number.h b/widgets/table/e-cell-number.h deleted file mode 100644 index 539f27679e..0000000000 --- a/widgets/table/e-cell-number.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CELL_NUMBER_H -#define E_CELL_NUMBER_H - -#include <table/e-cell-text.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_NUMBER \ - (e_cell_number_get_type ()) -#define E_CELL_NUMBER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_NUMBER, ECellNumber)) -#define E_CELL_NUMBER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_NUMBER, ECellNumberClass)) -#define E_IS_CELL_NUMBER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_NUMBER)) -#define E_IS_CELL_NUMBER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_NUMBER)) -#define E_CELL_NUMBER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_NUMBER, ECellNumberClass)) - -G_BEGIN_DECLS - -typedef struct _ECellNumber ECellNumber; -typedef struct _ECellNumberClass ECellNumberClass; - -struct _ECellNumber { - ECellText parent; -}; - -struct _ECellNumberClass { - ECellTextClass parent_class; -}; - -GType e_cell_number_get_type (void) G_GNUC_CONST; -ECell * e_cell_number_new (const gchar *fontname, - GtkJustification justify); - -G_END_DECLS - -#endif /* E_CELL_NUMBER_H */ diff --git a/widgets/table/e-cell-percent.c b/widgets/table/e-cell-percent.c deleted file mode 100644 index 81465d5a62..0000000000 --- a/widgets/table/e-cell-percent.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPercent - a subclass of ECellText used to show an integer percentage - * in an ETable. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> - -#include <sys/time.h> -#include <unistd.h> -#include <stdio.h> -#include <glib/gi18n.h> - -#include "e-cell-percent.h" - -G_DEFINE_TYPE (ECellPercent, e_cell_percent, E_TYPE_CELL_TEXT) - -static gchar * -ecp_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - gint percent; - static gchar buffer[8]; - - percent = GPOINTER_TO_INT (e_table_model_value_at (model, col, row)); - - /* A -ve value means the property is not set. */ - if (percent < 0) { - buffer[0] = '\0'; - } else { - g_snprintf (buffer, sizeof (buffer), "%i%%", percent); - } - - return buffer; -} - -static void -ecp_free_text (ECellText *cell, - gchar *text) -{ - /* Do Nothing. */ -} - -/* FIXME: We need to set the "transient_for" property for the dialog. */ -static void -show_percent_warning (void) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new ( - NULL, 0, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "%s", _("The percent value must be between 0 and 100, inclusive")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - -static void -ecp_set_value (ECellText *cell, - ETableModel *model, - gint col, - gint row, - const gchar *text) -{ - gint matched, percent; - gboolean empty = TRUE; - const gchar *p; - - if (text) { - p = text; - while (*p) { - if (!isspace ((guchar) *p)) { - empty = FALSE; - break; - } - p++; - } - } - - if (empty) { - percent = -1; - } else { - matched = sscanf (text, "%i", &percent); - - if (matched != 1 || percent < 0 || percent > 100) { - show_percent_warning (); - return; - } - } - - e_table_model_set_value_at ( - model, col, row, - GINT_TO_POINTER (percent)); -} - -static void -e_cell_percent_class_init (ECellPercentClass *ecpc) -{ - ECellTextClass *ectc = (ECellTextClass *) ecpc; - - ectc->get_text = ecp_get_text; - ectc->free_text = ecp_free_text; - ectc->set_value = ecp_set_value; -} - -static void -e_cell_percent_init (ECellPercent *ecp) -{ -} - -/** - * e_cell_percent_new: - * @fontname: font to be used to render on the screen - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render an integer - * percentage that comes from the model. The value returned from the model is - * interpreted as being an int. - * - * See ECellText for other features. - * - * Returns: an ECell object that can be used to render numbers. - */ -ECell * -e_cell_percent_new (const gchar *fontname, - GtkJustification justify) -{ - ECellPercent *ecn = g_object_new (E_TYPE_CELL_PERCENT, NULL); - - e_cell_text_construct (E_CELL_TEXT (ecn), fontname, justify); - - return (ECell *) ecn; -} diff --git a/widgets/table/e-cell-percent.h b/widgets/table/e-cell-percent.h deleted file mode 100644 index be4fdac9b7..0000000000 --- a/widgets/table/e-cell-percent.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPercent - a subclass of ECellText used to show an integer percentage - * in an ETable. - */ - -#ifndef E_CELL_PERCENT_H -#define E_CELL_PERCENT_H - -#include <table/e-cell-text.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_PERCENT \ - (e_cell_percent_get_type ()) -#define E_CELL_PERCENT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_PERCENT, ECellPercent)) -#define E_CELL_PERCENT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_PERCENT, ECellPercentClass)) -#define E_IS_CELL_NUMBER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_PERCENT)) -#define E_IS_CELL_NUMBER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_PERCENT)) -#define E_CELL_NUMBER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_PERCENT, ECellPercentClass)) - -G_BEGIN_DECLS - -typedef struct _ECellPercent ECellPercent; -typedef struct _ECellPercentClass ECellPercentClass; - -struct _ECellPercent { - ECellText parent; -}; - -struct _ECellPercentClass { - ECellTextClass parent_class; -}; - -GType e_cell_percent_get_type (void) G_GNUC_CONST; -ECell * e_cell_percent_new (const gchar *fontname, - GtkJustification justify); - -G_END_DECLS - -#endif /* E_CELL_PERCENT_H */ diff --git a/widgets/table/e-cell-pixbuf.c b/widgets/table/e-cell-pixbuf.c deleted file mode 100644 index 41b030ec5a..0000000000 --- a/widgets/table/e-cell-pixbuf.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Vladimir Vukicevic <vladimir@ximian.com> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> - -#include <libgnomecanvas/libgnomecanvas.h> - -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include "e-cell-pixbuf.h" - -G_DEFINE_TYPE (ECellPixbuf, e_cell_pixbuf, E_TYPE_CELL) - -typedef struct _ECellPixbufView ECellPixbufView; - -struct _ECellPixbufView { - ECellView cell_view; - GnomeCanvas *canvas; -}; - -/* Object argument IDs */ -enum { - PROP_0, - - PROP_SELECTED_COLUMN, - PROP_FOCUSED_COLUMN, - PROP_UNSELECTED_COLUMN -}; - -/* - * ECellPixbuf functions - */ - -ECell * -e_cell_pixbuf_new (void) -{ - return g_object_new (E_TYPE_CELL_PIXBUF, NULL); -} - -/* - * ECell methods - */ - -static ECellView * -pixbuf_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellPixbufView *pixbuf_view = g_new0 (ECellPixbufView, 1); - ETableItem *eti = E_TABLE_ITEM (e_table_item_view); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; - - pixbuf_view->cell_view.ecell = ecell; - pixbuf_view->cell_view.e_table_model = table_model; - pixbuf_view->cell_view.e_table_item_view = e_table_item_view; - pixbuf_view->cell_view.kill_view_cb = NULL; - pixbuf_view->cell_view.kill_view_cb_data = NULL; - - pixbuf_view->canvas = canvas; - - return (ECellView *) pixbuf_view; -} - -static void -pixbuf_kill_view (ECellView *ecell_view) -{ - ECellPixbufView *pixbuf_view = (ECellPixbufView *) ecell_view; - - if (pixbuf_view->cell_view.kill_view_cb) - pixbuf_view->cell_view.kill_view_cb ( - ecell_view, pixbuf_view->cell_view.kill_view_cb_data); - - if (pixbuf_view->cell_view.kill_view_cb_data) - g_list_free (pixbuf_view->cell_view.kill_view_cb_data); - - g_free (pixbuf_view); -} - -static void -pixbuf_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - GdkPixbuf *cell_pixbuf; - gint real_x, real_y; - gint pix_w, pix_h; - - cell_pixbuf = e_table_model_value_at (ecell_view->e_table_model, - 1, row); - - /* we can't make sure we really got a pixbuf since, well, it's a Gdk thing */ - - if (x2 - x1 == 0) - return; - - if (!cell_pixbuf) - return; - - pix_w = gdk_pixbuf_get_width (cell_pixbuf); - pix_h = gdk_pixbuf_get_height (cell_pixbuf); - - /* We center the pixbuf within our allocated space */ - if (x2 - x1 > pix_w) { - gint diff = (x2 - x1) - pix_w; - real_x = x1 + diff / 2; - } else { - real_x = x1; - } - - if (y2 - y1 > pix_h) { - gint diff = (y2 - y1) - pix_h; - real_y = y1 + diff / 2; - } else { - real_y = y1; - } - - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, cell_pixbuf, real_x, real_y); - cairo_paint_with_alpha (cr, 1); - cairo_restore (cr); -} - -static gint -pixbuf_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - /* noop */ - - return FALSE; -} - -static gint -pixbuf_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - GdkPixbuf *pixbuf; - if (row == -1) { - if (e_table_model_row_count (ecell_view->e_table_model) > 0) { - row = 0; - } else { - return 6; - } - } - - pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row); - if (!pixbuf) - return 0; - - /* We give ourselves 3 pixels of padding on either side */ - return gdk_pixbuf_get_height (pixbuf) + 6; -} - -/* - * ECell::print method - */ -static void -pixbuf_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - GdkPixbuf *pixbuf; - gint scale; - cairo_t *cr = gtk_print_context_get_cairo_context (context); - - pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row); - if (pixbuf == NULL) - return; - - scale = gdk_pixbuf_get_height (pixbuf); - cairo_save (cr); - cairo_translate (cr, 0, (gdouble)(height - scale) / (gdouble) 2); - gdk_cairo_set_source_pixbuf (cr, pixbuf, (gdouble) scale, (gdouble) scale); - cairo_paint (cr); - cairo_restore (cr); -} - -static gdouble -pixbuf_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - GdkPixbuf *pixbuf; - - if (row == -1) { - if (e_table_model_row_count (ecell_view->e_table_model) > 0) { - row = 0; - } else { - return 6; - } - } - - pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row); - if (!pixbuf) - return 0; - - /* We give ourselves 3 pixels of padding on either side */ - return gdk_pixbuf_get_height (pixbuf); -} - -static gint -pixbuf_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - gint pw; - gint num_rows, i; - gint max_width = -1; - - if (model_col == 0) { - num_rows = e_table_model_row_count (ecell_view->e_table_model); - - for (i = 0; i <= num_rows; i++) { - GdkPixbuf *pixbuf = (GdkPixbuf *) e_table_model_value_at - (ecell_view->e_table_model, - 1, - i); - if (!pixbuf) - continue; - pw = gdk_pixbuf_get_width (pixbuf); - if (max_width < pw) - max_width = pw; - } - } else { - return -1; - } - - return max_width; -} - -static void -pixbuf_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ECellPixbuf *pixbuf; - - pixbuf = E_CELL_PIXBUF (object); - - switch (property_id) { - case PROP_SELECTED_COLUMN: - pixbuf->selected_column = g_value_get_int (value); - break; - - case PROP_FOCUSED_COLUMN: - pixbuf->focused_column = g_value_get_int (value); - break; - - case PROP_UNSELECTED_COLUMN: - pixbuf->unselected_column = g_value_get_int (value); - break; - - default: - return; - } -} - -/* Get_arg handler for the pixbuf item */ -static void -pixbuf_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECellPixbuf *pixbuf; - - pixbuf = E_CELL_PIXBUF (object); - - switch (property_id) { - case PROP_SELECTED_COLUMN: - g_value_set_int (value, pixbuf->selected_column); - break; - - case PROP_FOCUSED_COLUMN: - g_value_set_int (value, pixbuf->focused_column); - break; - - case PROP_UNSELECTED_COLUMN: - g_value_set_int (value, pixbuf->unselected_column); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_cell_pixbuf_init (ECellPixbuf *ecp) -{ - ecp->selected_column = -1; - ecp->focused_column = -1; - ecp->unselected_column = -1; -} - -static void -e_cell_pixbuf_class_init (ECellPixbufClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ECellClass *ecc = E_CELL_CLASS (class); - - object_class->set_property = pixbuf_set_property; - object_class->get_property = pixbuf_get_property; - - ecc->new_view = pixbuf_new_view; - ecc->kill_view = pixbuf_kill_view; - ecc->draw = pixbuf_draw; - ecc->event = pixbuf_event; - ecc->height = pixbuf_height; - ecc->print = pixbuf_print; - ecc->print_height = pixbuf_print_height; - ecc->max_width = pixbuf_max_width; - - g_object_class_install_property ( - object_class, - PROP_SELECTED_COLUMN, - g_param_spec_int ( - "selected_column", - "Selected Column", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FOCUSED_COLUMN, - g_param_spec_int ( - "focused_column", - "Focused Column", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UNSELECTED_COLUMN, - g_param_spec_int ( - "unselected_column", - "Unselected Column", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); -} - diff --git a/widgets/table/e-cell-pixbuf.h b/widgets/table/e-cell-pixbuf.h deleted file mode 100644 index f4848f7430..0000000000 --- a/widgets/table/e-cell-pixbuf.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * e-cell-pixbuf.h - An ECell that displays a GdkPixbuf - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Vladimir Vukicevic <vladimir@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CELL_PIXBUF_H_ -#define _E_CELL_PIXBUF_H_ - -#include <table/e-table.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_PIXBUF \ - (e_cell_pixbuf_get_type ()) -#define E_CELL_PIXBUF(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_PIXBUF, ECellPixbuf)) -#define E_CELL_PIXBUF_CLASS(cls) \ - (G_TYPE_CHECK_INSTANCE_CAST_CLASS \ - ((cls), E_TYPE_CELL_PIXBUF, ECellPixbufClass)) -#define E_IS_CELL_PIXBUF(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_PIXBUF)) -#define E_IS_CELL_PIXBUF_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_PIXBUF)) -#define E_CELL_PIXBUF_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_PIXBUF, ECellPixbufClass)) - -G_BEGIN_DECLS - -typedef struct _ECellPixbuf ECellPixbuf; -typedef struct _ECellPixbufClass ECellPixbufClass; - -struct _ECellPixbuf { - ECell parent; - - gint selected_column; - gint focused_column; - gint unselected_column; -}; - -struct _ECellPixbufClass { - ECellClass parent_class; -}; - -GType e_cell_pixbuf_get_type (void) G_GNUC_CONST; -ECell * e_cell_pixbuf_new (void); - -G_END_DECLS - -#endif /* _E_CELL_PIXBUF_H */ diff --git a/widgets/table/e-cell-popup.c b/widgets/table/e-cell-popup.c deleted file mode 100644 index ce821700f3..0000000000 --- a/widgets/table/e-cell-popup.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * e-cell-popup.c: Popup cell renderer - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPopup - an abstract ECell class used to support popup selections like - * a GtkCombo widget. It contains a child ECell, e.g. an ECellText, but when - * selected it displays an arrow on the right edge which the user can click to - * show a popup. Subclasses implement the popup class function to show the - * popup. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> - -#include "gal-a11y-e-cell-popup.h" -#include "gal-a11y-e-cell-registry.h" -#include "e-util/e-util.h" - -#include "e-cell-popup.h" -#include "e-table-item.h" -#include <gtk/gtk.h> - -#define E_CELL_POPUP_ARROW_SIZE 16 -#define E_CELL_POPUP_ARROW_PAD 3 - -static void e_cell_popup_dispose (GObject *object); - -static ECellView * ecp_new_view (ECell *ecell, - ETableModel *table_model, - void *e_table_item_view); -static void ecp_kill_view (ECellView *ecv); -static void ecp_realize (ECellView *ecv); -static void ecp_unrealize (ECellView *ecv); -static void ecp_draw (ECellView *ecv, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2); -static gint ecp_event (ECellView *ecv, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions); -static gint ecp_height (ECellView *ecv, - gint model_col, - gint view_col, - gint row); -static gpointer ecp_enter_edit (ECellView *ecv, - gint model_col, - gint view_col, - gint row); -static void ecp_leave_edit (ECellView *ecv, - gint model_col, - gint view_col, - gint row, - void *edit_context); -static void ecp_print (ECellView *ecv, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height); -static gdouble ecp_print_height (ECellView *ecv, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width); -static gint ecp_max_width (ECellView *ecv, - gint model_col, - gint view_col); -static gchar *ecp_get_bg_color (ECellView *ecell_view, gint row); - -static gint e_cell_popup_do_popup (ECellPopupView *ecp_view, - GdkEvent *event, - gint row, - gint model_col); - -G_DEFINE_TYPE (ECellPopup, e_cell_popup, E_TYPE_CELL) - -static void -e_cell_popup_class_init (ECellPopupClass *class) -{ - ECellClass *ecc = E_CELL_CLASS (class); - - G_OBJECT_CLASS (class)->dispose = e_cell_popup_dispose; - - ecc->new_view = ecp_new_view; - ecc->kill_view = ecp_kill_view; - ecc->realize = ecp_realize; - ecc->unrealize = ecp_unrealize; - ecc->draw = ecp_draw; - ecc->event = ecp_event; - ecc->height = ecp_height; - ecc->enter_edit = ecp_enter_edit; - ecc->leave_edit = ecp_leave_edit; - ecc->print = ecp_print; - ecc->print_height = ecp_print_height; - ecc->max_width = ecp_max_width; - ecc->get_bg_color = ecp_get_bg_color; - - gal_a11y_e_cell_registry_add_cell_type ( - NULL, E_TYPE_CELL_POPUP, - gal_a11y_e_cell_popup_new); -} - -static void -e_cell_popup_init (ECellPopup *ecp) -{ - ecp->popup_shown = FALSE; - ecp->popup_model = NULL; -} - -/** - * e_cell_popup_new: - * - * Creates a new ECellPopup renderer. - * - * Returns: an ECellPopup object. - */ -ECell * -e_cell_popup_new (void) -{ - return g_object_new (E_TYPE_CELL_POPUP, NULL); -} - -static void -e_cell_popup_dispose (GObject *object) -{ - ECellPopup *ecp = E_CELL_POPUP (object); - - if (ecp->child) - g_object_unref (ecp->child); - ecp->child = NULL; - - G_OBJECT_CLASS (e_cell_popup_parent_class)->dispose (object); -} - -/* - * ECell::new_view method - */ -static ECellView * -ecp_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellPopup *ecp = E_CELL_POPUP (ecell); - ECellPopupView *ecp_view; - - /* We must have a child ECell before we create any views. */ - g_return_val_if_fail (ecp->child != NULL, NULL); - - ecp_view = g_new0 (ECellPopupView, 1); - - ecp_view->cell_view.ecell = ecell; - ecp_view->cell_view.e_table_model = table_model; - ecp_view->cell_view.e_table_item_view = e_table_item_view; - ecp_view->cell_view.kill_view_cb = NULL; - ecp_view->cell_view.kill_view_cb_data = NULL; - - ecp_view->child_view = e_cell_new_view ( - ecp->child, table_model, - e_table_item_view); - - return (ECellView *) ecp_view; -} - -/* - * ECell::kill_view method - */ -static void -ecp_kill_view (ECellView *ecv) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - if (ecp_view->cell_view.kill_view_cb) - ecp_view->cell_view.kill_view_cb ( - ecv, ecp_view->cell_view.kill_view_cb_data); - - if (ecp_view->cell_view.kill_view_cb_data) - g_list_free (ecp_view->cell_view.kill_view_cb_data); - - if (ecp_view->child_view) - e_cell_kill_view (ecp_view->child_view); - - g_free (ecp_view); -} - -/* - * ECell::realize method - */ -static void -ecp_realize (ECellView *ecv) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - e_cell_realize (ecp_view->child_view); - - if (E_CELL_CLASS (e_cell_popup_parent_class)->realize) - (* E_CELL_CLASS (e_cell_popup_parent_class)->realize) (ecv); -} - -/* - * ECell::unrealize method - */ -static void -ecp_unrealize (ECellView *ecv) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - e_cell_unrealize (ecp_view->child_view); - - if (E_CELL_CLASS (e_cell_popup_parent_class)->unrealize) - (* E_CELL_CLASS (e_cell_popup_parent_class)->unrealize) (ecv); -} - -/* - * ECell::draw method - */ -static void -ecp_draw (ECellView *ecv, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellPopup *ecp = E_CELL_POPUP (ecv->ecell); - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - GtkWidget *canvas; - gboolean show_popup_arrow; - - cairo_save (cr); - - canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ecv->e_table_item_view)->canvas); - - /* Display the popup arrow if we are the cursor cell, or the popup - * is shown for this cell. */ - show_popup_arrow = - e_table_model_is_cell_editable ( - ecv->e_table_model, model_col, row) && - (flags & E_CELL_CURSOR || - (ecp->popup_shown && ecp->popup_view_col == view_col - && ecp->popup_row == row - && ecp->popup_model == ((ECellView *) ecp_view)->e_table_model)); - - if (flags & E_CELL_CURSOR) - ecp->popup_arrow_shown = show_popup_arrow; - - if (show_popup_arrow) { - GtkStyleContext *style_context; - GdkRGBA color; - gint arrow_x; - gint arrow_y; - gint arrow_size; - gint midpoint_y; - - e_cell_draw ( - ecp_view->child_view, cr, model_col, - view_col, row, flags, - x1, y1, x2 - E_CELL_POPUP_ARROW_SIZE, y2); - - midpoint_y = y1 + ((y2 - y1 + 1) / 2); - - arrow_x = x2 - E_CELL_POPUP_ARROW_SIZE; - arrow_y = midpoint_y - E_CELL_POPUP_ARROW_SIZE / 2; - arrow_size = E_CELL_POPUP_ARROW_SIZE; - - style_context = gtk_widget_get_style_context (canvas); - - gtk_style_context_save (style_context); - - gtk_style_context_add_class ( - style_context, GTK_STYLE_CLASS_CELL); - - gtk_style_context_get_background_color ( - style_context, GTK_STATE_FLAG_NORMAL, &color); - - cairo_save (cr); - gdk_cairo_set_source_rgba (cr, &color); - gtk_render_background ( - style_context, cr, - (gdouble) arrow_x, - (gdouble) arrow_y, - (gdouble) arrow_size, - (gdouble) arrow_size); - cairo_restore (cr); - - arrow_x += E_CELL_POPUP_ARROW_PAD; - arrow_y += E_CELL_POPUP_ARROW_PAD; - arrow_size -= (E_CELL_POPUP_ARROW_PAD * 2); - - cairo_save (cr); - gtk_render_arrow ( - style_context, cr, G_PI, - (gdouble) arrow_x, - (gdouble) arrow_y, - (gdouble) arrow_size); - cairo_restore (cr); - - gtk_style_context_restore (style_context); - } else { - e_cell_draw ( - ecp_view->child_view, cr, model_col, - view_col, row, flags, x1, y1, x2, y2); - } - - cairo_restore (cr); -} - -/* - * ECell::event method - */ -static gint -ecp_event (ECellView *ecv, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - ECellPopup *ecp = E_CELL_POPUP (ecp_view->cell_view.ecell); - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - gint width; - - switch (event->type) { - case GDK_BUTTON_PRESS: - if (e_table_model_is_cell_editable (ecv->e_table_model, model_col, row) && - flags & E_CELL_CURSOR - && ecp->popup_arrow_shown) { - width = e_table_header_col_diff ( - eti->header, view_col, - view_col + 1); - - /* FIXME: The event coords seem to be relative to the - * text within the cell, so we have to add 4. */ - if (event->button.x + 4 >= width - E_CELL_POPUP_ARROW_SIZE) { - return e_cell_popup_do_popup (ecp_view, event, row, view_col); - } - } - break; - case GDK_KEY_PRESS: - if (e_table_model_is_cell_editable (ecv->e_table_model, model_col, row) && - event->key.state & GDK_MOD1_MASK - && event->key.keyval == GDK_KEY_Down) { - return e_cell_popup_do_popup (ecp_view, event, row, view_col); - } - break; - default: - break; - } - - return e_cell_event ( - ecp_view->child_view, event, model_col, view_col, - row, flags, actions); -} - -/* - * ECell::height method - */ -static gint -ecp_height (ECellView *ecv, - gint model_col, - gint view_col, - gint row) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - return e_cell_height (ecp_view->child_view, model_col, view_col, row); -} - -/* - * ECellView::enter_edit method - */ -static gpointer -ecp_enter_edit (ECellView *ecv, - gint model_col, - gint view_col, - gint row) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - return e_cell_enter_edit (ecp_view->child_view, model_col, view_col, row); -} - -/* - * ECellView::leave_edit method - */ -static void -ecp_leave_edit (ECellView *ecv, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - e_cell_leave_edit ( - ecp_view->child_view, model_col, view_col, row, - edit_context); -} - -static void -ecp_print (ECellView *ecv, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - e_cell_print ( - ecp_view->child_view, context, model_col, view_col, row, - width, height); -} - -static gdouble -ecp_print_height (ECellView *ecv, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - return e_cell_print_height ( - ecp_view->child_view, context, model_col, - view_col, row, width); -} - -static gint -ecp_max_width (ECellView *ecv, - gint model_col, - gint view_col) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecv; - - return e_cell_max_width (ecp_view->child_view, model_col, view_col); -} - -static gchar * -ecp_get_bg_color (ECellView *ecell_view, - gint row) -{ - ECellPopupView *ecp_view = (ECellPopupView *) ecell_view; - - return e_cell_get_bg_color (ecp_view->child_view, row); -} - -ECell * -e_cell_popup_get_child (ECellPopup *ecp) -{ - g_return_val_if_fail (E_IS_CELL_POPUP (ecp), NULL); - - return ecp->child; -} - -void -e_cell_popup_set_child (ECellPopup *ecp, - ECell *child) -{ - g_return_if_fail (E_IS_CELL_POPUP (ecp)); - - if (ecp->child) - g_object_unref (ecp->child); - - ecp->child = child; - g_object_ref (child); -} - -static gint -e_cell_popup_do_popup (ECellPopupView *ecp_view, - GdkEvent *event, - gint row, - gint view_col) -{ - ECellPopup *ecp = E_CELL_POPUP (ecp_view->cell_view.ecell); - gint (*popup_func) (ECellPopup *ecp, GdkEvent *event, gint row, gint view_col); - - ecp->popup_cell_view = ecp_view; - - popup_func = E_CELL_POPUP_CLASS (G_OBJECT_GET_CLASS (ecp))->popup; - - ecp->popup_view_col = view_col; - ecp->popup_row = row; - ecp->popup_model = ((ECellView *) ecp_view)->e_table_model; - - return popup_func ? popup_func (ecp, event, row, view_col) : FALSE; -} - -/* This redraws the popup cell. Only use this if you know popup_view_col and - * popup_row are valid. */ -void -e_cell_popup_queue_cell_redraw (ECellPopup *ecp) -{ - ETableItem *eti; - - eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - - e_table_item_redraw_range ( - eti, ecp->popup_view_col, ecp->popup_row, - ecp->popup_view_col, ecp->popup_row); -} - -void -e_cell_popup_set_shown (ECellPopup *ecp, - gboolean shown) -{ - ecp->popup_shown = shown; - e_cell_popup_queue_cell_redraw (ecp); -} diff --git a/widgets/table/e-cell-popup.h b/widgets/table/e-cell-popup.h deleted file mode 100644 index bc99196eaf..0000000000 --- a/widgets/table/e-cell-popup.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPopup - an ECell used to support popup selections like a GtkCombo - * widget. It contains a child ECell, e.g. an ECellText, but when selected it - * displays an arrow on the right edge which the user can click to show a - * popup. It will support subclassing or signals so that different types of - * popup can be provided. - */ - -#ifndef _E_CELL_POPUP_H_ -#define _E_CELL_POPUP_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_POPUP \ - (e_cell_popup_get_type ()) -#define E_CELL_POPUP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_POPUP, ECellPopup)) -#define E_CELL_POPUP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_POPUP, ECellPopupClass)) -#define E_IS_CELL_POPUP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_POPUP)) -#define E_IS_CELL_POPUP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_POPUP)) -#define E_CELL_POPUP_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_POPUP, ECellPopupClass)) - -G_BEGIN_DECLS - -typedef struct _ECellPopup ECellPopup; -typedef struct _ECellPopupView ECellPopupView; -typedef struct _ECellPopupClass ECellPopupClass; - -struct _ECellPopup { - ECell parent; - - ECell *child; - - /* This is TRUE if the popup window is shown for the cell being - * edited. While shown we display the arrow indented. */ - gboolean popup_shown; - - /* This is TRUE if the popup arrow is shown for the cell being edited. - * This is needed to stop the first click on the cell from popping up - * the popup window. We only popup the window after we have drawn the - * arrow. */ - gboolean popup_arrow_shown; - - /* The view in which the popup is shown. */ - ECellPopupView *popup_cell_view; - - gint popup_view_col; - gint popup_row; - ETableModel *popup_model; -}; - -struct _ECellPopupView { - ECellView cell_view; - - ECellView *child_view; -}; - -struct _ECellPopupClass { - ECellClass parent_class; - - /* Virtual function for subclasses to override. */ - gint (*popup) (ECellPopup *ecp, - GdkEvent *event, - gint row, - gint view_col); -}; - -GType e_cell_popup_get_type (void) G_GNUC_CONST; -ECell * e_cell_popup_new (void); -ECell * e_cell_popup_get_child (ECellPopup *ecp); -void e_cell_popup_set_child (ECellPopup *ecp, - ECell *child); -void e_cell_popup_set_shown (ECellPopup *ecp, - gboolean shown); -void e_cell_popup_queue_cell_redraw (ECellPopup *ecp); - -G_END_DECLS - -#endif /* _E_CELL_POPUP_H_ */ diff --git a/widgets/table/e-cell-size.c b/widgets/table/e-cell-size.c deleted file mode 100644 index 8f01847d7c..0000000000 --- a/widgets/table/e-cell-size.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/time.h> -#include <unistd.h> - -#include "e-util/e-util.h" - -#include "e-cell-size.h" - -G_DEFINE_TYPE (ECellSize, e_cell_size, E_TYPE_CELL_TEXT) - -static gchar * -ecd_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - gint size = GPOINTER_TO_INT (e_table_model_value_at (model, col, row)); - gfloat fsize; - - if (size < 1024) { - return g_strdup_printf ("%d bytes", size); - } else { - fsize = ((gfloat) size) / 1024.0; - if (fsize < 1024.0) { - return g_strdup_printf ("%d K", (gint) fsize); - } else { - fsize /= 1024.0; - return g_strdup_printf ("%.1f MB", fsize); - } - } -} - -static void -ecd_free_text (ECellText *cell, - gchar *text) -{ - g_free (text); -} - -static void -e_cell_size_class_init (ECellSizeClass *class) -{ - ECellTextClass *ectc = E_CELL_TEXT_CLASS (class); - - ectc->get_text = ecd_get_text; - ectc->free_text = ecd_free_text; -} - -static void -e_cell_size_init (ECellSize *e_cell_size) -{ -} - -/** - * e_cell_size_new: - * @fontname: font to be used to render on the screen - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render file sizes - * that that come from the model. The value returned from the model - * is interpreted as being a time_t. - * - * The ECellSize object support a large set of properties that can be - * configured through the Gtk argument system and allows the user to - * have a finer control of the way the string is displayed. The - * arguments supported allow the control of strikeout, underline, - * bold, color and a size filter. - * - * The arguments "strikeout_column", "underline_column", "bold_column" - * and "color_column" set and return an integer that points to a - * column in the model that controls these settings. So controlling - * the way things are rendered is achieved by having special columns - * in the model that will be used to flag whether the size should be - * rendered with strikeout, underline, or bolded. In the case of the - * "color_column" argument, the column in the model is expected to - * have a string that can be parsed by gdk_color_parse(). - * - * Returns: an ECell object that can be used to render file sizes. */ -ECell * -e_cell_size_new (const gchar *fontname, - GtkJustification justify) -{ - ECellSize *ecd = g_object_new (E_TYPE_CELL_SIZE, NULL); - - e_cell_text_construct (E_CELL_TEXT (ecd), fontname, justify); - - return (ECell *) ecd; -} - diff --git a/widgets/table/e-cell-size.h b/widgets/table/e-cell-size.h deleted file mode 100644 index 8b52343b8a..0000000000 --- a/widgets/table/e-cell-size.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * e-cell-size.h: Size item for e-table. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CELL_SIZE_H -#define E_CELL_SIZE_H - -#include <table/e-cell-text.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_SIZE \ - (e_cell_size_get_type ()) -#define E_CELL_SIZE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_SIZE, ECellSize)) -#define E_CELL_SIZE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_SIZE, ECellSizeClass)) -#define E_IS_CELL_SIZE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_SIZE)) -#define E_IS_CELL_SIZE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_SIZE)) -#define E_CELL_SIZE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_SIZE, ECellSizeClass)) - -G_BEGIN_DECLS - -typedef struct _ECellSize ECellSize; -typedef struct _ECellSizeClass ECellSizeClass; - -struct _ECellSize { - ECellText parent; -}; - -struct _ECellSizeClass { - ECellTextClass parent_class; -}; - -GType e_cell_size_get_type (void) G_GNUC_CONST; -ECell * e_cell_size_new (const gchar *fontname, - GtkJustification justify); - -G_END_DECLS - -#endif /* E_CELL_SIZE_H */ diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c deleted file mode 100644 index 6ad47b4c50..0000000000 --- a/widgets/table/e-cell-text.c +++ /dev/null @@ -1,2811 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Chris Lahey <clahey@ximian.com> - * - * A lot of code taken from: - * - * Text item type for GnomeCanvas widget - * - * GnomeCanvas is basically a port of the Tk toolkit's most excellent - * canvas widget. Tk is copyrighted by the Regents of the University - * of California, Sun Microsystems, and other parties. - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <ctype.h> -#include <math.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "text/e-text.h" -#include <glib/gi18n.h> -#include "e-util/e-text-event-processor.h" -#include "e-util/e-text-event-processor-emacs-like.h" -#include "e-util/e-util.h" -#include "misc/e-canvas.h" -#include "e-util/e-unicode.h" - -#include "e-table.h" -#include "e-cell-text.h" -#include "e-table-item.h" - -#define d(x) -#define DO_SELECTION 1 -#define VIEW_TO_CELL(view) E_CELL_TEXT (((ECellView *)view)->ecell) - -#if d(!)0 -#define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x)), g_print ("%s: e_table_item_leave_edit\n", __FUNCTION__)) -#else -#define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x))) -#endif - -/* This defines a line of text */ -struct line { - gchar *text; /* Line's text UTF-8, it is a pointer into the text->text string */ - gint length; /* Line's length in BYTES */ - gint width; /* Line's width in pixels */ - gint ellipsis_length; /* Length before adding ellipsis in BYTES */ -}; - -/* Object argument IDs */ -enum { - PROP_0, - - PROP_STRIKEOUT_COLUMN, - PROP_UNDERLINE_COLUMN, - PROP_BOLD_COLUMN, - PROP_COLOR_COLUMN, - PROP_EDITABLE, - PROP_BG_COLOR_COLUMN -}; - -enum { - E_SELECTION_PRIMARY, - E_SELECTION_CLIPBOARD -}; - -/* signals */ -enum { - TEXT_INSERTED, - TEXT_DELETED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static GdkAtom clipboard_atom = GDK_NONE; - -G_DEFINE_TYPE (ECellText, e_cell_text, E_TYPE_CELL) - -#define UTF8_ATOM gdk_atom_intern ("UTF8_STRING", FALSE) - -#define TEXT_PAD 4 - -typedef struct { - gpointer lines; /* Text split into lines (private field) */ - gint num_lines; /* Number of lines of text */ - gint max_width; - gint ref_count; -} ECellTextLineBreaks; - -typedef struct _CellEdit CellEdit; - -typedef struct { - ECellView cell_view; - GdkCursor *i_cursor; - - GnomeCanvas *canvas; - - /* - * During editing. - */ - CellEdit *edit; - - gint xofs, yofs; /* This gets added to the x - and y for the cell text. */ - gdouble ellipsis_width[2]; /* The width of the ellipsis. */ -} ECellTextView; - -struct _CellEdit { - - ECellTextView *text_view; - - gint model_col, view_col, row; - gint cell_width; - - PangoLayout *layout; - - gchar *text; - - gchar *old_text; - - /* - * Where the editing is taking place - */ - - gint xofs_edit, yofs_edit; /* Offset because of editing. - This is negative compared - to the other offsets. */ - - /* This needs to be reworked a bit once we get line wrapping. */ - gint selection_start; /* Start of selection - IN BYTES */ - gint selection_end; /* End of selection - IN BYTES */ - gboolean select_by_word; /* Current selection is by word */ - - /* This section is for drag scrolling and blinking cursor. */ - /* Cursor handling. */ - gint timeout_id; /* Current timeout id for scrolling */ - GTimer *timer; /* Timer for blinking cursor and scrolling */ - - gint lastx, lasty; /* Last x and y motion events */ - gint last_state; /* Last state */ - gulong scroll_start; /* Starting time for scroll (microseconds) */ - - gint show_cursor; /* Is cursor currently shown */ - gboolean button_down; /* Is mouse button 1 down */ - - ETextEventProcessor *tep; /* Text Event Processor */ - - gboolean has_selection; /* TRUE if we have the selection */ - - guint pointer_in : 1; - guint default_cursor_shown : 1; - GtkIMContext *im_context; - gboolean need_im_reset; - gboolean im_context_signals_registered; - - guint16 preedit_length; /* length of preedit string, in bytes */ - gint preedit_pos; /* position of preedit cursor */ - - ECellActions actions; -}; - -static void e_cell_text_view_command (ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data); - -static void e_cell_text_view_get_selection (CellEdit *edit, GdkAtom selection, guint32 time); -static void e_cell_text_view_supply_selection (CellEdit *edit, guint time, GdkAtom selection, gchar *data, gint length); - -static void _get_tep (CellEdit *edit); - -static gint get_position_from_xy (CellEdit *edit, gint x, gint y); -static gboolean _blink_scroll_timeout (gpointer data); - -static void e_cell_text_preedit_changed_cb (GtkIMContext *context, ECellTextView *text_view); -static void e_cell_text_commit_cb (GtkIMContext *context, const gchar *str, ECellTextView *text_view); -static gboolean e_cell_text_retrieve_surrounding_cb (GtkIMContext *context, ECellTextView *text_view); -static gboolean e_cell_text_delete_surrounding_cb (GtkIMContext *context, gint offset, gint n_chars, ECellTextView *text_view); -static void _insert (ECellTextView *text_view, const gchar *string, gint value); -static void _delete_selection (ECellTextView *text_view); -static PangoAttrList * build_attr_list (ECellTextView *text_view, gint row, gint text_length); -static void update_im_cursor_location (ECellTextView *tv); - -static gchar * -ect_real_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - return e_table_model_value_at (model, col, row); -} - -static void -ect_real_free_text (ECellText *cell, - gchar *text) -{ -} - -/* This is the default method for setting the ETableModel value based on - * the text in the ECellText. This simply uses the text as it is - it assumes - * the value in the model is a gchar *. Subclasses may parse the text into - * data structures to pass to the model. */ -static void -ect_real_set_value (ECellText *cell, - ETableModel *model, - gint col, - gint row, - const gchar *text) -{ - e_table_model_set_value_at (model, col, row, text); -} - -static void -ect_queue_redraw (ECellTextView *text_view, - gint view_col, - gint view_row) -{ - e_table_item_redraw_range ( - text_view->cell_view.e_table_item_view, - view_col, view_row, view_col, view_row); -} - -/* - * Shuts down the editing process - */ -static void -ect_stop_editing (ECellTextView *text_view, - gboolean commit) -{ - GdkWindow *window; - CellEdit *edit = text_view->edit; - gint row, view_col, model_col; - gchar *old_text, *text; - - if (!edit) - return; - - window = gtk_widget_get_window (GTK_WIDGET (text_view->canvas)); - - row = edit->row; - view_col = edit->view_col; - model_col = edit->model_col; - - old_text = edit->old_text; - text = edit->text; - if (edit->tep) - g_object_unref (edit->tep); - if (!edit->default_cursor_shown) { - gdk_window_set_cursor (window, NULL); - edit->default_cursor_shown = TRUE; - } - if (edit->timeout_id) { - g_source_remove (edit->timeout_id); - edit->timeout_id = 0; - } - if (edit->timer) { - g_timer_stop (edit->timer); - g_timer_destroy (edit->timer); - edit->timer = NULL; - } - - g_signal_handlers_disconnect_matched ( - edit->im_context, - G_SIGNAL_MATCH_DATA, 0, 0, - NULL, NULL, text_view); - - if (edit->layout) - g_object_unref (edit->layout); - - g_free (edit); - - text_view->edit = NULL; - if (commit) { - /* - * Accept the currently edited text. if it's the same as what's in the cell, do nothing. - */ - ECellView *ecell_view = (ECellView *) text_view; - ECellText *ect = (ECellText *) ecell_view->ecell; - - if (strcmp (old_text, text)) { - e_cell_text_set_value ( - ect, ecell_view->e_table_model, - model_col, row, text); - } - } - g_free (text); - g_free (old_text); - - ect_queue_redraw (text_view, view_col, row); -} - -/* - * Cancels the edits - */ -static void -ect_cancel_edit (ECellTextView *text_view) -{ - ect_stop_editing (text_view, FALSE); - e_table_item_leave_edit_ (text_view->cell_view.e_table_item_view); -} - -/* - * ECell::new_view method - */ -static ECellView * -ect_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellTextView *text_view = g_new0 (ECellTextView, 1); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas; - - text_view->cell_view.ecell = ecell; - text_view->cell_view.e_table_model = table_model; - text_view->cell_view.e_table_item_view = e_table_item_view; - text_view->cell_view.kill_view_cb = NULL; - text_view->cell_view.kill_view_cb_data = NULL; - - text_view->canvas = canvas; - - text_view->xofs = 0.0; - text_view->yofs = 0.0; - - return (ECellView *) text_view; -} - -/* - * ECell::kill_view method - */ -static void -ect_kill_view (ECellView *ecv) -{ - ECellTextView *text_view = (ECellTextView *) ecv; - - if (text_view->cell_view.kill_view_cb) - (text_view->cell_view.kill_view_cb)(ecv, text_view->cell_view.kill_view_cb_data); - - if (text_view->cell_view.kill_view_cb_data) - g_list_free (text_view->cell_view.kill_view_cb_data); - - g_free (text_view); -} - -/* - * ECell::realize method - */ -static void -ect_realize (ECellView *ecell_view) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - - text_view->i_cursor = gdk_cursor_new (GDK_XTERM); - - if (E_CELL_CLASS (e_cell_text_parent_class)->realize) - (* E_CELL_CLASS (e_cell_text_parent_class)->realize) (ecell_view); -} - -/* - * ECell::unrealize method - */ -static void -ect_unrealize (ECellView *ecv) -{ - ECellTextView *text_view = (ECellTextView *) ecv; - - if (text_view->edit) { - ect_cancel_edit (text_view); - } - - g_object_unref (text_view->i_cursor); - - if (E_CELL_CLASS (e_cell_text_parent_class)->unrealize) - (* E_CELL_CLASS (e_cell_text_parent_class)->unrealize) (ecv); - -} - -static PangoAttrList * -build_attr_list (ECellTextView *text_view, - gint row, - gint text_length) -{ - - ECellView *ecell_view = (ECellView *) text_view; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - PangoAttrList *attrs = pango_attr_list_new (); - gboolean bold, strikeout, underline; - - bold = ect->bold_column >= 0 && - row >= 0 && - e_table_model_value_at (ecell_view->e_table_model, ect->bold_column, row); - strikeout = ect->strikeout_column >= 0 && - row >= 0 && - e_table_model_value_at (ecell_view->e_table_model, ect->strikeout_column, row); - underline = ect->underline_column >= 0 && - row >= 0 && - e_table_model_value_at (ecell_view->e_table_model, ect->underline_column, row); - - if (bold || strikeout || underline) { - if (bold) { - PangoAttribute *attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); - attr->start_index = 0; - attr->end_index = text_length; - - pango_attr_list_insert_before (attrs, attr); - } - if (strikeout) { - PangoAttribute *attr = pango_attr_strikethrough_new (TRUE); - attr->start_index = 0; - attr->end_index = text_length; - - pango_attr_list_insert_before (attrs, attr); - } - if (underline) { - PangoAttribute *attr = pango_attr_underline_new (TRUE); - attr->start_index = 0; - attr->end_index = text_length; - - pango_attr_list_insert_before (attrs, attr); - } - } - return attrs; -} - -static PangoLayout * -layout_with_preedit (ECellTextView *text_view, - gint row, - const gchar *text, - gint width) -{ - CellEdit *edit = text_view->edit; - PangoAttrList *attrs; - PangoLayout *layout; - GString *tmp_string = g_string_new (NULL); - PangoAttrList *preedit_attrs = NULL; - gchar *preedit_string = NULL; - gint preedit_length = 0; - gint text_length = strlen (text); - gint mlen = MIN (edit->selection_start,text_length); - - gtk_im_context_get_preedit_string ( - edit->im_context, - &preedit_string,&preedit_attrs, - NULL); - preedit_length = edit->preedit_length = strlen (preedit_string);; - - layout = edit->layout; - - g_string_prepend_len (tmp_string, text,text_length); - - if (preedit_length) { - - /* mlen is the text_length in bytes, not chars - * check whether we are not inserting into - * the middle of a utf8 character - */ - - if (mlen < text_length) { - if (!g_utf8_validate (text + mlen, -1, NULL)) { - gchar *tc; - tc = g_utf8_find_next_char (text + mlen,NULL); - if (tc) { - mlen = (gint) (tc - text); - } - } - } - - g_string_insert (tmp_string, mlen, preedit_string); - } - - pango_layout_set_text (layout, tmp_string->str, tmp_string->len); - - attrs = (PangoAttrList *) build_attr_list (text_view, row, text_length); - - if (preedit_length) - pango_attr_list_splice (attrs, preedit_attrs, mlen, preedit_length); - pango_layout_set_attributes (layout, attrs); - g_string_free (tmp_string, TRUE); - if (preedit_string) - g_free (preedit_string); - if (preedit_attrs) - pango_attr_list_unref (preedit_attrs); - pango_attr_list_unref (attrs); - - update_im_cursor_location (text_view); - - return layout; -} - -static PangoLayout * -build_layout (ECellTextView *text_view, - gint row, - const gchar *text, - gint width) -{ - ECellView *ecell_view = (ECellView *) text_view; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - PangoAttrList *attrs; - PangoLayout *layout; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (((GnomeCanvasItem *) ecell_view->e_table_item_view)->canvas), text); - - attrs = (PangoAttrList *) build_attr_list (text_view, row, text ? strlen (text) : 0); - - pango_layout_set_attributes (layout, attrs); - pango_attr_list_unref (attrs); - - if (text_view->edit || width <= 0) - return layout; - - if (ect->font_name) - { - PangoFontDescription *desc = NULL, *fixed_desc = NULL; - gchar *fixed_family = NULL; - gint fixed_size = 0; - gboolean fixed_points = TRUE; - - fixed_desc = pango_font_description_from_string (ect->font_name); - if (fixed_desc) { - fixed_family = (gchar *) pango_font_description_get_family (fixed_desc); - fixed_size = pango_font_description_get_size (fixed_desc); - fixed_points = !pango_font_description_get_size_is_absolute (fixed_desc); - } - - desc = pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (((GnomeCanvasItem *) ecell_view->e_table_item_view)->canvas))->font_desc); - pango_font_description_set_family (desc, fixed_family); - if (fixed_points) - pango_font_description_set_size (desc, fixed_size); - else - pango_font_description_set_absolute_size (desc, fixed_size); -/* pango_font_description_set_style (desc, PANGO_STYLE_OBLIQUE); */ - pango_layout_set_font_description (layout, desc); - pango_font_description_free (desc); - pango_font_description_free (fixed_desc); - } - - pango_layout_set_width (layout, width * PANGO_SCALE); - pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); - - pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); - pango_layout_set_height (layout, 0); - - switch (ect->justify) { - case GTK_JUSTIFY_RIGHT: - pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); - break; - case GTK_JUSTIFY_CENTER: - pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); - break; - case GTK_JUSTIFY_LEFT: - default: - break; - } - - return layout; -} - -static PangoLayout * -generate_layout (ECellTextView *text_view, - gint model_col, - gint view_col, - gint row, - gint width) -{ - ECellView *ecell_view = (ECellView *) text_view; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - PangoLayout *layout; - CellEdit *edit = text_view->edit; - - if (edit && edit->layout && edit->model_col == model_col && edit->row == row) { - g_object_ref (edit->layout); - return edit->layout; - } - - if (row >= 0) { - gchar *temp = e_cell_text_get_text (ect, ecell_view->e_table_model, model_col, row); - layout = build_layout (text_view, row, temp ? temp : "?", width); - e_cell_text_free_text (ect, temp); - } else - layout = build_layout (text_view, row, "Mumbo Jumbo", width); - - return layout; -} - -static void -draw_cursor (cairo_t *cr, - gint x1, - gint y1, - PangoRectangle rect) -{ - gdouble scaled_x; - gdouble scaled_y; - gdouble scaled_height; - - /* Pango stores each cursor position as a zero-width rectangle. */ - scaled_x = x1 + ((gdouble) rect.x) / PANGO_SCALE; - scaled_y = y1 + ((gdouble) rect.y) / PANGO_SCALE; - scaled_height = ((gdouble) rect.height) / PANGO_SCALE; - - /* Adding 0.5 to scaled_x gives a sharp, one-pixel line. */ - cairo_move_to (cr, scaled_x + 0.5, scaled_y); - cairo_line_to (cr, scaled_x + 0.5, scaled_y + scaled_height); - cairo_set_line_width (cr, 1); - cairo_stroke (cr); -} - -static gboolean -show_pango_rectangle (CellEdit *edit, - PangoRectangle rect) -{ - gint x1 = rect.x / PANGO_SCALE; - gint x2 = (rect.x + rect.width) / PANGO_SCALE; -#if 0 - gint y1 = rect.y / PANGO_SCALE; - gint y2 = (rect.y + rect.height) / PANGO_SCALE; -#endif - - gint new_xofs_edit = edit->xofs_edit; - gint new_yofs_edit = edit->yofs_edit; - - if (x1 < new_xofs_edit) - new_xofs_edit = x1; - if (2 + x2 - edit->cell_width > new_xofs_edit) - new_xofs_edit = 2 + x2 - edit->cell_width; - if (new_xofs_edit < 0) - new_xofs_edit = 0; - -#if 0 - if (y1 < new_yofs_edit) - new_yofs_edit = y1; - if (2 + y2 - edit->cell_height > new_yofs_edit) - new_yofs_edit = 2 + y2 - edit->cell_height; - if (new_yofs_edit < 0) - new_yofs_edit = 0; -#endif - - if (new_xofs_edit != edit->xofs_edit || - new_yofs_edit != edit->yofs_edit) { - edit->xofs_edit = new_xofs_edit; - edit->yofs_edit = new_yofs_edit; - return TRUE; - } - - return FALSE; -} - -static gint -get_vertical_spacing (GtkWidget *canvas) -{ - GtkWidget *widget; - gint vspacing = 0; - - g_return_val_if_fail (E_IS_CANVAS (canvas), 3); - - /* The parent should be either an ETable or ETree. */ - widget = gtk_widget_get_parent (canvas); - - gtk_widget_style_get (widget, "vertical-spacing", &vspacing, NULL); - - return vspacing; -} - -/* - * ECell::draw method - */ -static void -ect_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - PangoLayout *layout; - ECellTextView *text_view = (ECellTextView *) ecell_view; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - CellEdit *edit = text_view->edit; - gboolean selected; - GtkWidget *canvas = GTK_WIDGET (text_view->canvas); - GtkStyle *style; - gint x_origin, y_origin, vspacing; - - cairo_save (cr); - style = gtk_widget_get_style (canvas); - - selected = flags & E_CELL_SELECTED; - - if (selected) { - if (gtk_widget_has_focus (canvas)) - gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_SELECTED]); - else - gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_ACTIVE]); - } else { - gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]); - - if (ect->color_column != -1) { - gchar *color_spec; - GdkColor color; - - color_spec = e_table_model_value_at ( - ecell_view->e_table_model, - ect->color_column, row); - if (color_spec && gdk_color_parse (color_spec, &color)) - gdk_cairo_set_source_color (cr, &color); - } - } - - vspacing = get_vertical_spacing (canvas); - - x1 += 4; - y1 += vspacing; - x2 -= 4; - y2 -= vspacing; - - x_origin = x1 + ect->x + text_view->xofs - (edit ? edit->xofs_edit : 0); - y_origin = y1 + ect->y + text_view->yofs - (edit ? edit->yofs_edit : 0); - - cairo_rectangle (cr, x1, y1, x2 - x1, y2 - y1); - cairo_clip (cr); - - layout = generate_layout (text_view, model_col, view_col, row, x2 - x1); - - if (edit && edit->view_col == view_col && edit->row == row) { - layout = layout_with_preedit (text_view, row, edit->text ? edit->text : "?", x2 - x1); - } - - cairo_move_to (cr, x_origin, y_origin); - pango_cairo_show_layout (cr, layout); - - if (edit && edit->view_col == view_col && edit->row == row) { - if (edit->selection_start != edit->selection_end) { - cairo_region_t *clip_region; - gint indices[2]; - GtkStateType state; - - state = edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE; - - indices[0] = MIN (edit->selection_start, edit->selection_end); - indices[1] = MAX (edit->selection_start, edit->selection_end); - - clip_region = gdk_pango_layout_get_clip_region ( - layout, x_origin, y_origin, indices, 1); - gdk_cairo_region (cr, clip_region); - cairo_clip (cr); - cairo_region_destroy (clip_region); - - gdk_cairo_set_source_color (cr, &style->base[state]); - cairo_paint (cr); - - gdk_cairo_set_source_color (cr, &style->text[state]); - cairo_move_to (cr, x_origin, y_origin); - pango_cairo_show_layout (cr, layout); - } else { - if (edit->show_cursor) { - PangoRectangle strong_pos, weak_pos; - pango_layout_get_cursor_pos (layout, edit->selection_start + edit->preedit_length, &strong_pos, &weak_pos); - - draw_cursor (cr, x_origin, y_origin, strong_pos); - if (strong_pos.x != weak_pos.x || - strong_pos.y != weak_pos.y || - strong_pos.width != weak_pos.width || - strong_pos.height != weak_pos.height) - draw_cursor (cr, x_origin, y_origin, weak_pos); - } - } - } - - g_object_unref (layout); - cairo_restore (cr); -} - -/* - * Get the background color - */ -static gchar * -ect_get_bg_color (ECellView *ecell_view, - gint row) -{ - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - gchar *color_spec; - - if (ect->bg_color_column == -1) - return NULL; - - color_spec = e_table_model_value_at ( - ecell_view->e_table_model, - ect->bg_color_column, row); - - return color_spec; -} - -/* - * Selects the entire string - */ - -static void -ect_edit_select_all (ECellTextView *text_view) -{ - g_return_if_fail (text_view->edit); - - text_view->edit->selection_start = 0; - text_view->edit->selection_end = strlen (text_view->edit->text); -} - -static gboolean -key_begins_editing (GdkEventKey *event) -{ - if (event->length == 0) - return FALSE; - - return TRUE; -} - -/* - * ECell::event method - */ -static gint -ect_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - ETextEventProcessorEvent e_tep_event; - gboolean edit_display = FALSE; - gint preedit_len; - CellEdit *edit = text_view->edit; - GtkWidget *canvas = GTK_WIDGET (text_view->canvas); - gint return_val = 0; - d (gboolean press = FALSE); - - if (!(flags & E_CELL_EDITING)) - return 0; - - if (edit && !edit->preedit_length && flags & E_CELL_PREEDIT) - return 1; - - if (edit && edit->view_col == view_col && edit->row == row) { - edit_display = TRUE; - } - - e_tep_event.type = event->type; - switch (event->type) { - case GDK_FOCUS_CHANGE: - break; - case GDK_KEY_PRESS: /* Fall Through */ - if (edit_display) { - edit->show_cursor = FALSE; - } else { - ect_stop_editing (text_view, TRUE); - } - return_val = TRUE; - /* Fallthrough */ - case GDK_KEY_RELEASE: - preedit_len = edit_display ? edit->preedit_length : 0; - if (edit_display && edit->im_context && - gtk_im_context_filter_keypress (\ - edit->im_context, - (GdkEventKey *) event)) { - - edit->need_im_reset = TRUE; - if (preedit_len && flags & E_CELL_PREEDIT) - return 0; - else - return 1; - } - - if (event->key.keyval == GDK_KEY_Escape) { - /* if not changed, then pass this even to parent */ - return_val = text_view->edit != NULL && text_view->edit->text && text_view->edit->old_text && 0 != strcmp (text_view->edit->text, text_view->edit->old_text); - ect_cancel_edit (text_view); - break; - } - - if ((!edit_display) && - e_table_model_is_cell_editable (ecell_view->e_table_model, model_col, row) && - key_begins_editing (&event->key)) { - e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); - ect_edit_select_all (text_view); - edit = text_view->edit; - edit_display = TRUE; - } - if (edit_display) { - GdkEventKey key = event->key; - if (key.type == GDK_KEY_PRESS && - (key.keyval == GDK_KEY_KP_Enter || key.keyval == GDK_KEY_Return)) { - /* stop editing when it's only GDK_KEY_PRESS event */ - e_table_item_leave_edit_ (text_view->cell_view.e_table_item_view); - } else { - e_tep_event.key.time = key.time; - e_tep_event.key.state = key.state; - e_tep_event.key.keyval = key.keyval; - - /* This is probably ugly hack, but we have to handle UTF-8 input somehow */ -#if 0 - e_tep_event.key.length = key.length; - e_tep_event.key.string = key.string; -#else - e_tep_event.key.string = e_utf8_from_gtk_event_key (canvas, key.keyval, key.string); - if (e_tep_event.key.string != NULL) { - e_tep_event.key.length = strlen (e_tep_event.key.string); - } else { - e_tep_event.key.length = 0; - } -#endif - _get_tep (edit); - return_val = e_text_event_processor_handle_event (edit->tep, &e_tep_event); - if (e_tep_event.key.string) - g_free ((gpointer) e_tep_event.key.string); - break; - } - } - - break; - case GDK_BUTTON_PRESS: /* Fall Through */ - d (press = TRUE); - case GDK_BUTTON_RELEASE: - d (g_print ("%s: %s\n", __FUNCTION__, press ? "GDK_BUTTON_PRESS" : "GDK_BUTTON_RELEASE")); - event->button.x -= 4; - event->button.y -= 1; - if ((!edit_display) - && e_table_model_is_cell_editable (ecell_view->e_table_model, model_col, row) - && event->type == GDK_BUTTON_RELEASE - && event->button.button == 1) { - GdkEventButton button = event->button; - - e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); - edit = text_view->edit; - edit_display = TRUE; - - e_tep_event.button.type = GDK_BUTTON_PRESS; - e_tep_event.button.time = button.time; - e_tep_event.button.state = button.state; - e_tep_event.button.button = button.button; - e_tep_event.button.position = get_position_from_xy (edit, event->button.x, event->button.y); - e_tep_event.button.device = - gdk_event_get_device (event); - _get_tep (edit); - edit->actions = 0; - return_val = e_text_event_processor_handle_event ( - edit->tep, &e_tep_event); - *actions = edit->actions; - if (event->button.button == 1) { - if (event->type == GDK_BUTTON_PRESS) - edit->button_down = TRUE; - else - edit->button_down = FALSE; - } - edit->lastx = button.x; - edit->lasty = button.y; - edit->last_state = button.state; - - e_tep_event.button.type = GDK_BUTTON_RELEASE; - } - if (edit_display) { - GdkEventButton button = event->button; - e_tep_event.button.time = button.time; - e_tep_event.button.state = button.state; - e_tep_event.button.button = button.button; - e_tep_event.button.position = get_position_from_xy (edit, event->button.x, event->button.y); - e_tep_event.button.device = - gdk_event_get_device (event); - _get_tep (edit); - edit->actions = 0; - return_val = e_text_event_processor_handle_event ( - edit->tep, &e_tep_event); - *actions = edit->actions; - if (event->button.button == 1) { - if (event->type == GDK_BUTTON_PRESS) - edit->button_down = TRUE; - else - edit->button_down = FALSE; - } - edit->lastx = button.x; - edit->lasty = button.y; - edit->last_state = button.state; - } - break; - case GDK_MOTION_NOTIFY: - event->motion.x -= 4; - event->motion.y -= 1; - if (edit_display) { - GdkEventMotion motion = event->motion; - e_tep_event.motion.time = motion.time; - e_tep_event.motion.state = motion.state; - e_tep_event.motion.position = get_position_from_xy (edit, event->motion.x, event->motion.y); - _get_tep (edit); - edit->actions = 0; - return_val = e_text_event_processor_handle_event ( - edit->tep, &e_tep_event); - *actions = edit->actions; - edit->lastx = motion.x; - edit->lasty = motion.y; - edit->last_state = motion.state; - } - break; - case GDK_ENTER_NOTIFY: -#if 0 - edit->pointer_in = TRUE; -#endif - if (edit_display) { - if (edit->default_cursor_shown) { - GdkWindow *window; - - window = gtk_widget_get_window (canvas); - gdk_window_set_cursor (window, text_view->i_cursor); - edit->default_cursor_shown = FALSE; - } - } - break; - case GDK_LEAVE_NOTIFY: -#if 0 - text_view->pointer_in = FALSE; -#endif - if (edit_display) { - if (!edit->default_cursor_shown) { - GdkWindow *window; - - window = gtk_widget_get_window (canvas); - gdk_window_set_cursor (window, NULL); - edit->default_cursor_shown = TRUE; - } - } - break; - default: - break; - } - - return return_val; -} - -/* - * ECell::height method - */ -static gint -ect_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - gint height; - PangoLayout *layout; - - layout = generate_layout (text_view, model_col, view_col, row, 0); - pango_layout_get_pixel_size (layout, NULL, &height); - g_object_unref (layout); - return height + (get_vertical_spacing (GTK_WIDGET (text_view->canvas)) * 2); -} - -/* - * ECellView::enter_edit method - */ -static gpointer -ect_enter_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - CellEdit *edit; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - gchar *temp; - - edit = g_new0 (CellEdit, 1); - text_view->edit = edit; - - edit->im_context = E_CANVAS (text_view->canvas)->im_context; - edit->need_im_reset = FALSE; - edit->im_context_signals_registered = FALSE; - edit->view_col = -1; - edit->model_col = -1; - edit->row = -1; - - edit->text_view = text_view; - edit->model_col = model_col; - edit->view_col = view_col; - edit->row = row; - edit->cell_width = e_table_header_get_column ( - ((ETableItem *) ecell_view->e_table_item_view)->header, - view_col)->width - 8; - - edit->layout = generate_layout (text_view, model_col, view_col, row, edit->cell_width); - - edit->xofs_edit = 0.0; - edit->yofs_edit = 0.0; - - edit->selection_start = 0; - edit->selection_end = 0; - edit->select_by_word = FALSE; - - edit->timeout_id = g_timeout_add (10, _blink_scroll_timeout, text_view); - edit->timer = g_timer_new (); - g_timer_elapsed (edit->timer, &(edit->scroll_start)); - g_timer_start (edit->timer); - - edit->lastx = 0; - edit->lasty = 0; - edit->last_state = 0; - - edit->scroll_start = 0; - edit->show_cursor = TRUE; - edit->button_down = FALSE; - - edit->tep = NULL; - - edit->has_selection = FALSE; - - edit->pointer_in = FALSE; - edit->default_cursor_shown = TRUE; - - temp = e_cell_text_get_text (ect, ecell_view->e_table_model, model_col, row); - edit->old_text = g_strdup (temp); - e_cell_text_free_text (ect, temp); - edit->text = g_strdup (edit->old_text); - - if (edit->im_context) { - gtk_im_context_reset (edit->im_context); - if (!edit->im_context_signals_registered) { - g_signal_connect ( - edit->im_context, "preedit_changed", - G_CALLBACK (e_cell_text_preedit_changed_cb), - text_view); - g_signal_connect ( - edit->im_context, "commit", - G_CALLBACK (e_cell_text_commit_cb), - text_view); - g_signal_connect ( - edit->im_context, "retrieve_surrounding", - G_CALLBACK (e_cell_text_retrieve_surrounding_cb), - text_view); - g_signal_connect ( - edit->im_context, "delete_surrounding", - G_CALLBACK (e_cell_text_delete_surrounding_cb), - text_view); - - edit->im_context_signals_registered = TRUE; - } - gtk_im_context_focus_in (edit->im_context); - } - -#if 0 - if (edit->pointer_in) { - if (edit->default_cursor_shown) { - gdk_window_set_cursor (GTK_WIDGET (item->canvas)->window, text_view->i_cursor); - edit->default_cursor_shown = FALSE; - } - } -#endif - ect_queue_redraw (text_view, view_col, row); - - return NULL; -} - -/* - * ECellView::leave_edit method - */ -static void -ect_leave_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - CellEdit *edit = text_view->edit; - - if (edit) { - if (edit->im_context) { - gtk_im_context_focus_out (edit->im_context); - - if (edit->im_context_signals_registered) { - g_signal_handlers_disconnect_matched (edit->im_context, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, edit); - edit->im_context_signals_registered = FALSE; - } - } - ect_stop_editing (text_view, TRUE); - } else { - /* - * We did invoke this leave edit internally - */ - } -} - -/* - * ECellView::save_state method - */ -static gpointer -ect_save_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - CellEdit *edit = text_view->edit; - - gint *save_state = g_new (int, 2); - - save_state[0] = edit->selection_start; - save_state[1] = edit->selection_end; - return save_state; -} - -/* - * ECellView::load_state method - */ -static void -ect_load_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context, - gpointer save_state) -{ - ECellTextView *text_view = (ECellTextView *) ecell_view; - CellEdit *edit = text_view->edit; - gint length; - gint *selection = save_state; - - length = strlen (edit->text); - - edit->selection_start = MIN (selection[0], length); - edit->selection_end = MIN (selection[1], length); - - ect_queue_redraw (text_view, view_col, row); -} - -/* - * ECellView::free_state method - */ -static void -ect_free_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer save_state) -{ - g_free (save_state); -} - -static void -get_font_size (PangoLayout *layout, - PangoFontDescription *font, - const gchar *text, - gdouble *width, - gdouble *height) -{ - gint w; - gint h; - - g_return_if_fail (layout != NULL); - pango_layout_set_font_description (layout, font); - pango_layout_set_text (layout, text, -1); - pango_layout_set_width (layout, -1); - pango_layout_set_indent (layout, 0); - - pango_layout_get_size (layout, &w, &h); - - *width = (gdouble)w/(gdouble)PANGO_SCALE; - *height = (gdouble)h/(gdouble)PANGO_SCALE; -} - -static void -ect_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - PangoFontDescription *font_des; - PangoLayout *layout; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - ECellTextView *ectView = (ECellTextView *) ecell_view; - GtkWidget *canvas = GTK_WIDGET (ectView->canvas); - GtkStyle *style; - PangoDirection dir; - gboolean strikeout, underline; - cairo_t *cr; - gchar *string; - gdouble ty, ly, text_width = 0.0, text_height = 0.0; - - cr = gtk_print_context_get_cairo_context (context); - string = e_cell_text_get_text (ect, ecell_view->e_table_model, model_col, row); - - cairo_save (cr); - layout = gtk_print_context_create_pango_layout (context); - font_des = pango_font_description_from_string ("sans 10"); /* fix me font hardcoded */ - pango_layout_set_font_description (layout, font_des); - - pango_layout_set_text (layout, string, -1); - get_font_size (layout, font_des, string, &text_width, &text_height); - - cairo_move_to (cr, 2, 2); - cairo_rectangle (cr, 2, 2, width + 2, height + 2); - cairo_clip (cr); - - style = gtk_widget_get_style (canvas); - pango_context = gtk_widget_get_pango_context (canvas); - font_metrics = pango_context_get_metrics ( - pango_context, style->font_desc, - pango_context_get_language (pango_context)); - ty = (gdouble)(text_height - - pango_font_metrics_get_ascent (font_metrics) - - pango_font_metrics_get_descent (font_metrics)) / 2.0 /(gdouble) PANGO_SCALE; - - strikeout = ect->strikeout_column >= 0 && row >= 0 && - e_table_model_value_at (ecell_view->e_table_model, ect->strikeout_column, row); - underline = ect->underline_column >= 0 && row >= 0 && - e_table_model_value_at (ecell_view->e_table_model, ect->underline_column, row); - - dir = pango_find_base_dir (string, strlen (string)); - - if (underline) { - ly = ty + (gdouble) pango_font_metrics_get_underline_position (font_metrics) / (gdouble) PANGO_SCALE; - cairo_new_path (cr); - if (dir == PANGO_DIRECTION_RTL) { - cairo_move_to (cr, width - 2, ly + text_height + 6); - cairo_line_to (cr, MAX (width - 2 - text_width, 2), ly + text_height + 6); - } - else { - cairo_move_to (cr, 2, ly + text_height + 6); - cairo_line_to (cr, MIN (2 + text_width, width - 2), ly + text_height + 6); - } - cairo_set_line_width (cr, (gdouble) pango_font_metrics_get_underline_thickness (font_metrics) / (gdouble) PANGO_SCALE); - cairo_stroke (cr); - } - - if (strikeout) { - ly = ty + (gdouble) pango_font_metrics_get_strikethrough_position (font_metrics) / (gdouble) PANGO_SCALE; - cairo_new_path (cr); - if (dir == PANGO_DIRECTION_RTL) { - cairo_move_to (cr, width - 2, ly + text_height + 6); - cairo_line_to (cr, MAX (width - 2 - text_width, 2), ly + text_height + 6); - } - else { - cairo_move_to (cr, 2, ly + text_height + 6); - cairo_line_to (cr, MIN (2 + text_width, width - 2), ly + text_height + 6); - } - cairo_set_line_width (cr,(gdouble) pango_font_metrics_get_strikethrough_thickness (font_metrics) / (gdouble) PANGO_SCALE); - - cairo_stroke (cr); - } - - cairo_move_to (cr, 2, text_height- 5); - pango_layout_set_width (layout, (width - 4) * PANGO_SCALE); - pango_layout_set_wrap (layout, PANGO_WRAP_CHAR); - pango_cairo_show_layout (cr, layout); - cairo_restore (cr); - - pango_font_description_free (font_des); - g_object_unref (layout); - e_cell_text_free_text (ect, string); -} - -static gdouble -ect_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - /* - * Font size is 16 by default. To leave some margin for cell - * text area, 2 for footer, 2 for header, actual print height - * should be 16 + 4. - * Height of some special font is much higher than others, - * such as Arabic. So leave some more margin for cell. - */ - PangoFontDescription *font_des; - PangoLayout *layout; - ECellText *ect = E_CELL_TEXT (ecell_view->ecell); - gchar *string; - gdouble text_width = 0.0, text_height = 0.0; - gint lines = 1; - - string = e_cell_text_get_text (ect, ecell_view->e_table_model, model_col, row); - - layout = gtk_print_context_create_pango_layout (context); - font_des = pango_font_description_from_string ("sans 10"); /* fix me font hardcoded */ - pango_layout_set_font_description (layout, font_des); - - pango_layout_set_text (layout, string, -1); - get_font_size (layout, font_des, string, &text_width, &text_height); - /* Checking if the text width goes beyond the column width to increase the - * number of lines. - */ - if (text_width > width - 4) - lines = (text_width / (width - 4)) + 1; - return 16 *lines + 8; -} - -static gint -ect_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - /* New ECellText */ - ECellTextView *text_view = (ECellTextView *) ecell_view; - gint row; - gint number_of_rows; - gint max_width = 0; - - number_of_rows = e_table_model_row_count (ecell_view->e_table_model); - - for (row = 0; row < number_of_rows; row++) { - PangoLayout *layout = generate_layout (text_view, model_col, view_col, row, 0); - gint width; - - pango_layout_get_pixel_size (layout, &width, NULL); - - max_width = MAX (max_width, width); - g_object_unref (layout); - } - - return max_width + 8; -} - -static gint -ect_max_width_by_row (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - /* New ECellText */ - ECellTextView *text_view = (ECellTextView *) ecell_view; - gint width; - PangoLayout *layout; - - if (row >= e_table_model_row_count (ecell_view->e_table_model)) - return 0; - - layout = generate_layout (text_view, model_col, view_col, row, 0); - pango_layout_get_pixel_size (layout, &width, NULL); - g_object_unref (layout); - - return width + 8; -} - -static void -ect_finalize (GObject *object) -{ - ECellText *ect = E_CELL_TEXT (object); - - g_free (ect->font_name); - - G_OBJECT_CLASS (e_cell_text_parent_class)->finalize (object); -} - -/* Set_arg handler for the text item */ -static void -ect_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ECellText *text; - - text = E_CELL_TEXT (object); - - switch (property_id) { - case PROP_STRIKEOUT_COLUMN: - text->strikeout_column = g_value_get_int (value); - break; - - case PROP_UNDERLINE_COLUMN: - text->underline_column = g_value_get_int (value); - break; - - case PROP_BOLD_COLUMN: - text->bold_column = g_value_get_int (value); - break; - - case PROP_COLOR_COLUMN: - text->color_column = g_value_get_int (value); - break; - - case PROP_EDITABLE: - text->editable = g_value_get_boolean (value); - break; - - case PROP_BG_COLOR_COLUMN: - text->bg_color_column = g_value_get_int (value); - break; - - default: - return; - } -} - -/* Get_arg handler for the text item */ -static void -ect_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECellText *text; - - text = E_CELL_TEXT (object); - - switch (property_id) { - case PROP_STRIKEOUT_COLUMN: - g_value_set_int (value, text->strikeout_column); - break; - - case PROP_UNDERLINE_COLUMN: - g_value_set_int (value, text->underline_column); - break; - - case PROP_BOLD_COLUMN: - g_value_set_int (value, text->bold_column); - break; - - case PROP_COLOR_COLUMN: - g_value_set_int (value, text->color_column); - break; - - case PROP_EDITABLE: - g_value_set_boolean (value, text->editable); - break; - - case PROP_BG_COLOR_COLUMN: - g_value_set_int (value, text->bg_color_column); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gchar *ellipsis_default = NULL; -static gboolean use_ellipsis_default = TRUE; - -static void -e_cell_text_class_init (ECellTextClass *class) -{ - ECellClass *ecc = E_CELL_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - const gchar *ellipsis_env; - - object_class->finalize = ect_finalize; - - ecc->new_view = ect_new_view; - ecc->kill_view = ect_kill_view; - ecc->realize = ect_realize; - ecc->unrealize = ect_unrealize; - ecc->draw = ect_draw; - ecc->event = ect_event; - ecc->height = ect_height; - ecc->enter_edit = ect_enter_edit; - ecc->leave_edit = ect_leave_edit; - ecc->save_state = ect_save_state; - ecc->load_state = ect_load_state; - ecc->free_state = ect_free_state; - ecc->print = ect_print; - ecc->print_height = ect_print_height; - ecc->max_width = ect_max_width; - ecc->max_width_by_row = ect_max_width_by_row; - ecc->get_bg_color = ect_get_bg_color; - - class->get_text = ect_real_get_text; - class->free_text = ect_real_free_text; - class->set_value = ect_real_set_value; - - object_class->get_property = ect_get_property; - object_class->set_property = ect_set_property; - - signals[TEXT_INSERTED] = g_signal_new ( - "text_inserted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ECellTextClass, text_inserted), - NULL, NULL, - e_marshal_VOID__POINTER_INT_INT_INT_INT, - G_TYPE_NONE, 5, - G_TYPE_POINTER, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - signals[TEXT_DELETED] = g_signal_new ( - "text_deleted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ECellTextClass, text_deleted), - NULL, NULL, - e_marshal_VOID__POINTER_INT_INT_INT_INT, - G_TYPE_NONE, 5, - G_TYPE_POINTER, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - g_object_class_install_property ( - object_class, - PROP_STRIKEOUT_COLUMN, - g_param_spec_int ( - "strikeout_column", - "Strikeout Column", - NULL, - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UNDERLINE_COLUMN, - g_param_spec_int ( - "underline_column", - "Underline Column", - NULL, - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_BOLD_COLUMN, - g_param_spec_int ( - "bold_column", - "Bold Column", - NULL, - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_COLOR_COLUMN, - g_param_spec_int ( - "color_column", - "Color Column", - NULL, - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_BG_COLOR_COLUMN, - g_param_spec_int ( - "bg_color_column", - "BG Color Column", - NULL, - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - - ellipsis_env = g_getenv ("GAL_ELLIPSIS"); - if (ellipsis_env) { - if (*ellipsis_env) { - ellipsis_default = g_strdup (ellipsis_env); - } else { - use_ellipsis_default = FALSE; - } - } -} - -/* IM Context Callbacks */ - -static void -e_cell_text_get_cursor_locations (ECellTextView *tv, - GdkRectangle *strong_pos, - GdkRectangle *weak_pos) -{ - GdkRectangle area; - CellEdit *edit = tv->edit; - ECellView *cell_view = (ECellView *) tv; - ETableItem *item = E_TABLE_ITEM ((cell_view)->e_table_item_view); - GnomeCanvasItem *parent_item = GNOME_CANVAS_ITEM (item)->parent; - PangoRectangle pango_strong_pos; - PangoRectangle pango_weak_pos; - gint x, y, col, row; - gdouble x1,y1; - gint cx, cy; - gint index; - - row = edit->row; - col = edit->view_col; - - e_table_item_get_cell_geometry ( - item, &row, &col, &x, &y, NULL, &area.height); - - gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (parent_item), &x1, &y1, NULL, NULL); - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (GNOME_CANVAS_ITEM (parent_item)->canvas), &cx, &cy); - - index = edit->selection_end + edit->preedit_pos; - - pango_layout_get_cursor_pos ( - edit->layout, - index, - strong_pos ? &pango_strong_pos : NULL, - weak_pos ? &pango_weak_pos : NULL); - - if (strong_pos) { - strong_pos->x = x + x1 - cx - edit->xofs_edit + pango_strong_pos.x / PANGO_SCALE; - strong_pos->y = y + y1 - cy - edit->yofs_edit + pango_strong_pos.y / PANGO_SCALE; - strong_pos->width = 0; - strong_pos->height = pango_strong_pos.height / PANGO_SCALE; - } - - if (weak_pos) { - weak_pos->x = x + x1 - cx - edit->xofs_edit + pango_weak_pos.x / PANGO_SCALE; - weak_pos->y = y + y1 - cy - edit->yofs_edit + pango_weak_pos.y / PANGO_SCALE; - weak_pos->width = 0; - weak_pos->height = pango_weak_pos.height / PANGO_SCALE; - } -} - -static void -update_im_cursor_location (ECellTextView *tv) -{ - CellEdit *edit = tv->edit; - GdkRectangle area; - - e_cell_text_get_cursor_locations (tv, &area, NULL); - - gtk_im_context_set_cursor_location (edit->im_context, &area); -} - -static void -e_cell_text_preedit_changed_cb (GtkIMContext *context, - ECellTextView *tv) -{ - gchar *preedit_string; - gint cursor_pos; - CellEdit *edit = tv->edit; - gtk_im_context_get_preedit_string ( - edit->im_context, &preedit_string, - NULL, &cursor_pos); - - edit->preedit_length = strlen (preedit_string); - cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); - edit->preedit_pos = g_utf8_offset_to_pointer (preedit_string, cursor_pos) - preedit_string; - g_free (preedit_string); - - ect_queue_redraw (tv, edit->view_col, edit->row); -} - -static void -e_cell_text_commit_cb (GtkIMContext *context, - const gchar *str, - ECellTextView *tv) -{ - CellEdit *edit = tv->edit; - ETextEventProcessorCommand command = { 0 }; - - if (g_utf8_validate (str, strlen (str), NULL)) { - command.action = E_TEP_INSERT; - command.position = E_TEP_SELECTION; - command.string = (gchar *) str; - command.value = strlen (str); - e_cell_text_view_command (edit->tep, &command, edit); - } - -} - -static gboolean -e_cell_text_retrieve_surrounding_cb (GtkIMContext *context, - ECellTextView *tv) -{ - CellEdit *edit = tv->edit; - - gtk_im_context_set_surrounding ( - context, - edit->text, - strlen (edit->text), - MIN (edit->selection_start, edit->selection_end)); - - return TRUE; -} - -static gboolean -e_cell_text_delete_surrounding_cb (GtkIMContext *context, - gint offset, - gint n_chars, - ECellTextView *tv) -{ - gint begin_pos, end_pos; - glong text_len; - CellEdit *edit = tv->edit; - - text_len = g_utf8_strlen (edit->text, -1); - begin_pos = g_utf8_pointer_to_offset ( - edit->text, - edit->text + MIN (edit->selection_start, edit->selection_end)); - begin_pos += offset; - end_pos = begin_pos + n_chars; - if (begin_pos < 0 || text_len < begin_pos) - return FALSE; - if (end_pos > text_len) - end_pos = text_len; - edit->selection_start = g_utf8_offset_to_pointer (edit->text, begin_pos) - - edit->text; - edit->selection_end = g_utf8_offset_to_pointer (edit->text, end_pos) - - edit->text; - - _delete_selection (tv); - - return TRUE; -} - -static void -e_cell_text_init (ECellText *ect) -{ - ect->ellipsis = g_strdup (ellipsis_default); - ect->use_ellipsis = use_ellipsis_default; - ect->strikeout_column = -1; - ect->underline_column = -1; - ect->bold_column = -1; - ect->color_column = -1; - ect->bg_color_column = -1; - ect->editable = TRUE; -} - -/** - * e_cell_text_new: - * @fontname: this param is no longer used, but left here for api stability - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render strings that - * that come from the model. The value returned from the model is - * interpreted as being a gchar *. - * - * The ECellText object support a large set of properties that can be - * configured through the Gtk argument system and allows the user to have - * a finer control of the way the string is displayed. The arguments supported - * allow the control of strikeout, underline, bold, and color. - * - * The arguments "strikeout_column", "underline_column", "bold_column" - * and "color_column" set and return an integer that points to a - * column in the model that controls these settings. So controlling - * the way things are rendered is achieved by having special columns - * in the model that will be used to flag whether the text should be - * rendered with strikeout, or bolded. In the case of the - * "color_column" argument, the column in the model is expected to - * have a string that can be parsed by gdk_color_parse(). - * - * Returns: an ECell object that can be used to render strings. - */ -ECell * -e_cell_text_new (const gchar *fontname, - GtkJustification justify) -{ - ECellText *ect = g_object_new (E_TYPE_CELL_TEXT, NULL); - - e_cell_text_construct (ect, fontname, justify); - - return (ECell *) ect; -} - -/** - * e_cell_text_construct: - * @cell: The cell to construct - * @fontname: this param is no longer used, but left here for api stability - * @justify: Justification of the string in the cell - * - * constructs the ECellText. To be used by subclasses and language - * bindings. - * - * Returns: The ECellText. - */ -ECell * -e_cell_text_construct (ECellText *cell, - const gchar *fontname, - GtkJustification justify) -{ - if (!cell) - return E_CELL (NULL); - if (fontname) - cell->font_name = g_strdup (fontname); - cell->justify = justify; - return E_CELL (cell); -} - -gchar * -e_cell_text_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row) -{ - ECellTextClass *class; - - g_return_val_if_fail (E_IS_CELL_TEXT (cell), NULL); - - class = E_CELL_TEXT_GET_CLASS (cell); - if (class->get_text == NULL) - return NULL; - - return class->get_text (cell, model, col, row); -} - -void -e_cell_text_free_text (ECellText *cell, - gchar *text) -{ - ECellTextClass *class; - - g_return_if_fail (E_IS_CELL_TEXT (cell)); - - class = E_CELL_TEXT_GET_CLASS (cell); - if (class->free_text == NULL) - return; - - class->free_text (cell, text); -} - -void -e_cell_text_set_value (ECellText *cell, - ETableModel *model, - gint col, - gint row, - const gchar *text) -{ - ECellTextClass *class; - - g_return_if_fail (E_IS_CELL_TEXT (cell)); - - class = E_CELL_TEXT_GET_CLASS (cell); - if (class->set_value == NULL) - return; - - class->set_value (cell, model, col, row, text); -} - -/* fixme: Handle Font attributes */ -/* position is in BYTES */ - -static gint -get_position_from_xy (CellEdit *edit, - gint x, - gint y) -{ - gint index; - gint trailing; - const gchar *text; - - PangoLayout *layout = generate_layout (edit->text_view, edit->model_col, edit->view_col, edit->row, edit->cell_width); - ECellTextView *text_view = edit->text_view; - ECellText *ect = (ECellText *) ((ECellView *) text_view)->ecell; - - x -= (ect->x + text_view->xofs - edit->xofs_edit); - y -= (ect->y + text_view->yofs - edit->yofs_edit); - - pango_layout_xy_to_index (layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); - - text = pango_layout_get_text (layout); - - return g_utf8_offset_to_pointer (text + index, trailing) - text; -} - -#define SCROLL_WAIT_TIME 30000 - -static gboolean -_blink_scroll_timeout (gpointer data) -{ - ECellTextView *text_view = (ECellTextView *) data; - ECellText *ect = E_CELL_TEXT (((ECellView *) text_view)->ecell); - CellEdit *edit = text_view->edit; - - gulong current_time; - gboolean scroll = FALSE; - gboolean redraw = FALSE; - gint width, height; - - g_timer_elapsed (edit->timer, ¤t_time); - - if (edit->scroll_start + SCROLL_WAIT_TIME > 1000000) { - if (current_time > edit->scroll_start - (1000000 - SCROLL_WAIT_TIME) && - current_time < edit->scroll_start) - scroll = TRUE; - } else { - if (current_time > edit->scroll_start + SCROLL_WAIT_TIME || - current_time < edit->scroll_start) - scroll = TRUE; - } - - pango_layout_get_pixel_size (edit->layout, &width, &height); - - if (scroll && edit->button_down) { - /* FIXME: Copy this for y. */ - if (edit->lastx - ect->x > edit->cell_width) { - if (edit->xofs_edit < width - edit->cell_width) { - edit->xofs_edit += 4; - if (edit->xofs_edit > width - edit->cell_width + 1) - edit->xofs_edit = width - edit->cell_width + 1; - redraw = TRUE; - } - } - if (edit->lastx - ect->x < 0 && - edit->xofs_edit > 0) { - edit->xofs_edit -= 4; - if (edit->xofs_edit < 0) - edit->xofs_edit = 0; - redraw = TRUE; - } - if (redraw) { - ETextEventProcessorEvent e_tep_event; - e_tep_event.type = GDK_MOTION_NOTIFY; - e_tep_event.motion.state = edit->last_state; - e_tep_event.motion.time = 0; - e_tep_event.motion.position = get_position_from_xy (edit, edit->lastx, edit->lasty); - _get_tep (edit); - e_text_event_processor_handle_event ( - edit->tep, - &e_tep_event); - edit->scroll_start = current_time; - } - } - - if (!((current_time / 500000) % 2)) { - if (!edit->show_cursor) - redraw = TRUE; - edit->show_cursor = TRUE; - } else { - if (edit->show_cursor) - redraw = TRUE; - edit->show_cursor = FALSE; - } - if (redraw) { - ect_queue_redraw (text_view, edit->view_col, edit->row); - } - return TRUE; -} - -static gint -next_word (CellEdit *edit, - gint start) -{ - gchar *p; - gint length; - - length = strlen (edit->text); - if (start >= length) - return length; - - p = g_utf8_next_char (edit->text + start); - - while (*p && g_unichar_validate (g_utf8_get_char (p))) { - gunichar unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) - return p - edit->text; - p = g_utf8_next_char (p); - } - - return p - edit->text; -} - -static gint -_get_position (ECellTextView *text_view, - ETextEventProcessorCommand *command) -{ - gint length; - CellEdit *edit = text_view->edit; - gchar *p; - gint unival; - gint index; - gint trailing; - - switch (command->position) { - - case E_TEP_VALUE: - return command->value; - - case E_TEP_SELECTION: - return edit->selection_end; - - case E_TEP_START_OF_BUFFER: - return 0; - - /* fixme: this probably confuses TEP */ - - case E_TEP_END_OF_BUFFER: - return strlen (edit->text); - - case E_TEP_START_OF_LINE: - - if (edit->selection_end < 1) return 0; - - p = g_utf8_find_prev_char (edit->text, edit->text + edit->selection_end); - - if (p == edit->text) return 0; - - p = g_utf8_find_prev_char (edit->text, p); - - while (p && p > edit->text) { - if (*p == '\n') return p - edit->text + 1; - p = g_utf8_find_prev_char (edit->text, p); - } - - return 0; - - case E_TEP_END_OF_LINE: - - length = strlen (edit->text); - if (edit->selection_end >= length) return length; - - p = g_utf8_next_char (edit->text + edit->selection_end); - - while (*p && g_unichar_validate (g_utf8_get_char (p))) { - if (*p == '\n') return p - edit->text; - p = g_utf8_next_char (p); - } - - return p - edit->text; - - case E_TEP_FORWARD_CHARACTER: - - length = strlen (edit->text); - if (edit->selection_end >= length) return length; - - p = g_utf8_next_char (edit->text + edit->selection_end); - - return p - edit->text; - - case E_TEP_BACKWARD_CHARACTER: - - if (edit->selection_end < 1) return 0; - - p = g_utf8_find_prev_char (edit->text, edit->text + edit->selection_end); - - if (p == NULL) return 0; - - return p - edit->text; - - case E_TEP_FORWARD_WORD: - return next_word (edit, edit->selection_end); - - case E_TEP_BACKWARD_WORD: - - if (edit->selection_end < 1) return 0; - - p = g_utf8_find_prev_char (edit->text, edit->text + edit->selection_end); - - if (p == edit->text) return 0; - - p = g_utf8_find_prev_char (edit->text, p); - - while (p && p > edit->text && g_unichar_validate (g_utf8_get_char (p))) { - unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - return (g_utf8_next_char (p) - edit->text); - } - p = g_utf8_find_prev_char (edit->text, p); - } - - return 0; - - case E_TEP_FORWARD_LINE: - pango_layout_move_cursor_visually ( - edit->layout, - TRUE, - edit->selection_end, - 0, - TRUE, - &index, - &trailing); - index = g_utf8_offset_to_pointer (edit->text + index, trailing) - edit->text; - if (index < 0) - return 0; - length = strlen (edit->text); - if (index >= length) - return length; - return index; - case E_TEP_BACKWARD_LINE: - pango_layout_move_cursor_visually ( - edit->layout, - TRUE, - edit->selection_end, - 0, - TRUE, - &index, - &trailing); - - index = g_utf8_offset_to_pointer (edit->text + index, trailing) - edit->text; - if (index < 0) - return 0; - length = strlen (edit->text); - if (index >= length) - return length; - return index; - case E_TEP_FORWARD_PARAGRAPH: - case E_TEP_BACKWARD_PARAGRAPH: - - case E_TEP_FORWARD_PAGE: - case E_TEP_BACKWARD_PAGE: - return edit->selection_end; - default: - return edit->selection_end; - } - - g_return_val_if_reached (0); - - return 0; /* Kill warning */ -} - -static void -_delete_selection (ECellTextView *text_view) -{ - CellEdit *edit = text_view->edit; - gint length; - gchar *sp, *ep; - - if (edit->selection_end == edit->selection_start) return; - - if (edit->selection_end < edit->selection_start) { - edit->selection_end ^= edit->selection_start; - edit->selection_start ^= edit->selection_end; - edit->selection_end ^= edit->selection_start; - } - - sp = edit->text + edit->selection_start; - ep = edit->text + edit->selection_end; - length = strlen (ep) + 1; - - memmove (sp, ep, length); - - edit->selection_end = edit->selection_start; - - g_signal_emit (VIEW_TO_CELL (text_view), signals[TEXT_DELETED], 0, text_view, edit->selection_start, ep - sp, edit->row, edit->model_col); -} - -/* fixme: */ -/* NB! We expect value to be length IN BYTES */ - -static void -_insert (ECellTextView *text_view, - const gchar *string, - gint value) -{ - CellEdit *edit = text_view->edit; - gchar *temp; - - if (value <= 0) return; - - edit->selection_start = MIN (strlen (edit->text), edit->selection_start); - - temp = g_new (gchar, strlen (edit->text) + value + 1); - - strncpy (temp, edit->text, edit->selection_start); - strncpy (temp + edit->selection_start, string, value); - strcpy (temp + edit->selection_start + value, edit->text + edit->selection_end); - - g_free (edit->text); - - edit->text = temp; - - edit->selection_start += value; - edit->selection_end = edit->selection_start; - - g_signal_emit (VIEW_TO_CELL (text_view), signals[TEXT_INSERTED], 0, text_view, edit->selection_end - value, value, edit->row, edit->model_col); -} - -static void -capitalize (CellEdit *edit, - gint start, - gint end, - ETextEventProcessorCaps type) -{ - ECellTextView *text_view = edit->text_view; - - gboolean first = TRUE; - gint character_length = g_utf8_strlen (edit->text + start, start - end); - const gchar *p = edit->text + start; - const gchar *text_end = edit->text + end; - gchar *new_text = g_new0 (char, character_length * 6 + 1); - gchar *output = new_text; - - while (p && *p && p < text_end && g_unichar_validate (g_utf8_get_char (p))) { - gunichar unival = g_utf8_get_char (p); - gunichar newval = unival; - - switch (type) { - case E_TEP_CAPS_UPPER: - newval = g_unichar_toupper (unival); - break; - case E_TEP_CAPS_LOWER: - newval = g_unichar_tolower (unival); - break; - case E_TEP_CAPS_TITLE: - if (g_unichar_isalpha (unival)) { - if (first) - newval = g_unichar_totitle (unival); - else - newval = g_unichar_tolower (unival); - first = FALSE; - } else { - first = TRUE; - } - break; - } - g_unichar_to_utf8 (newval, output); - output = g_utf8_next_char (output); - - p = g_utf8_next_char (p); - } - *output = 0; - - edit->selection_end = end; - edit->selection_start = start; - _delete_selection (text_view); - - _insert (text_view, new_text, output - new_text); - - g_free (new_text); -} - -static void -e_cell_text_view_command (ETextEventProcessor *tep, - ETextEventProcessorCommand *command, - gpointer data) -{ - CellEdit *edit = (CellEdit *) data; - ECellTextView *text_view = edit->text_view; - ECellText *ect = E_CELL_TEXT (text_view->cell_view.ecell); - - gboolean change = FALSE; - gboolean redraw = FALSE; - - gint sel_start, sel_end; - - /* If the EText isn't editable, then ignore any commands that would - * modify the text. */ - if (!ect->editable && (command->action == E_TEP_DELETE - || command->action == E_TEP_INSERT - || command->action == E_TEP_PASTE - || command->action == E_TEP_GET_SELECTION)) - return; - - switch (command->action) { - case E_TEP_MOVE: - edit->selection_start = _get_position (text_view, command); - edit->selection_end = edit->selection_start; - if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - break; - case E_TEP_SELECT: - edit->selection_end = _get_position (text_view, command); - sel_start = MIN (edit->selection_start, edit->selection_end); - sel_end = MAX (edit->selection_start, edit->selection_end); - if (sel_start != sel_end) { - e_cell_text_view_supply_selection ( - edit, command->time, GDK_SELECTION_PRIMARY, - edit->text + sel_start, - sel_end - sel_start); - } else if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - break; - case E_TEP_DELETE: - if (edit->selection_end == edit->selection_start) { - edit->selection_end = _get_position (text_view, command); - } - _delete_selection (text_view); - if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - change = TRUE; - break; - - case E_TEP_INSERT: - if (!edit->preedit_length && edit->selection_end != edit->selection_start) { - _delete_selection (text_view); - } - _insert (text_view, command->string, command->value); - if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - change = TRUE; - break; - case E_TEP_COPY: - sel_start = MIN (edit->selection_start, edit->selection_end); - sel_end = MAX (edit->selection_start, edit->selection_end); - if (sel_start != sel_end) { - e_cell_text_view_supply_selection ( - edit, command->time, clipboard_atom, - edit->text + sel_start, - sel_end - sel_start); - } - if (edit->timer) { - g_timer_reset (edit->timer); - } - break; - case E_TEP_PASTE: - e_cell_text_view_get_selection (edit, clipboard_atom, command->time); - if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - change = TRUE; - break; - case E_TEP_GET_SELECTION: - e_cell_text_view_get_selection (edit, GDK_SELECTION_PRIMARY, command->time); - break; - case E_TEP_ACTIVATE: - e_table_item_leave_edit_ (text_view->cell_view.e_table_item_view); - break; - case E_TEP_SET_SELECT_BY_WORD: - edit->select_by_word = command->value; - break; - case E_TEP_GRAB: - edit->actions = E_CELL_GRAB; - break; - case E_TEP_UNGRAB: - edit->actions = E_CELL_UNGRAB; - break; - case E_TEP_CAPS: - if (edit->selection_start == edit->selection_end) { - capitalize (edit, edit->selection_start, next_word (edit, edit->selection_start), command->value); - } else { - gint selection_start = MIN (edit->selection_start, edit->selection_end); - gint selection_end = edit->selection_start + edit->selection_end - selection_start; /* Slightly faster than MAX */ - capitalize (edit, selection_start, selection_end, command->value); - } - if (edit->timer) { - g_timer_reset (edit->timer); - } - redraw = TRUE; - change = TRUE; - break; - case E_TEP_NOP: - break; - } - - if (change) { - if (edit->layout) - g_object_unref (edit->layout); - edit->layout = build_layout (text_view, edit->row, edit->text, edit->cell_width); - } - - if (!edit->button_down) { - PangoRectangle strong_pos, weak_pos; - pango_layout_get_cursor_pos (edit->layout, edit->selection_end, &strong_pos, &weak_pos); - if (strong_pos.x != weak_pos.x || - strong_pos.y != weak_pos.y || - strong_pos.width != weak_pos.width || - strong_pos.height != weak_pos.height) { - if (show_pango_rectangle (edit, weak_pos)) - redraw = TRUE; - } - if (show_pango_rectangle (edit, strong_pos)) { - redraw = TRUE; - } - } - - if (redraw) { - ect_queue_redraw (text_view, edit->view_col, edit->row); - } -} - -static void -e_cell_text_view_supply_selection (CellEdit *edit, - guint time, - GdkAtom selection, - gchar *data, - gint length) -{ -#if DO_SELECTION - GtkClipboard *clipboard; - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (edit->text_view->canvas), selection); - - if (selection == GDK_SELECTION_PRIMARY) { - edit->has_selection = TRUE; - } - - gtk_clipboard_set_text (clipboard, data, length); -#endif -} - -#ifdef DO_SELECTION -static void -paste_received (GtkClipboard *clipboard, - const gchar *text, - gpointer data) -{ - CellEdit *edit; - - g_return_if_fail (data); - - edit = (CellEdit *) data; - - if (text && g_utf8_validate (text, strlen (text), NULL)) { - ETextEventProcessorCommand command = { 0 }; - command.action = E_TEP_INSERT; - command.position = E_TEP_SELECTION; - command.string = (gchar *) text; - command.value = strlen (text); - command.time = GDK_CURRENT_TIME; - e_cell_text_view_command (edit->tep, &command, edit); - } -} -#endif - -static void -e_cell_text_view_get_selection (CellEdit *edit, - GdkAtom selection, - guint32 time) -{ -#if DO_SELECTION - gtk_clipboard_request_text ( - gtk_widget_get_clipboard (GTK_WIDGET (edit->text_view->canvas), - selection), - paste_received, edit); -#endif -} - -static void -_get_tep (CellEdit *edit) -{ - if (!edit->tep) { - edit->tep = e_text_event_processor_emacs_like_new (); - g_signal_connect ( - edit->tep, "command", - G_CALLBACK (e_cell_text_view_command), edit); - } -} - -/** - * e_cell_text_set_selection: - * @cell_view: the given cell view - * @col: column of the given cell in the view - * @row: row of the given cell in the view - * @start: start offset of the selection - * @end: end offset of the selection - * - * Sets the selection of given text cell. - * If the current editing cell is not the given cell, this function - * will return FALSE; - * - * If success, the [start, end) part of the text will be selected. - * - * This API is most likely to be used by a11y implementations. - * - * Returns: whether the action is successful. - */ -gboolean -e_cell_text_set_selection (ECellView *cell_view, - gint col, - gint row, - gint start, - gint end) -{ - ECellTextView *ectv; - CellEdit *edit; - ETextEventProcessorCommand command1 = { 0 }, command2 = { 0 }; - - g_return_val_if_fail (cell_view != NULL, FALSE); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - if (!edit) - return FALSE; - - if (edit->view_col != col || edit->row != row) - return FALSE; - - command1.action = E_TEP_MOVE; - command1.position = E_TEP_VALUE; - command1.value = start; - e_cell_text_view_command (edit->tep, &command1, edit); - - command2.action = E_TEP_SELECT; - command2.position = E_TEP_VALUE; - command2.value = end; - e_cell_text_view_command (edit->tep, &command2, edit); - - return TRUE; -} - -/** - * e_cell_text_get_selection: - * @cell_view: the given cell view - * @col: column of the given cell in the view - * @row: row of the given cell in the view - * @start: a pointer to an gint value indicates the start offset of the selection - * @end: a pointer to an gint value indicates the end offset of the selection - * - * Gets the selection of given text cell. - * If the current editing cell is not the given cell, this function - * will return FALSE; - * - * This API is most likely to be used by a11y implementations. - * - * Returns: whether the action is successful. - */ -gboolean -e_cell_text_get_selection (ECellView *cell_view, - gint col, - gint row, - gint *start, - gint *end) -{ - ECellTextView *ectv; - CellEdit *edit; - - g_return_val_if_fail (cell_view != NULL, FALSE); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - if (!edit) - return FALSE; - - if (edit->view_col != col || edit->row != row) - return FALSE; - - if (start) - *start = edit->selection_start; - if (end) - *end = edit->selection_end; - return TRUE; -} - -/** - * e_cell_text_copy_clipboard: - * @cell_view: the given cell view - * @col: column of the given cell in the view - * @row: row of the given cell in the view - * - * Copys the selected text to clipboard. - * - * This API is most likely to be used by a11y implementations. - */ -void -e_cell_text_copy_clipboard (ECellView *cell_view, - gint col, - gint row) -{ - ECellTextView *ectv; - CellEdit *edit; - ETextEventProcessorCommand command = { 0 }; - - g_return_if_fail (cell_view != NULL); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - if (!edit) - return; - - if (edit->view_col != col || edit->row != row) - return; - - command.action = E_TEP_COPY; - command.time = GDK_CURRENT_TIME; - e_cell_text_view_command (edit->tep, &command, edit); -} - -/** - * e_cell_text_paste_clipboard: - * @cell_view: the given cell view - * @col: column of the given cell in the view - * @row: row of the given cell in the view - * - * Pastes the text from the clipboardt. - * - * This API is most likely to be used by a11y implementations. - */ -void -e_cell_text_paste_clipboard (ECellView *cell_view, - gint col, - gint row) -{ - ECellTextView *ectv; - CellEdit *edit; - ETextEventProcessorCommand command = { 0 }; - - g_return_if_fail (cell_view != NULL); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - if (!edit) - return; - - if (edit->view_col != col || edit->row != row) - return; - - command.action = E_TEP_PASTE; - command.time = GDK_CURRENT_TIME; - e_cell_text_view_command (edit->tep, &command, edit); -} - -/** - * e_cell_text_delete_selection: - * @cell_view: the given cell view - * @col: column of the given cell in the view - * @row: row of the given cell in the view - * - * Deletes the selected text of the cell. - * - * This API is most likely to be used by a11y implementations. - */ -void -e_cell_text_delete_selection (ECellView *cell_view, - gint col, - gint row) -{ - ECellTextView *ectv; - CellEdit *edit; - ETextEventProcessorCommand command = { 0 }; - - g_return_if_fail (cell_view != NULL); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - if (!edit) - return; - - if (edit->view_col != col || edit->row != row) - return; - - command.action = E_TEP_DELETE; - command.position = E_TEP_SELECTION; - e_cell_text_view_command (edit->tep, &command, edit); -} - -/** - * e_cell_text_get_text_by_view: - * @cell_view: the given cell view - * @col: column of the given cell in the model - * @row: row of the given cell in the model - * - * Get the cell's text directly from CellEdit, - * during editting this cell, the cell's text value maybe inconsistant - * with the text got from table_model. - * The caller should free the text after using it. - * - * This API is most likely to be used by a11y implementations. - */ -gchar * -e_cell_text_get_text_by_view (ECellView *cell_view, - gint col, - gint row) -{ - ECellTextView *ectv; - CellEdit *edit; - gchar *ret, *model_text; - - g_return_val_if_fail (cell_view != NULL, NULL); - - ectv = (ECellTextView *) cell_view; - edit = ectv->edit; - - if (edit && ectv->edit->row == row && ectv->edit->model_col == col) { /* being editted now */ - ret = g_strdup (edit->text); - } else{ - model_text = e_cell_text_get_text ( - E_CELL_TEXT (cell_view->ecell), - cell_view->e_table_model, col, row); - ret = g_strdup (model_text); - e_cell_text_free_text (E_CELL_TEXT (cell_view->ecell), model_text); - } - - return ret; - -} diff --git a/widgets/table/e-cell-text.h b/widgets/table/e-cell-text.h deleted file mode 100644 index 850d0caf29..0000000000 --- a/widgets/table/e-cell-text.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Text cell renderer. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * A lot of code taken from: - * - * Text item type for GnomeCanvas widget - * - * GnomeCanvas is basically a port of the Tk toolkit's most excellent - * canvas widget. Tk is copyrighted by the Regents of the University - * of California, Sun Microsystems, and other parties. - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - * - */ - -#ifndef E_CELL_TEXT_H -#define E_CELL_TEXT_H - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_TEXT \ - (e_cell_text_get_type ()) -#define E_CELL_TEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_TEXT, ECellText)) -#define E_CELL_TEXT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_TEXT, ECellTextClass)) -#define E_IS_CELL_TEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_TEXT)) -#define E_IS_CELL_TEXT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_TEXT)) -#define E_CELL_TEXT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_TEXT, ECellTextClass)) - -G_BEGIN_DECLS - -typedef struct _ECellText ECellText; -typedef struct _ECellTextClass ECellTextClass; - -struct _ECellText { - ECell parent; - - GtkJustification justify; - gchar *font_name; - - gdouble x, y; /* Position at anchor */ - - gulong pixel; /* Fill color */ - - /* Clip handling */ - gchar *ellipsis; /* The ellipsis characters. NULL = "...". */ - - guint use_ellipsis : 1; /* Whether to use the ellipsis. */ - guint editable : 1; /* Whether the text can be edited. */ - - gint strikeout_column; - gint underline_column; - gint bold_column; - - /* This column in the ETable should return a string specifying a color, - * either a color name like "red" or a color spec like "rgb:F/0/0". - * See the XParseColor man page for the formats available. */ - gint color_column; - gint bg_color_column; -}; - -struct _ECellTextClass { - ECellClass parent_class; - - /* Methods */ - gchar * (*get_text) (ECellText *cell, - ETableModel *model, - gint col, - gint row); - void (*free_text) (ECellText *cell, - gchar *text); - void (*set_value) (ECellText *cell, - ETableModel *model, - gint col, - gint row, - const gchar *text); - - /* Signals */ - void (*text_inserted) (ECellText *cell, - ECellView *cell_view, - gint pos, - gint len, - gint row, - gint model_col); - void (*text_deleted) (ECellText *cell, - ECellView *cell_view, - gint pos, - gint len, - gint row, - gint model_col); -}; - -GType e_cell_text_get_type (void) G_GNUC_CONST; -ECell * e_cell_text_new (const gchar *fontname, - GtkJustification justify); -ECell * e_cell_text_construct (ECellText *cell, - const gchar *fontname, - GtkJustification justify); - -/* Gets the value from the model and converts it into a string. In ECellText - * itself, the value is assumed to be a gchar * and so needs no conversion. - * In subclasses the ETableModel value may be a more complicated datatype. */ -gchar * e_cell_text_get_text (ECellText *cell, - ETableModel *model, - gint col, - gint row); - -/* Frees the value returned by e_cell_text_get_text(). */ -void e_cell_text_free_text (ECellText *cell, - gchar *text); - -/* Sets the ETableModel value, based on the given string. */ -void e_cell_text_set_value (ECellText *cell, - ETableModel *model, - gint col, - gint row, - const gchar *text); - -/* Sets the selection of given text cell */ -gboolean e_cell_text_set_selection (ECellView *cell_view, - gint col, - gint row, - gint start, - gint end); - -/* Gets the selection of given text cell */ -gboolean e_cell_text_get_selection (ECellView *cell_view, - gint col, - gint row, - gint *start, - gint *end); - -/* Copys the selected text to the clipboard */ -void e_cell_text_copy_clipboard (ECellView *cell_view, - gint col, - gint row); - -/* Pastes the text from the clipboard */ -void e_cell_text_paste_clipboard (ECellView *cell_view, - gint col, - gint row); - -/* Deletes selected text */ -void e_cell_text_delete_selection (ECellView *cell_view, - gint col, - gint row); - -/* get text directly from view, both col and row are model format */ -gchar * e_cell_text_get_text_by_view (ECellView *cell_view, - gint col, - gint row); - -G_END_DECLS - -#endif /* E_CELL_TEXT_H */ - diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c deleted file mode 100644 index f4de9d6922..0000000000 --- a/widgets/table/e-cell-toggle.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * e-cell-toggle.c - Multi-state image toggle cell object. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "art/empty.xpm" - -#include "gal-a11y-e-cell-toggle.h" -#include "gal-a11y-e-cell-registry.h" -#include "e-util/e-util.h" - -#include "e-cell-toggle.h" -#include "e-table-item.h" - -#define E_CELL_TOGGLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CELL_TOGGLE, ECellTogglePrivate)) - -struct _ECellTogglePrivate { - gchar **icon_names; - guint n_icon_names; - - GdkPixbuf *empty; - GPtrArray *pixbufs; - gint height; -}; - -G_DEFINE_TYPE (ECellToggle, e_cell_toggle, E_TYPE_CELL) - -typedef struct { - ECellView cell_view; - GnomeCanvas *canvas; -} ECellToggleView; - -static void -cell_toggle_load_icons (ECellToggle *cell_toggle) -{ - GtkIconTheme *icon_theme; - gint width, height; - gint max_height = 0; - guint ii; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - - g_ptr_array_set_size (cell_toggle->priv->pixbufs, 0); - - for (ii = 0; ii < cell_toggle->priv->n_icon_names; ii++) { - const gchar *icon_name = cell_toggle->priv->icon_names[ii]; - GdkPixbuf *pixbuf = NULL; - - if (icon_name != NULL) - pixbuf = gtk_icon_theme_load_icon ( - icon_theme, icon_name, height, 0, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - if (pixbuf == NULL) - pixbuf = g_object_ref (cell_toggle->priv->empty); - - g_ptr_array_add (cell_toggle->priv->pixbufs, pixbuf); - max_height = MAX (max_height, gdk_pixbuf_get_height (pixbuf)); - } - - cell_toggle->priv->height = max_height; -} - -static void -cell_toggle_dispose (GObject *object) -{ - ECellTogglePrivate *priv; - - priv = E_CELL_TOGGLE_GET_PRIVATE (object); - - if (priv->empty != NULL) { - g_object_unref (priv->empty); - priv->empty = NULL; - } - - /* This unrefs all the elements. */ - g_ptr_array_set_size (priv->pixbufs, 0); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_cell_toggle_parent_class)->dispose (object); -} - -static void -cell_toggle_finalize (GObject *object) -{ - ECellTogglePrivate *priv; - guint ii; - - priv = E_CELL_TOGGLE_GET_PRIVATE (object); - - /* The array is not NULL-terminated, - * so g_strfreev() will not work. */ - for (ii = 0; ii < priv->n_icon_names; ii++) - g_free (priv->icon_names[ii]); - g_free (priv->icon_names); - - g_ptr_array_free (priv->pixbufs, TRUE); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_cell_toggle_parent_class)->finalize (object); -} - -static ECellView * -cell_toggle_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1); - ETableItem *eti = E_TABLE_ITEM (e_table_item_view); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; - - toggle_view->cell_view.ecell = ecell; - toggle_view->cell_view.e_table_model = table_model; - toggle_view->cell_view.e_table_item_view = e_table_item_view; - toggle_view->cell_view.kill_view_cb = NULL; - toggle_view->cell_view.kill_view_cb_data = NULL; - toggle_view->canvas = canvas; - - return (ECellView *) toggle_view; -} - -static void -cell_toggle_kill_view (ECellView *ecell_view) -{ - ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; - - if (toggle_view->cell_view.kill_view_cb) - toggle_view->cell_view.kill_view_cb ( - ecell_view, toggle_view->cell_view.kill_view_cb_data); - - if (toggle_view->cell_view.kill_view_cb_data) - g_list_free (toggle_view->cell_view.kill_view_cb_data); - - g_free (ecell_view); -} - -static void -cell_toggle_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellTogglePrivate *priv; - GdkPixbuf *image; - gint x, y; - - const gint value = GPOINTER_TO_INT ( - e_table_model_value_at (ecell_view->e_table_model, model_col, row)); - - priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell); - - if (value < 0 || value >= priv->pixbufs->len) - return; - - image = g_ptr_array_index (priv->pixbufs, value); - - if ((x2 - x1) < gdk_pixbuf_get_width (image)) - x = x1; - else - x = x1 + ((x2 - x1) - gdk_pixbuf_get_width (image)) / 2; - - if ((y2 - y1) < gdk_pixbuf_get_height (image)) - y = y1; - else - y = y1 + ((y2 - y1) - gdk_pixbuf_get_height (image)) / 2; - - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, image, x, y); - cairo_paint_with_alpha (cr, 1); - cairo_restore (cr); -} - -static void -etog_set_value (ECellToggleView *toggle_view, - gint model_col, - gint view_col, - gint row, - gint value) -{ - ECellTogglePrivate *priv; - - priv = E_CELL_TOGGLE_GET_PRIVATE (toggle_view->cell_view.ecell); - - if (value >= priv->pixbufs->len) - value = 0; - - e_table_model_set_value_at ( - toggle_view->cell_view.e_table_model, - model_col, row, GINT_TO_POINTER (value)); -} - -static gint -cell_toggle_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; - gpointer _value = e_table_model_value_at ( - ecell_view->e_table_model, model_col, row); - const gint value = GPOINTER_TO_INT (_value); - - switch (event->type) { - case GDK_KEY_PRESS: - if (event->key.keyval != GDK_KEY_space) - return FALSE; - /* Fall through */ - case GDK_BUTTON_PRESS: - if (!e_table_model_is_cell_editable ( - ecell_view->e_table_model, model_col, row)) - return FALSE; - - etog_set_value ( - toggle_view, model_col, view_col, row, value + 1); - - return TRUE; - - default: - return FALSE; - } -} - -static gint -cell_toggle_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellTogglePrivate *priv; - - priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell); - - return priv->height; -} - -static void -cell_toggle_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - ECellTogglePrivate *priv; - GdkPixbuf *image; - gdouble image_width, image_height; - const gint value = GPOINTER_TO_INT ( - e_table_model_value_at (ecell_view->e_table_model, model_col, row)); - - cairo_t *cr; - - priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell); - - if (value >= priv->pixbufs->len) - return; - - image = g_ptr_array_index (priv->pixbufs, value); - if (image) { - cr = gtk_print_context_get_cairo_context (context); - cairo_save (cr); - cairo_translate (cr, 0 , 0); - image = gdk_pixbuf_add_alpha (image, TRUE, 255, 255, 255); - image_width = (gdouble) gdk_pixbuf_get_width (image); - image_height = (gdouble) gdk_pixbuf_get_height (image); - cairo_rectangle ( - cr, - image_width / 7, - image_height / 3, - image_width - image_width / 4, - image_width - image_height / 7); - cairo_clip (cr); - gdk_cairo_set_source_pixbuf (cr, image, 0, image_height / 4); - cairo_paint (cr); - cairo_restore (cr); - } -} - -static gdouble -cell_toggle_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - ECellTogglePrivate *priv; - - priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell); - - return priv->height; -} - -static gint -cell_toggle_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - ECellTogglePrivate *priv; - gint max_width = 0; - gint number_of_rows; - gint row; - - priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell); - - number_of_rows = e_table_model_row_count (ecell_view->e_table_model); - for (row = 0; row < number_of_rows; row++) { - GdkPixbuf *pixbuf; - gpointer value; - - value = e_table_model_value_at ( - ecell_view->e_table_model, model_col, row); - pixbuf = g_ptr_array_index ( - priv->pixbufs, GPOINTER_TO_INT (value)); - - max_width = MAX (max_width, gdk_pixbuf_get_width (pixbuf)); - } - - return max_width; -} - -static void -e_cell_toggle_class_init (ECellToggleClass *class) -{ - GObjectClass *object_class; - ECellClass *cell_class; - - g_type_class_add_private (class, sizeof (ECellTogglePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = cell_toggle_dispose; - object_class->finalize = cell_toggle_finalize; - - cell_class = E_CELL_CLASS (class); - cell_class->new_view = cell_toggle_new_view; - cell_class->kill_view = cell_toggle_kill_view; - cell_class->draw = cell_toggle_draw; - cell_class->event = cell_toggle_event; - cell_class->height = cell_toggle_height; - cell_class->print = cell_toggle_print; - cell_class->print_height = cell_toggle_print_height; - cell_class->max_width = cell_toggle_max_width; - - gal_a11y_e_cell_registry_add_cell_type ( - NULL, E_TYPE_CELL_TOGGLE, gal_a11y_e_cell_toggle_new); -} - -static void -e_cell_toggle_init (ECellToggle *cell_toggle) -{ - cell_toggle->priv = E_CELL_TOGGLE_GET_PRIVATE (cell_toggle); - - cell_toggle->priv->empty = - gdk_pixbuf_new_from_xpm_data (empty_xpm); - - cell_toggle->priv->pixbufs = - g_ptr_array_new_with_free_func (g_object_unref); -} - -/** - * e_cell_toggle_construct: - * @cell_toggle: a fresh ECellToggle object - * @icon_names: array of icon names, some of which may be %NULL - * @n_icon_names: length of the @icon_names array - * - * Constructs the @cell_toggle object with the @icon_names and @n_icon_names - * arguments. - */ -void -e_cell_toggle_construct (ECellToggle *cell_toggle, - const gchar **icon_names, - guint n_icon_names) -{ - guint ii; - - g_return_if_fail (E_IS_CELL_TOGGLE (cell_toggle)); - g_return_if_fail (icon_names != NULL); - g_return_if_fail (n_icon_names > 0); - - cell_toggle->priv->icon_names = g_new (gchar *, n_icon_names); - cell_toggle->priv->n_icon_names = n_icon_names; - - for (ii = 0; ii < n_icon_names; ii++) - cell_toggle->priv->icon_names[ii] = g_strdup (icon_names[ii]); - - cell_toggle_load_icons (cell_toggle); -} - -/** - * e_cell_toggle_new: - * @icon_names: array of icon names, some of which may be %NULL - * @n_icon_names: length of the @icon_names array - * - * Creates a new ECell renderer that can be used to render toggle - * buttons with the icons specified in @icon_names. The value returned - * by ETableModel::get_value is typecast into an integer and clamped - * to the [0..n_icon_names) range. That will select the image rendered. - * - * %NULL elements in @icon_names will show no icon for the corresponding - * integer value. - * - * Returns: an ECell object that can be used to render multi-state - * toggle cells. - */ -ECell * -e_cell_toggle_new (const gchar **icon_names, - guint n_icon_names) -{ - ECellToggle *cell_toggle; - - g_return_val_if_fail (icon_names != NULL, NULL); - g_return_val_if_fail (n_icon_names > 0, NULL); - - cell_toggle = g_object_new (E_TYPE_CELL_TOGGLE, NULL); - e_cell_toggle_construct (cell_toggle, icon_names, n_icon_names); - - return (ECell *) cell_toggle; -} - -GPtrArray * -e_cell_toggle_get_pixbufs (ECellToggle *cell_toggle) -{ - g_return_val_if_fail (E_IS_CELL_TOGGLE (cell_toggle), NULL); - - return cell_toggle->priv->pixbufs; -} diff --git a/widgets/table/e-cell-toggle.h b/widgets/table/e-cell-toggle.h deleted file mode 100644 index 3bc223c229..0000000000 --- a/widgets/table/e-cell-toggle.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Multi-state image toggle cell object. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CELL_TOGGLE_H -#define E_CELL_TOGGLE_H - -#include <libgnomecanvas/libgnomecanvas.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_TOGGLE \ - (e_cell_toggle_get_type ()) -#define E_CELL_TOGGLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_TOGGLE, ECellToggle)) -#define E_CELL_TOGGLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_TOGGLE, ECellToggleClass)) -#define E_IS_CELL_TOGGLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_TOGGLE)) -#define E_IS_CELL_TOGGLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_TOGGLE)) -#define E_CELL_TOGGLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_TOGGLE, ECellToggleClass)) - -G_BEGIN_DECLS - -typedef struct _ECellToggle ECellToggle; -typedef struct _ECellToggleClass ECellToggleClass; -typedef struct _ECellTogglePrivate ECellTogglePrivate; - -struct _ECellToggle { - ECell parent; - ECellTogglePrivate *priv; -}; - -struct _ECellToggleClass { - ECellClass parent_class; -}; - -GType e_cell_toggle_get_type (void) G_GNUC_CONST; -ECell * e_cell_toggle_new (const gchar **icon_names, - guint n_icon_names); -void e_cell_toggle_construct (ECellToggle *cell_toggle, - const gchar **icon_names, - guint n_icon_names); -GPtrArray * e_cell_toggle_get_pixbufs (ECellToggle *cell_toggle); - -G_END_DECLS - -#endif /* E_CELL_TOGGLE_H */ - diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c deleted file mode 100644 index 00d096f4e6..0000000000 --- a/widgets/table/e-cell-tree.c +++ /dev/null @@ -1,881 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-cell-tree.c - Tree cell object. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * A majority of code taken from: - * - * the ECellText renderer. - * Copyright 1998, The Free Software Foundation - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <math.h> -#include <stdio.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "gal-a11y-e-cell-registry.h" -#include "gal-a11y-e-cell-tree.h" -#include "e-util/e-util.h" - -#include "e-cell-tree.h" -#include "e-table-item.h" -#include "e-tree.h" -#include "e-tree-model.h" -#include "e-tree-table-adapter.h" - -G_DEFINE_TYPE (ECellTree, e_cell_tree, E_TYPE_CELL) - -typedef struct { - ECellView cell_view; - ECellView *subcell_view; - - GnomeCanvas *canvas; - gboolean prelit; - gint animate_timeout; - -} ECellTreeView; - -#define INDENT_AMOUNT 16 - -ECellView * -e_cell_tree_view_get_subcell_view (ECellView *ect) -{ - return ((ECellTreeView *) ect)->subcell_view; -} - -static ETreePath -e_cell_tree_get_node (ETableModel *table_model, - gint row) -{ - return e_table_model_value_at (table_model, -1, row); -} - -static ETreeModel * -e_cell_tree_get_tree_model (ETableModel *table_model, - gint row) -{ - return e_table_model_value_at (table_model, -2, row); -} - -static ETreeTableAdapter * -e_cell_tree_get_tree_table_adapter (ETableModel *table_model, - gint row) -{ - return e_table_model_value_at (table_model, -3, row); -} - -static gint -visible_depth_of_node (ETableModel *model, - gint row) -{ - ETreeModel *tree_model = e_cell_tree_get_tree_model (model, row); - ETreeTableAdapter *adapter = e_cell_tree_get_tree_table_adapter (model, row); - ETreePath path = e_cell_tree_get_node (model, row); - return (e_tree_model_node_depth (tree_model, path) - - (e_tree_table_adapter_root_node_is_visible (adapter) ? 0 : 1)); -} - -/* If this is changed to not include the width of the expansion pixmap - * if the path is not expandable, then max_width needs to change as - * well. */ -static gint -offset_of_node (ETableModel *table_model, - gint row) -{ - ETreeModel *tree_model = e_cell_tree_get_tree_model (table_model, row); - ETreePath path = e_cell_tree_get_node (table_model, row); - - if (visible_depth_of_node (table_model, row) >= 0 || - e_tree_model_node_is_expandable (tree_model, path)) { - return (visible_depth_of_node (table_model, row) + 1) * INDENT_AMOUNT; - } else { - return 0; - } -} - -/* - * ECell::new_view method - */ -static ECellView * -ect_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellTree *ect = E_CELL_TREE (ecell); - ECellTreeView *tree_view = g_new0 (ECellTreeView, 1); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas; - - tree_view->cell_view.ecell = ecell; - tree_view->cell_view.e_table_model = table_model; - tree_view->cell_view.e_table_item_view = e_table_item_view; - tree_view->cell_view.kill_view_cb = NULL; - tree_view->cell_view.kill_view_cb_data = NULL; - - /* create our subcell view */ - tree_view->subcell_view = e_cell_new_view (ect->subcell, table_model, e_table_item_view /* XXX */); - - tree_view->canvas = canvas; - - return (ECellView *) tree_view; -} - -/* - * ECell::kill_view method - */ -static void -ect_kill_view (ECellView *ecv) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecv; - - if (tree_view->cell_view.kill_view_cb) - (tree_view->cell_view.kill_view_cb)(ecv, tree_view->cell_view.kill_view_cb_data); - - if (tree_view->cell_view.kill_view_cb_data) - g_list_free (tree_view->cell_view.kill_view_cb_data); - - /* kill our subcell view */ - e_cell_kill_view (tree_view->subcell_view); - - g_free (tree_view); -} - -/* - * ECell::realize method - */ -static void -ect_realize (ECellView *ecell_view) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - - /* realize our subcell view */ - e_cell_realize (tree_view->subcell_view); - - if (E_CELL_CLASS (e_cell_tree_parent_class)->realize) - (* E_CELL_CLASS (e_cell_tree_parent_class)->realize) (ecell_view); -} - -/* - * ECell::unrealize method - */ -static void -ect_unrealize (ECellView *ecv) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecv; - - /* unrealize our subcell view. */ - e_cell_unrealize (tree_view->subcell_view); - - if (E_CELL_CLASS (e_cell_tree_parent_class)->unrealize) - (* E_CELL_CLASS (e_cell_tree_parent_class)->unrealize) (ecv); -} - -static void -draw_expander (ECellTreeView *ectv, - cairo_t *cr, - GtkExpanderStyle expander_style, - GtkStateType state, - GdkRectangle *rect) -{ - GtkStyleContext *style_context; - GtkWidget *tree; - GtkStateFlags flags = 0; - gint exp_size; - - tree = gtk_widget_get_parent (GTK_WIDGET (ectv->canvas)); - style_context = gtk_widget_get_style_context (tree); - - gtk_style_context_save (style_context); - - gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_EXPANDER); - - switch (state) { - case GTK_STATE_PRELIGHT: - flags |= GTK_STATE_FLAG_PRELIGHT; - break; - case GTK_STATE_SELECTED: - flags |= GTK_STATE_FLAG_SELECTED; - break; - case GTK_STATE_INSENSITIVE: - flags |= GTK_STATE_FLAG_INSENSITIVE; - break; - default: - break; - } - - if (expander_style == GTK_EXPANDER_EXPANDED) - flags |= GTK_STATE_FLAG_ACTIVE; - - gtk_style_context_set_state (style_context, flags); - - gtk_widget_style_get (tree, "expander_size", &exp_size, NULL); - - cairo_save (cr); - - gtk_render_expander ( - style_context, cr, - (gdouble) rect->x + rect->width - exp_size, - (gdouble) (rect->y + rect->height / 2) - (exp_size / 2), - (gdouble) exp_size, - (gdouble) exp_size); - - cairo_restore (cr); - - gtk_style_context_restore (style_context); -} - -/* - * ECell::draw method - */ -static void -ect_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row); - ETreeTableAdapter *tree_table_adapter = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row); - ETreePath node; - GdkRectangle rect; - gint offset, subcell_offset; - - cairo_save (cr); - - /* only draw the tree effects if we're the active sort */ - if (/* XXX */ TRUE) { - GdkPixbuf *node_image; - gint node_image_width = 0, node_image_height = 0; - - tree_view->prelit = FALSE; - - node = e_cell_tree_get_node (ecell_view->e_table_model, row); - - offset = offset_of_node (ecell_view->e_table_model, row); - subcell_offset = offset; - - node_image = e_tree_model_icon_at (tree_model, node); - - if (node_image) { - node_image_width = gdk_pixbuf_get_width (node_image); - node_image_height = gdk_pixbuf_get_height (node_image); - } - - /* - * Be a nice citizen: clip to the region we are supposed to draw on - */ - rect.x = x1; - rect.y = y1; - rect.width = subcell_offset + node_image_width; - rect.height = y2 - y1; - - /* now draw our icon if we're expandable */ - if (e_tree_model_node_is_expandable (tree_model, node)) { - gboolean expanded = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node); - GdkRectangle r; - - r = rect; - r.width -= node_image_width + 2; - draw_expander (tree_view, cr, expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED, GTK_STATE_NORMAL, &r); - } - - if (node_image) { - gdk_cairo_set_source_pixbuf ( - cr, node_image, - x1 + subcell_offset, - y1 + (y2 - y1) / 2 - node_image_height / 2); - cairo_paint (cr); - - subcell_offset += node_image_width; - } - } - - /* Now cause our subcell to draw its contents, shifted by - * subcell_offset pixels */ - e_cell_draw ( - tree_view->subcell_view, cr, - model_col, view_col, row, flags, - x1 + subcell_offset, y1, x2, y2); - - cairo_restore (cr); -} - -static void -adjust_event_position (GdkEvent *event, - gint offset) -{ - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - event->button.x += offset; - break; - case GDK_MOTION_NOTIFY: - event->motion.x += offset; - break; - default: - break; - } -} - -static gboolean -event_in_expander (GdkEvent *event, - gint offset, - gint height) -{ - switch (event->type) { - case GDK_BUTTON_PRESS: - return (event->button.x > (offset - INDENT_AMOUNT) && event->button.x < offset); - case GDK_MOTION_NOTIFY: - return (event->motion.x > (offset - INDENT_AMOUNT) && event->motion.x < offset && - event->motion.y > 2 && event->motion.y < (height - 2)); - default: - break; - } - - return FALSE; -} - -/* - * ECell::height method - */ -static gint -ect_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - - return (((e_cell_height (tree_view->subcell_view, model_col, view_col, row)) + 1) / 2) * 2; -} - -typedef struct { - ECellTreeView *ectv; - ETreeTableAdapter *etta; - ETreePath node; - gboolean expanded; - gboolean finish; - GdkRectangle area; -} animate_closure_t; - -static gboolean -animate_expander (gpointer data) -{ - GtkLayout *layout; - GdkWindow *window; - animate_closure_t *closure = (animate_closure_t *) data; - cairo_t *cr; - - if (closure->finish) { - e_tree_table_adapter_node_set_expanded (closure->etta, closure->node, !closure->expanded); - closure->ectv->animate_timeout = 0; - g_free (data); - return FALSE; - } - - layout = GTK_LAYOUT (closure->ectv->canvas); - window = gtk_layout_get_bin_window (layout); - - cr = gdk_cairo_create (window); - - draw_expander ( - closure->ectv, cr, closure->expanded ? - GTK_EXPANDER_SEMI_COLLAPSED : - GTK_EXPANDER_SEMI_EXPANDED, - GTK_STATE_NORMAL, &closure->area); - closure->finish = TRUE; - - cairo_destroy (cr); - - return TRUE; -} - -/* - * ECell::event method - */ -static gint -ect_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - GtkLayout *layout; - GdkWindow *window; - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row); - ETreeTableAdapter *etta = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row); - ETreePath node = e_cell_tree_get_node (ecell_view->e_table_model, row); - gint offset = offset_of_node (ecell_view->e_table_model, row); - gint result; - - layout = GTK_LAYOUT (tree_view->canvas); - window = gtk_layout_get_bin_window (layout); - - switch (event->type) { - case GDK_BUTTON_PRESS: - - if (event_in_expander (event, offset, 0)) { - if (e_tree_model_node_is_expandable (tree_model, node)) { - gboolean expanded = e_tree_table_adapter_node_is_expanded (etta, node); - gint tmp_row = row; - GdkRectangle area; - animate_closure_t *closure = g_new0 (animate_closure_t, 1); - cairo_t *cr; - gint hgt; - - e_table_item_get_cell_geometry ( - tree_view->cell_view.e_table_item_view, - &tmp_row, &view_col, &area.x, &area.y, NULL, &area.height); - area.width = offset - 2; - hgt = e_cell_height (ecell_view, model_col, view_col, row); - - if (hgt != area.height) /* Composite cells */ - area.height += hgt; - - cr = gdk_cairo_create (window); - draw_expander ( - tree_view, cr, expanded ? - GTK_EXPANDER_SEMI_EXPANDED : - GTK_EXPANDER_SEMI_COLLAPSED, - GTK_STATE_NORMAL, &area); - cairo_destroy (cr); - - closure->ectv = tree_view; - closure->etta = etta; - closure->node = node; - closure->expanded = expanded; - closure->area = area; - tree_view->animate_timeout = g_timeout_add (50, animate_expander, closure); - return TRUE; - } - } - else if (event->button.x < (offset - INDENT_AMOUNT)) - return FALSE; - break; - - case GDK_MOTION_NOTIFY: - - if (e_tree_model_node_is_expandable (tree_model, node)) { - gint height = ect_height (ecell_view, model_col, view_col, row); - GdkRectangle area; - gboolean in_expander = event_in_expander (event, offset, height); - - if (tree_view->prelit ^ in_expander) { - gint tmp_row = row; - cairo_t *cr; - - e_table_item_get_cell_geometry ( - tree_view->cell_view.e_table_item_view, - &tmp_row, &view_col, &area.x, &area.y, NULL, &area.height); - area.width = offset - 2; - - cr = gdk_cairo_create (window); - draw_expander ( - tree_view, cr, - e_tree_table_adapter_node_is_expanded (etta, node) ? - GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED, - in_expander ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, &area); - cairo_destroy (cr); - - tree_view->prelit = in_expander; - return TRUE; - } - - } - break; - - case GDK_LEAVE_NOTIFY: - - if (tree_view->prelit) { - gint tmp_row = row; - GdkRectangle area; - cairo_t *cr; - - e_table_item_get_cell_geometry ( - tree_view->cell_view.e_table_item_view, - &tmp_row, &view_col, &area.x, &area.y, NULL, &area.height); - area.width = offset - 2; - - cr = gdk_cairo_create (window); - draw_expander ( - tree_view, cr, - e_tree_table_adapter_node_is_expanded (etta, node) ? - GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED, - GTK_STATE_NORMAL, &area); - cairo_destroy (cr); - - tree_view->prelit = FALSE; - } - return TRUE; - - default: - break; - } - - adjust_event_position (event, -offset); - result = e_cell_event (tree_view->subcell_view, event, model_col, view_col, row, flags, actions); - adjust_event_position (event, offset); - - return result; -} - -/* - * ECell::max_width method - */ -static gint -ect_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - gint row; - gint number_of_rows; - gint max_width = 0; - gint width = 0; - gint subcell_max_width = 0; - gboolean per_row = e_cell_max_width_by_row_implemented (tree_view->subcell_view); - - number_of_rows = e_table_model_row_count (ecell_view->e_table_model); - - if (!per_row) - subcell_max_width = e_cell_max_width (tree_view->subcell_view, model_col, view_col); - - for (row = 0; row < number_of_rows; row++) { - ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row); - ETreePath node; - GdkPixbuf *node_image; - gint node_image_width = 0; - - gint offset, subcell_offset; -#if 0 - gboolean expanded, expandable; - ETreeTableAdapter *tree_table_adapter = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row); -#endif - - node = e_cell_tree_get_node (ecell_view->e_table_model, row); - - offset = offset_of_node (ecell_view->e_table_model, row); - subcell_offset = offset; - - node_image = e_tree_model_icon_at (tree_model, node); - - if (node_image) { - node_image_width = gdk_pixbuf_get_width (node_image); - } - - width = subcell_offset + node_image_width; - - if (per_row) - width += e_cell_max_width_by_row (tree_view->subcell_view, model_col, view_col, row); - else - width += subcell_max_width; - -#if 0 - expandable = e_tree_model_node_is_expandable (tree_model, node); - expanded = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node); - - /* This is unnecessary since this is already handled - * by the offset_of_node function. If that changes, - * this will have to change too. */ - - if (expandable) { - GdkPixbuf *image; - - image = (expanded - ? E_CELL_TREE (tree_view->cell_view.ecell)->open_pixbuf - : E_CELL_TREE (tree_view->cell_view.ecell)->closed_pixbuf); - - width += gdk_pixbuf_get_width (image); - } -#endif - - max_width = MAX (max_width, width); - } - - return max_width; -} - -/* - * ECellView::get_bg_color method - */ -static gchar * -ect_get_bg_color (ECellView *ecell_view, - gint row) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - - return e_cell_get_bg_color (tree_view->subcell_view, row); -} - -/* - * ECellView::enter_edit method - */ -static gpointer -ect_enter_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - /* just defer to our subcell's view */ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - - return e_cell_enter_edit (tree_view->subcell_view, model_col, view_col, row); -} - -/* - * ECellView::leave_edit method - */ -static void -ect_leave_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - /* just defer to our subcell's view */ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - - e_cell_leave_edit (tree_view->subcell_view, model_col, view_col, row, edit_context); -} - -static void -ect_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - ECellTreeView *tree_view = (ECellTreeView *) ecell_view; - cairo_t *cr = gtk_print_context_get_cairo_context (context); - - cairo_save (cr); - - if (/* XXX only if we're the active sort */ TRUE) { - ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row); - ETreeTableAdapter *tree_table_adapter = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row); - ETreePath node = e_cell_tree_get_node (ecell_view->e_table_model, row); - gint offset = offset_of_node (ecell_view->e_table_model, row); - gint subcell_offset = offset; - gboolean expandable = e_tree_model_node_is_expandable (tree_model, node); - - /* draw our lines */ - if (E_CELL_TREE (tree_view->cell_view.ecell)->draw_lines) { - gint depth; - - if (!e_tree_model_node_is_root (tree_model, node) - || e_tree_model_node_get_children (tree_model, node, NULL) > 0) { - cairo_move_to ( - cr, - offset - INDENT_AMOUNT / 2, - height / 2); - cairo_line_to (cr, offset, height / 2); - } - - if (visible_depth_of_node (ecell_view->e_table_model, row) != 0) { - cairo_move_to ( - cr, - offset - INDENT_AMOUNT / 2, height); - cairo_line_to ( - cr, - offset - INDENT_AMOUNT / 2, - e_tree_table_adapter_node_get_next - (tree_table_adapter, node) ? 0 : - height / 2); - } - - /* now traverse back up to the root of the tree, checking at - * each level if the node has siblings, and drawing the - * correct vertical pipe for it's configuration. */ - node = e_tree_model_node_get_parent (tree_model, node); - depth = visible_depth_of_node (ecell_view->e_table_model, row) - 1; - offset -= INDENT_AMOUNT; - while (node && depth != 0) { - if (e_tree_table_adapter_node_get_next (tree_table_adapter, node)) { - cairo_move_to ( - cr, - offset - INDENT_AMOUNT / 2, - height); - cairo_line_to ( - cr, - offset - INDENT_AMOUNT / 2, 0); - } - node = e_tree_model_node_get_parent (tree_model, node); - depth--; - offset -= INDENT_AMOUNT; - } - } - - /* now draw our icon if we're expandable */ - if (expandable) { - gboolean expanded; - GdkRectangle r; - gint exp_size = 0; - - gtk_widget_style_get (GTK_WIDGET (gtk_widget_get_parent (GTK_WIDGET (tree_view->canvas))), "expander_size", &exp_size, NULL); - - node = e_cell_tree_get_node (ecell_view->e_table_model, row); - expanded = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node); - - r.x = 0; - r.y = 0; - r.width = MIN (width, exp_size); - r.height = height; - - draw_expander (tree_view, cr, expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED, GTK_STATE_NORMAL, &r); - } - - cairo_stroke (cr); - - cairo_translate (cr, subcell_offset, 0); - width -= subcell_offset; - } - - cairo_restore (cr); - - e_cell_print (tree_view->subcell_view, context, model_col, view_col, row, width, height); -} - -static gdouble -ect_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - return 12; /* XXX */ -} - -/* - * GObject::dispose method - */ -static void -ect_dispose (GObject *object) -{ - ECellTree *ect = E_CELL_TREE (object); - - /* destroy our subcell */ - if (ect->subcell) - g_object_unref (ect->subcell); - ect->subcell = NULL; - - G_OBJECT_CLASS (e_cell_tree_parent_class)->dispose (object); -} - -static void -e_cell_tree_class_init (ECellTreeClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ECellClass *ecc = E_CELL_CLASS (class); - - object_class->dispose = ect_dispose; - - ecc->new_view = ect_new_view; - ecc->kill_view = ect_kill_view; - ecc->realize = ect_realize; - ecc->unrealize = ect_unrealize; - ecc->draw = ect_draw; - ecc->event = ect_event; - ecc->height = ect_height; - ecc->enter_edit = ect_enter_edit; - ecc->leave_edit = ect_leave_edit; - ecc->print = ect_print; - ecc->print_height = ect_print_height; - ecc->max_width = ect_max_width; - ecc->get_bg_color = ect_get_bg_color; - - gal_a11y_e_cell_registry_add_cell_type (NULL, E_TYPE_CELL_TREE, gal_a11y_e_cell_tree_new); -} - -static void -e_cell_tree_init (ECellTree *ect) -{ - /* nothing to do */ -} - -/** - * e_cell_tree_construct: - * @ect: the ECellTree we're constructing. - * @draw_lines: whether or not to draw the lines between parents/children/siblings. - * @subcell: the ECell to render to the right of the tree effects. - * - * Constructs an ECellTree. used by subclasses that need to - * initialize a nested ECellTree. See e_cell_tree_new() for more info. - * - **/ -void -e_cell_tree_construct (ECellTree *ect, - gboolean draw_lines, - ECell *subcell) -{ - ect->subcell = subcell; - if (subcell) - g_object_ref_sink (subcell); - - ect->draw_lines = draw_lines; -} - -/** - * e_cell_tree_new: - * @draw_lines: whether or not to draw the lines between parents/children/siblings. - * @subcell: the ECell to render to the right of the tree effects. - * - * Creates a new ECell renderer that can be used to render tree - * effects that come from an ETreeModel. Various assumptions are made - * as to the fact that the ETableModel the ETable this cell is - * associated with is in fact an ETreeModel. The cell uses special - * columns to get at structural information (needed to draw the - * lines/icons. - * - * Return value: an ECell object that can be used to render trees. - **/ -ECell * -e_cell_tree_new (gboolean draw_lines, - ECell *subcell) -{ - ECellTree *ect = g_object_new (E_TYPE_CELL_TREE, NULL); - - e_cell_tree_construct (ect, draw_lines, subcell); - - return (ECell *) ect; -} - diff --git a/widgets/table/e-cell-tree.h b/widgets/table/e-cell-tree.h deleted file mode 100644 index cf43c47a1c..0000000000 --- a/widgets/table/e-cell-tree.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-cell-tree.h - Tree cell object. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * A majority of code taken from: - * - * the ECellText renderer. - * Copyright 1998, The Free Software Foundation - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _E_CELL_TREE_H_ -#define _E_CELL_TREE_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_TREE \ - (e_cell_tree_get_type ()) -#define E_CELL_TREE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_TREE, ECellTree)) -#define E_CELL_TREE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_TREE, ECellTreeClass)) -#define E_IS_CELL_TREE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_TREE)) -#define E_IS_CELL_TREE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_TREE)) -#define E_CELL_TREE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_TREE, ECellTreeClass)) - -G_BEGIN_DECLS - -typedef struct _ECellTree ECellTree; -typedef struct _ECellTreeClass ECellTreeClass; - -struct _ECellTree { - ECell parent; - - gboolean draw_lines; - - ECell *subcell; -}; - -struct _ECellTreeClass { - ECellClass parent_class; -}; - -GType e_cell_tree_get_type (void) G_GNUC_CONST; -ECell * e_cell_tree_new (gboolean draw_lines, - ECell *subcell); -void e_cell_tree_construct (ECellTree *ect, - gboolean draw_lines, - ECell *subcell); -ECellView * e_cell_tree_view_get_subcell_view - (ECellView *ect); - -G_END_DECLS - -#endif /* _E_CELL_TREE_H_ */ - diff --git a/widgets/table/e-cell-vbox.c b/widgets/table/e-cell-vbox.c deleted file mode 100644 index bce40a8a2e..0000000000 --- a/widgets/table/e-cell-vbox.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <math.h> -#include <stdio.h> - -#include <gtk/gtk.h> - -#include "gal-a11y-e-cell-registry.h" -#include "gal-a11y-e-cell-vbox.h" -#include "e-util/e-util.h" - -#include "e-cell-vbox.h" -#include "e-table-item.h" - -G_DEFINE_TYPE (ECellVbox, e_cell_vbox, E_TYPE_CELL) - -#define INDENT_AMOUNT 16 - -/* - * ECell::new_view method - */ -static ECellView * -ecv_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - ECellVbox *ecv = E_CELL_VBOX (ecell); - ECellVboxView *vbox_view = g_new0 (ECellVboxView, 1); - gint i; - - vbox_view->cell_view.ecell = ecell; - vbox_view->cell_view.e_table_model = table_model; - vbox_view->cell_view.e_table_item_view = e_table_item_view; - vbox_view->cell_view.kill_view_cb = NULL; - vbox_view->cell_view.kill_view_cb_data = NULL; - - /* create our subcell view */ - vbox_view->subcell_view_count = ecv->subcell_count; - vbox_view->subcell_views = g_new (ECellView *, vbox_view->subcell_view_count); - vbox_view->model_cols = g_new (int, vbox_view->subcell_view_count); - - for (i = 0; i < vbox_view->subcell_view_count; i++) { - vbox_view->subcell_views[i] = e_cell_new_view (ecv->subcells[i], table_model, e_table_item_view /* XXX */); - vbox_view->model_cols[i] = ecv->model_cols[i]; - } - - return (ECellView *) vbox_view; -} - -/* - * ECell::kill_view method - */ -static void -ecv_kill_view (ECellView *ecv) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecv; - gint i; - - if (vbox_view->cell_view.kill_view_cb) - (vbox_view->cell_view.kill_view_cb)(ecv, vbox_view->cell_view.kill_view_cb_data); - - if (vbox_view->cell_view.kill_view_cb_data) - g_list_free (vbox_view->cell_view.kill_view_cb_data); - - /* kill our subcell view */ - for (i = 0; i < vbox_view->subcell_view_count; i++) - e_cell_kill_view (vbox_view->subcell_views[i]); - - g_free (vbox_view->model_cols); - g_free (vbox_view->subcell_views); - g_free (vbox_view); -} - -/* - * ECell::realize method - */ -static void -ecv_realize (ECellView *ecell_view) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecell_view; - gint i; - - /* realize our subcell view */ - for (i = 0; i < vbox_view->subcell_view_count; i++) - e_cell_realize (vbox_view->subcell_views[i]); - - if (E_CELL_CLASS (e_cell_vbox_parent_class)->realize) - (* E_CELL_CLASS (e_cell_vbox_parent_class)->realize) (ecell_view); -} - -/* - * ECell::unrealize method - */ -static void -ecv_unrealize (ECellView *ecv) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecv; - gint i; - - /* unrealize our subcell view. */ - for (i = 0; i < vbox_view->subcell_view_count; i++) - e_cell_unrealize (vbox_view->subcell_views[i]); - - if (E_CELL_CLASS (e_cell_vbox_parent_class)->unrealize) - (* E_CELL_CLASS (e_cell_vbox_parent_class)->unrealize) (ecv); -} - -/* - * ECell::draw method - */ -static void -ecv_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecell_view; - - gint subcell_offset = 0; - gint i; - - for (i = 0; i < vbox_view->subcell_view_count; i++) { - /* Now cause our subcells to draw their contents, - * shifted by subcell_offset pixels */ - gint height; - - height = e_cell_height ( - vbox_view->subcell_views[i], - vbox_view->model_cols[i], view_col, row); - e_cell_draw ( - vbox_view->subcell_views[i], cr, - vbox_view->model_cols[i], view_col, row, flags, - x1, y1 + subcell_offset, x2, - y1 + subcell_offset + height); - - subcell_offset += e_cell_height ( - vbox_view->subcell_views[i], - vbox_view->model_cols[i], view_col, row); - } -} - -/* - * ECell::event method - */ -static gint -ecv_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecell_view; - gint y = 0; - gint i; - gint subcell_offset = 0; - - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - y = event->button.y; - break; - case GDK_MOTION_NOTIFY: - y = event->motion.y; - break; - default: - /* nada */ - break; - } - - for (i = 0; i < vbox_view->subcell_view_count; i++) { - gint height = e_cell_height (vbox_view->subcell_views[i], vbox_view->model_cols[i], view_col, row); - if (y < subcell_offset + height) - return e_cell_event (vbox_view->subcell_views[i], event, vbox_view->model_cols[i], view_col, row, flags, actions); - subcell_offset += height; - } - return 0; -} - -/* - * ECell::height method - */ -static gint -ecv_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecell_view; - gint height = 0; - gint i; - - for (i = 0; i < vbox_view->subcell_view_count; i++) { - height += e_cell_height (vbox_view->subcell_views[i], vbox_view->model_cols[i], view_col, row); - } - return height; -} - -/* - * ECell::max_width method - */ -static gint -ecv_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - ECellVboxView *vbox_view = (ECellVboxView *) ecell_view; - gint max_width = 0; - gint i; - - for (i = 0; i < vbox_view->subcell_view_count; i++) { - gint width = e_cell_max_width (vbox_view->subcell_views[i], vbox_view->model_cols[i], view_col); - max_width = MAX (width, max_width); - } - - return max_width; -} - -/* - * GObject::dispose method - */ -static void -ecv_dispose (GObject *object) -{ - ECellVbox *ecv = E_CELL_VBOX (object); - gint i; - - /* destroy our subcell */ - for (i = 0; i < ecv->subcell_count; i++) - if (ecv->subcells[i]) - g_object_unref (ecv->subcells[i]); - g_free (ecv->subcells); - ecv->subcells = NULL; - ecv->subcell_count = 0; - - G_OBJECT_CLASS (e_cell_vbox_parent_class)->dispose (object); -} - -static void -ecv_finalize (GObject *object) -{ - ECellVbox *ecv = E_CELL_VBOX (object); - - g_free (ecv->model_cols); - - G_OBJECT_CLASS (e_cell_vbox_parent_class)->finalize (object); -} - -static void -e_cell_vbox_class_init (ECellVboxClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ECellClass *ecc = E_CELL_CLASS (class); - - object_class->dispose = ecv_dispose; - object_class->finalize = ecv_finalize; - - ecc->new_view = ecv_new_view; - ecc->kill_view = ecv_kill_view; - ecc->realize = ecv_realize; - ecc->unrealize = ecv_unrealize; - ecc->draw = ecv_draw; - ecc->event = ecv_event; - ecc->height = ecv_height; - ecc->max_width = ecv_max_width; - - gal_a11y_e_cell_registry_add_cell_type (NULL, E_TYPE_CELL_VBOX, gal_a11y_e_cell_vbox_new); -} - -static void -e_cell_vbox_init (ECellVbox *ecv) -{ - ecv->subcells = NULL; - ecv->subcell_count = 0; -} - -/** - * e_cell_vbox_new: - * - * Creates a new ECell renderer that can be used to render multiple - * child cells. - * - * Return value: an ECell object that can be used to render multiple - * child cells. - **/ -ECell * -e_cell_vbox_new (void) -{ - return g_object_new (E_TYPE_CELL_VBOX, NULL); -} - -void -e_cell_vbox_append (ECellVbox *vbox, - ECell *subcell, - gint model_col) -{ - vbox->subcell_count++; - - vbox->subcells = g_renew (ECell *, vbox->subcells, vbox->subcell_count); - vbox->model_cols = g_renew (int, vbox->model_cols, vbox->subcell_count); - - vbox->subcells[vbox->subcell_count - 1] = subcell; - vbox->model_cols[vbox->subcell_count - 1] = model_col; - - if (subcell) - g_object_ref_sink (subcell); -} diff --git a/widgets/table/e-cell-vbox.h b/widgets/table/e-cell-vbox.h deleted file mode 100644 index 2ab522c4ae..0000000000 --- a/widgets/table/e-cell-vbox.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * Chris Lahey <clahey@ximina.com - * - * A majority of code taken from: - * the ECellText renderer. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CELL_VBOX_H_ -#define _E_CELL_VBOX_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL_VBOX \ - (e_cell_vbox_get_type ()) -#define E_CELL_VBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL_VBOX, ECellVbox)) -#define E_CELL_VBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL_VBOX, ECellVboxClass)) -#define E_IS_CELL_VBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL_VBOX)) -#define E_IS_CELL_VBOX_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL_VBOX)) -#define E_CELL_VBOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL_VBOX, ECellVboxClass)) - -G_BEGIN_DECLS - -typedef struct _ECellVbox ECellVbox; -typedef struct _ECellVboxView ECellVboxView; -typedef struct _ECellVboxClass ECellVboxClass; - -struct _ECellVbox { - ECell parent; - - gint subcell_count; - ECell **subcells; - gint *model_cols; -}; - -struct _ECellVboxView { - ECellView cell_view; - - gint subcell_view_count; - ECellView **subcell_views; - gint *model_cols; -}; - -struct _ECellVboxClass { - ECellClass parent_class; -}; - -GType e_cell_vbox_get_type (void) G_GNUC_CONST; -ECell * e_cell_vbox_new (void); -void e_cell_vbox_append (ECellVbox *vbox, - ECell *subcell, - gint model_col); - -G_END_DECLS - -#endif /* _E_CELL_VBOX_H_ */ diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c deleted file mode 100644 index b9b96eecb0..0000000000 --- a/widgets/table/e-cell.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include "e-util/e-util.h" - -#include "e-cell.h" - -G_DEFINE_TYPE (ECell, e_cell, G_TYPE_OBJECT) - -static ECellView * -ec_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - return NULL; -} - -static void -ec_realize (ECellView *e_cell) -{ -} - -static void -ec_kill_view (ECellView *ecell_view) -{ -} - -static void -ec_unrealize (ECellView *e_cell) -{ -} - -static void -ec_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - g_critical ("e-cell-draw invoked"); -} - -static gint -ec_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - g_critical ("e-cell-event invoked"); - - return 0; -} - -static gint -ec_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - g_critical ("e-cell-height invoked"); - - return 0; -} - -static void -ec_focus (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ecell_view->focus_col = view_col; - ecell_view->focus_row = row; - ecell_view->focus_x1 = x1; - ecell_view->focus_y1 = y1; - ecell_view->focus_x2 = x2; - ecell_view->focus_y2 = y2; -} - -static void -ec_unfocus (ECellView *ecell_view) -{ - ecell_view->focus_col = -1; - ecell_view->focus_row = -1; - ecell_view->focus_x1 = -1; - ecell_view->focus_y1 = -1; - ecell_view->focus_x2 = -1; - ecell_view->focus_y2 = -1; -} - -static gpointer -ec_enter_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - return NULL; -} - -static void -ec_leave_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context) -{ -} - -static gpointer -ec_save_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context) -{ - return NULL; -} - -static void -ec_load_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context, - gpointer save_state) -{ -} - -static void -ec_free_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer save_state) -{ -} - -static void -e_cell_class_init (ECellClass *class) -{ - class->realize = ec_realize; - class->unrealize = ec_unrealize; - class->new_view = ec_new_view; - class->kill_view = ec_kill_view; - class->draw = ec_draw; - class->event = ec_event; - class->focus = ec_focus; - class->unfocus = ec_unfocus; - class->height = ec_height; - class->enter_edit = ec_enter_edit; - class->leave_edit = ec_leave_edit; - class->save_state = ec_save_state; - class->load_state = ec_load_state; - class->free_state = ec_free_state; - class->print = NULL; - class->print_height = NULL; - class->max_width = NULL; - class->max_width_by_row = NULL; -} - -static void -e_cell_init (ECell *cell) -{ -} - -/** - * e_cell_event: - * @ecell_view: The ECellView where the event will be dispatched - * @event: The GdkEvent. - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * @flags: flags about the current state - * @actions: a second return value in case the cell wants to take some action - * (specifically grabbing & ungrabbing) - * - * Dispatches the event @event to the @ecell_view for. - * - * Returns: processing state from the GdkEvent handling. - */ -gint -e_cell_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - return class->event ( - ecell_view, event, model_col, - view_col, row, flags, actions); -} - -/** - * e_cell_new_view: - * @ecell: the Ecell that will create the new view - * @table_model: the table model the ecell is bound to - * @e_table_item_view: an ETableItem object (the CanvasItem that - * reprensents the view of the table) - * - * ECell renderers new to be bound to a table_model and to the actual view - * during their life time to actually render the data. This method is invoked - * by the ETableItem canvas item to instatiate a new view of the ECell. - * - * This is invoked when the ETableModel is attached to the ETableItem - * (a CanvasItem that can render ETableModels in the screen). - * - * Returns: a new ECellView for this @ecell on the @table_model displayed - * on the @e_table_item_view. - */ -ECellView * -e_cell_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view) -{ - return E_CELL_GET_CLASS (ecell)->new_view ( - ecell, table_model, e_table_item_view); -} - -/** - * e_cell_realize: - * @ecell_view: The ECellView to be realized. - * - * This function is invoked to give a chance to the ECellView to allocate - * any resources it needs from Gdk, equivalent to the GtkWidget::realize - * signal. - */ -void -e_cell_realize (ECellView *ecell_view) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_if_fail (class->realize != NULL); - - class->realize (ecell_view); -} - -/** - * e_cell_kill_view: - * @ecell_view: view to be destroyed. - * - * This method it used to destroy a view of an ECell renderer - */ -void -e_cell_kill_view (ECellView *ecell_view) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_if_fail (class->kill_view != NULL); - - class->kill_view (ecell_view); -} - -/** - * e_cell_unrealize: - * @ecell_view: The ECellView to be unrealized. - * - * This function is invoked to give a chance to the ECellView to - * release any resources it allocated during the realize method, - * equivalent to the GtkWidget::unrealize signal. - */ -void -e_cell_unrealize (ECellView *ecell_view) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_if_fail (class->unrealize != NULL); - - class->unrealize (ecell_view); -} - -/** - * e_cell_draw: - * @ecell_view: the ECellView to redraw - * @cr: a Cairo context - * @model_col: the column in the model being drawn. - * @view_col: the column in the view being drawn (what the model maps to). - * @row: the row being drawn - * @flags: rendering flags. - * @x1: boudary for the rendering - * @y1: boudary for the rendering - * @x2: boudary for the rendering - * @y2: boudary for the rendering - * - * This instructs the ECellView to render itself into the Cairo context. - * The region to be drawn in given by (x1,y1)-(x2,y2). - * - * The most important flags are %E_CELL_SELECTED and %E_CELL_FOCUSED, other - * flags include alignments and justifications. - */ -void -e_cell_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2) -{ - ECellClass *class; - - g_return_if_fail (ecell_view != NULL); - g_return_if_fail (row >= 0); - g_return_if_fail (row < e_table_model_row_count (ecell_view->e_table_model)); - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_if_fail (class->draw != NULL); - - cairo_save (cr); - - class->draw ( - ecell_view, cr, - model_col, view_col, - row, flags, x1, y1, x2, y2); - - cairo_restore (cr); -} - -/** - * e_cell_print: - * @ecell_view: the ECellView to redraw - * @context: The GtkPrintContext where we output our printed data. - * @model_col: the column in the model being drawn. - * @view_col: the column in the view being drawn (what the model maps to). - * @row: the row being drawn - * @width: width - * @height: height - * - * FIXME: - */ -void -e_cell_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->print != NULL) - class->print ( - ecell_view, context, - model_col, view_col, - row, width, height); -} - -/** - * e_cell_print: - * - * FIXME: - */ -gdouble -e_cell_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->print_height == NULL) - return 0.0; - - return class->print_height ( - ecell_view, context, - model_col, view_col, - row, width); -} - -/** - * e_cell_height: - * @ecell_view: the ECellView. - * @model_col: the column in the model - * @view_col: the column in the view. - * @row: the row to me measured - * - * Returns: the height of the cell at @model_col, @row rendered at - * @view_col, @row. - */ -gint -e_cell_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_val_if_fail (class->height != NULL, 0); - - return class->height (ecell_view, model_col, view_col, row); -} - -/** - * e_cell_enter_edit: - * @ecell_view: the ECellView that will enter editing - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * - * Notifies the ECellView that it is about to enter editing mode for - * @model_col, @row rendered at @view_col, @row. - */ -gpointer -e_cell_enter_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_val_if_fail (class->enter_edit != NULL, NULL); - - return class->enter_edit (ecell_view, model_col, view_col, row); -} - -/** - * e_cell_leave_edit: - * @ecell_view: the ECellView that will leave editing - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * @edit_context: the editing context - * - * Notifies the ECellView that editing is finished at @model_col, @row - * rendered at @view_col, @row. - */ -void -e_cell_leave_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_if_fail (class->leave_edit != NULL); - - class->leave_edit (ecell_view, model_col, view_col, row, edit_context); -} - -/** - * e_cell_save_state: - * @ecell_view: the ECellView to save - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * @edit_context: the editing context - * - * Returns: The save state. - * - * Requests that the ECellView return a gpointer representing the state - * of the ECell. This is primarily intended for things like selection - * or scrolling. - */ -gpointer -e_cell_save_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->save_state == NULL) - return NULL; - - return class->save_state ( - ecell_view, model_col, view_col, row, edit_context); -} - -/** - * e_cell_load_state: - * @ecell_view: the ECellView to load - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * @edit_context: the editing context - * @save_state: the save state to load from - * - * Requests that the ECellView load from the given save state. - */ -void -e_cell_load_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context, - gpointer save_state) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->load_state != NULL) - class->load_state ( - ecell_view, model_col, view_col, - row, edit_context, save_state); -} - -/** - * e_cell_free_state: - * @ecell_view: the ECellView - * @model_col: the column in the model - * @view_col: the column in the view - * @row: the row - * @edit_context: the editing context - * @save_state: the save state to free - * - * Requests that the ECellView free the given save state. - */ -void -e_cell_free_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer save_state) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->free_state != NULL) - class->free_state ( - ecell_view, model_col, view_col, row, save_state); -} - -/** - * e_cell_max_width: - * @ecell_view: the ECellView that will leave editing - * @model_col: the column in the model - * @view_col: the column in the view. - * - * Returns: the maximum width for the ECellview at @model_col which - * is being rendered as @view_col - */ -gint -e_cell_max_width (ECellView *ecell_view, - gint model_col, - gint view_col) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - g_return_val_if_fail (class->max_width != NULL, 0); - - return class->max_width (ecell_view, model_col, view_col); -} - -/** - * e_cell_max_width_by_row: - * @ecell_view: the ECellView that we are curious about - * @model_col: the column in the model - * @view_col: the column in the view. - * @row: The row in the model. - * - * Returns: the maximum width for the ECellview at @model_col which - * is being rendered as @view_col for the data in @row. - */ -gint -e_cell_max_width_by_row (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->max_width_by_row == NULL) - return e_cell_max_width (ecell_view, model_col, view_col); - - return class->max_width_by_row (ecell_view, model_col, view_col, row); -} - -/** - * e_cell_max_width_by_row_implemented: - * @ecell_view: the ECellView that we are curious about - * @model_col: the column in the model - * @view_col: the column in the view. - * @row: The row in the model. - * - * Returns: the maximum width for the ECellview at @model_col which - * is being rendered as @view_col for the data in @row. - */ -gboolean -e_cell_max_width_by_row_implemented (ECellView *ecell_view) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - return (class->max_width_by_row != NULL); -} - -gchar * -e_cell_get_bg_color (ECellView *ecell_view, - gint row) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->get_bg_color == NULL) - return NULL; - - return class->get_bg_color (ecell_view, row); -} - -void -e_cell_style_set (ECellView *ecell_view, - GtkStyle *previous_style) -{ - ECellClass *class; - - class = E_CELL_GET_CLASS (ecell_view->ecell); - - if (class->style_set != NULL) - class->style_set (ecell_view, previous_style); -} - diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h deleted file mode 100644 index 38fcc68c32..0000000000 --- a/widgets/table/e-cell.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CELL_H_ -#define _E_CELL_H_ - -#include <gtk/gtk.h> -#include <table/e-table-model.h> - -/* Standard GObject macros */ -#define E_TYPE_CELL \ - (e_cell_get_type ()) -#define E_CELL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CELL, ECell)) -#define E_CELL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CELL, ECellClass)) -#define E_CELL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL, ECellClass)) -#define E_IS_CELL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CELL)) -#define E_IS_CELL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CELL)) -#define E_CELL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CELL, ECellClass)) - -G_BEGIN_DECLS - -typedef struct _ECell ECell; -typedef struct _ECellClass ECellClass; -typedef struct _ECellView ECellView; - -typedef gboolean (*ETableSearchFunc) (gconstpointer haystack, - const gchar *needle); - -typedef enum { - E_CELL_SELECTED = 1 << 0, - - E_CELL_JUSTIFICATION = 3 << 1, - E_CELL_JUSTIFY_CENTER = 0 << 1, - E_CELL_JUSTIFY_LEFT = 1 << 1, - E_CELL_JUSTIFY_RIGHT = 2 << 1, - E_CELL_JUSTIFY_FILL = 3 << 1, - - E_CELL_ALIGN_LEFT = 1 << 1, - E_CELL_ALIGN_RIGHT = 1 << 2, - - E_CELL_FOCUSED = 1 << 3, - - E_CELL_EDITING = 1 << 4, - - E_CELL_CURSOR = 1 << 5, - - E_CELL_PREEDIT = 1 << 6 -} ECellFlags; - -typedef enum { - E_CELL_GRAB = 1 << 0, - E_CELL_UNGRAB = 1 << 1 -} ECellActions; - -struct _ECellView { - ECell *ecell; - ETableModel *e_table_model; - void *e_table_item_view; - - gint focus_x1, focus_y1, focus_x2, focus_y2; - gint focus_col, focus_row; - - void (*kill_view_cb) (struct _ECellView *, gpointer); - GList *kill_view_cb_data; -}; - -#define E_CELL_IS_FOCUSED(ecell_view) (ecell_view->focus_x1 != -1) - -struct _ECell { - GObject parent; -}; - -struct _ECellClass { - GObjectClass parent_class; - - ECellView * (*new_view) (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view); - void (*kill_view) (ECellView *ecell_view); - - void (*realize) (ECellView *ecell_view); - void (*unrealize) (ECellView *ecell_view); - - void (*draw) (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2); - gint (*event) (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions); - void (*focus) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gint x1, - gint y1, - gint x2, - gint y2); - void (*unfocus) (ECellView *ecell_view); - gint (*height) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); - - gpointer (*enter_edit) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); - void (*leave_edit) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context); - gpointer (*save_state) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context); - void (*load_state) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer context, - gpointer save_state); - void (*free_state) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer save_state); - void (*print) (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height); - gdouble (*print_height) (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width); - gint (*max_width) (ECellView *ecell_view, - gint model_col, - gint view_col); - gint (*max_width_by_row) (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); - gchar * (*get_bg_color) (ECellView *ecell_view, - gint row); - - void (*style_set) (ECellView *ecell_view, - GtkStyle *previous_style); -}; - -GType e_cell_get_type (void) G_GNUC_CONST; - -/* View creation methods. */ -ECellView * e_cell_new_view (ECell *ecell, - ETableModel *table_model, - gpointer e_table_item_view); -void e_cell_kill_view (ECellView *ecell_view); - -/* Cell View methods. */ -gint e_cell_event (ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - ECellActions *actions); -void e_cell_realize (ECellView *ecell_view); -void e_cell_unrealize (ECellView *ecell_view); -void e_cell_draw (ECellView *ecell_view, - cairo_t *cr, - gint model_col, - gint view_col, - gint row, - ECellFlags flags, - gint x1, - gint y1, - gint x2, - gint y2); -void e_cell_print (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width, - gdouble height); -gdouble e_cell_print_height (ECellView *ecell_view, - GtkPrintContext *context, - gint model_col, - gint view_col, - gint row, - gdouble width); -gint e_cell_max_width (ECellView *ecell_view, - gint model_col, - gint view_col); -gint e_cell_max_width_by_row (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); -gboolean e_cell_max_width_by_row_implemented - (ECellView *ecell_view); -gchar * e_cell_get_bg_color (ECellView *ecell_view, - gint row); -void e_cell_style_set (ECellView *ecell_view, - GtkStyle *previous_style); - -void e_cell_focus (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gint x1, - gint y1, - gint x2, - gint y2); -void e_cell_unfocus (ECellView *ecell_view); -gint e_cell_height (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); -gpointer e_cell_enter_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row); -void e_cell_leave_edit (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context); -gpointer e_cell_save_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context); -void e_cell_load_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer edit_context, - gpointer state); -void e_cell_free_state (ECellView *ecell_view, - gint model_col, - gint view_col, - gint row, - gpointer state); - -G_END_DECLS - -#endif /* _E_CELL_H_ */ diff --git a/widgets/table/e-popup-menu.c b/widgets/table/e-popup-menu.c deleted file mode 100644 index 3e82496748..0000000000 --- a/widgets/table/e-popup-menu.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Jody Goldberg (jgoldberg@home.com) - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <libintl.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "e-popup-menu.h" - -/* - * Creates an item with an optional icon - */ -static void -make_item (GtkMenu *menu, - GtkMenuItem *item, - const gchar *name) -{ - GtkWidget *label; - - if (*name == '\0') - return; - - /* - * Ugh. This needs to go into Gtk+ - */ - label = gtk_label_new_with_mnemonic (name); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - - gtk_container_add (GTK_CONTAINER (item), label); -} - -GtkMenu * -e_popup_menu_create_with_domain (EPopupMenu *menu_list, - guint32 disable_mask, - guint32 hide_mask, - gpointer default_closure, - const gchar *domain) -{ - GtkMenu *menu = GTK_MENU (gtk_menu_new ()); - gboolean last_item_separator = TRUE; - gint last_non_separator = -1; - gint i; - - for (i = 0; menu_list[i].name; i++) { - if (strcmp ("", menu_list[i].name) && !(menu_list[i].disable_mask & hide_mask)) { - last_non_separator = i; - } - } - - for (i = 0; i <= last_non_separator; i++) { - gboolean separator; - - separator = !strcmp ("", menu_list[i].name); - - if ((!(separator && last_item_separator)) && !(menu_list[i].disable_mask & hide_mask)) { - GtkWidget *item = NULL; - - if (!separator) { - item = gtk_menu_item_new (); - - make_item (menu, GTK_MENU_ITEM (item), dgettext (domain, menu_list[i].name)); - } else { - item = gtk_menu_item_new (); - } - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - if (menu_list[i].fn) - g_signal_connect ( - item, "activate", - G_CALLBACK (menu_list[i].fn), - default_closure); - - if (menu_list[i].disable_mask & disable_mask) - gtk_widget_set_sensitive (item, FALSE); - - gtk_widget_show (item); - - last_item_separator = separator; - } - } - - return menu; -} diff --git a/widgets/table/e-popup-menu.h b/widgets/table/e-popup-menu.h deleted file mode 100644 index 9fd3616eb2..0000000000 --- a/widgets/table/e-popup-menu.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * Jody Goldberg (jgoldberg@home.com) - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_POPUP_MENU_H -#define E_POPUP_MENU_H - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define E_POPUP_SEPARATOR { (gchar *) "", NULL, (NULL), 0 } -#define E_POPUP_TERMINATOR { NULL, NULL, (NULL), 0 } - -#define E_POPUP_ITEM(name,fn,disable_mask) \ - { (gchar *) (name), NULL, (fn), (disable_mask) } - -typedef struct _EPopupMenu EPopupMenu; - -struct _EPopupMenu { - gchar *name; - gchar *pixname; - GCallback fn; - guint32 disable_mask; -}; - -GtkMenu * e_popup_menu_create_with_domain (EPopupMenu *menu_list, - guint32 disable_mask, - guint32 hide_mask, - gpointer default_closure, - const gchar *domain); - -G_END_DECLS - -#endif /* E_POPUP_MENU_H */ diff --git a/widgets/table/e-table-click-to-add.c b/widgets/table/e-table-click-to-add.c deleted file mode 100644 index b08d3fcf39..0000000000 --- a/widgets/table/e-table-click-to-add.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include "gal-a11y-e-table-click-to-add.h" -#include "text/e-text.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas-utils.h" -#include "misc/e-canvas.h" - -#include "e-table-click-to-add.h" -#include "e-table-defines.h" -#include "e-table-header.h" -#include "e-table-one.h" - -enum { - CURSOR_CHANGE, - STYLE_SET, - LAST_SIGNAL -}; - -static guint etcta_signals[LAST_SIGNAL] = { 0 }; - -/* workaround for avoiding APi breakage */ -#define etcta_get_type e_table_click_to_add_get_type -G_DEFINE_TYPE (ETableClickToAdd, etcta, GNOME_TYPE_CANVAS_GROUP) - -enum { - PROP_0, - PROP_HEADER, - PROP_MODEL, - PROP_MESSAGE, - PROP_WIDTH, - PROP_HEIGHT -}; - -static void -etcta_cursor_change (GObject *object, - gint row, - gint col, - ETableClickToAdd *etcta) -{ - g_signal_emit ( - etcta, - etcta_signals[CURSOR_CHANGE], 0, - row, col); -} - -static void -etcta_style_set (ETableClickToAdd *etcta, - GtkStyle *previous_style) -{ - GtkWidget *widget; - GtkStyle *style; - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etcta)->canvas); - style = gtk_widget_get_style (widget); - - if (etcta->rect) - gnome_canvas_item_set ( - etcta->rect, - "outline_color_gdk", &style->fg[GTK_STATE_NORMAL], - "fill_color_gdk", &style->bg[GTK_STATE_NORMAL], - NULL); - - if (etcta->text) - gnome_canvas_item_set ( - etcta->text, - "fill_color_gdk", &style->text[GTK_STATE_NORMAL], - NULL); -} - -static void -etcta_add_table_header (ETableClickToAdd *etcta, - ETableHeader *header) -{ - etcta->eth = header; - if (etcta->eth) - g_object_ref (etcta->eth); - if (etcta->row) - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etcta->row), - "ETableHeader", header, - NULL); -} - -static void -etcta_drop_table_header (ETableClickToAdd *etcta) -{ - if (!etcta->eth) - return; - - g_object_unref (etcta->eth); - etcta->eth = NULL; -} - -static void -etcta_add_one (ETableClickToAdd *etcta, - ETableModel *one) -{ - etcta->one = one; - if (etcta->one) - g_object_ref (etcta->one); - if (etcta->row) - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etcta->row), - "ETableModel", one, - NULL); - g_object_set ( - etcta->selection, - "model", one, - NULL); -} - -static void -etcta_drop_one (ETableClickToAdd *etcta) -{ - if (!etcta->one) - return; - g_object_unref (etcta->one); - etcta->one = NULL; - g_object_set ( - etcta->selection, - "model", NULL, - NULL); -} - -static void -etcta_add_model (ETableClickToAdd *etcta, - ETableModel *model) -{ - etcta->model = model; - if (etcta->model) - g_object_ref (etcta->model); -} - -static void -etcta_drop_model (ETableClickToAdd *etcta) -{ - etcta_drop_one (etcta); - if (!etcta->model) - return; - g_object_unref (etcta->model); - etcta->model = NULL; -} - -static void -etcta_add_message (ETableClickToAdd *etcta, - const gchar *message) -{ - etcta->message = g_strdup (message); -} - -static void -etcta_drop_message (ETableClickToAdd *etcta) -{ - g_free (etcta->message); - etcta->message = NULL; -} - -static void -etcta_dispose (GObject *object) -{ - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (object); - - etcta_drop_table_header (etcta); - etcta_drop_model (etcta); - etcta_drop_message (etcta); - if (etcta->selection) - g_object_unref (etcta->selection); - etcta->selection = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etcta_parent_class)->dispose (object); -} - -static void -etcta_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - ETableClickToAdd *etcta; - - item = GNOME_CANVAS_ITEM (object); - etcta = E_TABLE_CLICK_TO_ADD (object); - - switch (property_id) { - case PROP_HEADER: - etcta_drop_table_header (etcta); - etcta_add_table_header (etcta, E_TABLE_HEADER (g_value_get_object (value))); - break; - case PROP_MODEL: - etcta_drop_model (etcta); - etcta_add_model (etcta, E_TABLE_MODEL (g_value_get_object (value))); - break; - case PROP_MESSAGE: - etcta_drop_message (etcta); - etcta_add_message (etcta, g_value_get_string (value)); - break; - case PROP_WIDTH: - etcta->width = g_value_get_double (value); - if (etcta->row) - gnome_canvas_item_set ( - etcta->row, - "minimum_width", etcta->width, - NULL); - if (etcta->text) - gnome_canvas_item_set ( - etcta->text, - "width", (etcta->width < 4 ? 4 : etcta->width) - 4, - NULL); - if (etcta->rect) - gnome_canvas_item_set ( - etcta->rect, - "x2", etcta->width - 1, - NULL); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - return; - - } - gnome_canvas_item_request_update (item); -} - -static void -create_rect_and_text (ETableClickToAdd *etcta) -{ - GtkWidget *widget; - GtkStyle *style; - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etcta)->canvas); - style = gtk_widget_get_style (widget); - - if (!etcta->rect) - etcta->rect = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etcta), - gnome_canvas_rect_get_type (), - "x1", (gdouble) 0, - "y1", (gdouble) 0, - "x2", (gdouble) etcta->width - 1, - "y2", (gdouble) etcta->height - 1, - "outline_color_gdk", &style->fg[GTK_STATE_NORMAL], - "fill_color_gdk", &style->bg[GTK_STATE_NORMAL], - NULL); - - if (!etcta->text) - etcta->text = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etcta), - e_text_get_type (), - "text", etcta->message ? etcta->message : "", - "width", etcta->width - 4, - "fill_color_gdk", &style->text[GTK_STATE_NORMAL], - NULL); -} - -static void -etcta_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableClickToAdd *etcta; - - etcta = E_TABLE_CLICK_TO_ADD (object); - - switch (property_id) { - case PROP_HEADER: - g_value_set_object (value, etcta->eth); - break; - case PROP_MODEL: - g_value_set_object (value, etcta->model); - break; - case PROP_MESSAGE: - g_value_set_string (value, etcta->message); - break; - case PROP_WIDTH: - g_value_set_double (value, etcta->width); - break; - case PROP_HEIGHT: - g_value_set_double (value, etcta->height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -etcta_realize (GnomeCanvasItem *item) -{ - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item); - - create_rect_and_text (etcta); - e_canvas_item_move_absolute (etcta->text, 2, 2); - - if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize) - (*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)(item); - - e_canvas_item_request_reflow (item); -} - -static void -etcta_unrealize (GnomeCanvasItem *item) -{ - if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)(item); -} - -static void finish_editing (ETableClickToAdd *etcta); - -static gint -item_key_press (ETableItem *item, - gint row, - gint col, - GdkEvent *event, - ETableClickToAdd *etcta) -{ - switch (event->key.keyval) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_ISO_Enter: - case GDK_KEY_3270_Enter: - finish_editing (etcta); - return TRUE; - } - return FALSE; -} - -static void -set_initial_selection (ETableClickToAdd *etcta) -{ - e_selection_model_do_something ( - E_SELECTION_MODEL (etcta->selection), - 0, e_table_header_prioritized_column (etcta->eth), - 0); -} - -static void -finish_editing (ETableClickToAdd *etcta) -{ - if (etcta->row) { - ETableModel *one; - - e_table_item_leave_edit (E_TABLE_ITEM (etcta->row)); - e_table_one_commit (E_TABLE_ONE (etcta->one)); - etcta_drop_one (etcta); - g_object_run_dispose (G_OBJECT (etcta->row)); - etcta->row = NULL; - - one = e_table_one_new (etcta->model); - etcta_add_one (etcta, one); - g_object_unref (one); - - e_selection_model_clear (E_SELECTION_MODEL (etcta->selection)); - - etcta->row = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etcta), - e_table_item_get_type (), - "ETableHeader", etcta->eth, - "ETableModel", etcta->one, - "minimum_width", etcta->width, - "horizontal_draw_grid", TRUE, - "vertical_draw_grid", TRUE, - "selection_model", etcta->selection, - "cursor_mode", E_CURSOR_SPREADSHEET, - NULL); - - g_signal_connect ( - etcta->row, "key_press", - G_CALLBACK (item_key_press), etcta); - - set_initial_selection (etcta); - } -} - -/* Handles the events on the ETableClickToAdd, particularly - * it creates the ETableItem and passes in some events. */ -static gint -etcta_event (GnomeCanvasItem *item, - GdkEvent *e) -{ - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item); - - switch (e->type) { - case GDK_FOCUS_CHANGE: - if (!e->focus_change.in) - return TRUE; - - case GDK_BUTTON_PRESS: - if (etcta->text) { - g_object_run_dispose (G_OBJECT (etcta->text)); - etcta->text = NULL; - } - if (etcta->rect) { - g_object_run_dispose (G_OBJECT (etcta->rect)); - etcta->rect = NULL; - } - if (!etcta->row) { - ETableModel *one; - - one = e_table_one_new (etcta->model); - etcta_add_one (etcta, one); - g_object_unref (one); - - e_selection_model_clear (E_SELECTION_MODEL (etcta->selection)); - - etcta->row = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (item), - e_table_item_get_type (), - "ETableHeader", etcta->eth, - "ETableModel", etcta->one, - "minimum_width", etcta->width, - "horizontal_draw_grid", TRUE, - "vertical_draw_grid", TRUE, - "selection_model", etcta->selection, - "cursor_mode", E_CURSOR_SPREADSHEET, - NULL); - - g_signal_connect ( - etcta->row, "key_press", - G_CALLBACK (item_key_press), etcta); - - e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etcta->row), TRUE); - - set_initial_selection (etcta); - } - break; - - case GDK_KEY_PRESS: - switch (e->key.keyval) { - case GDK_KEY_Tab: - case GDK_KEY_KP_Tab: - case GDK_KEY_ISO_Left_Tab: - finish_editing (etcta); - break; - default: - return FALSE; - case GDK_KEY_Escape: - if (etcta->row) { - e_table_item_leave_edit (E_TABLE_ITEM (etcta->row)); - etcta_drop_one (etcta); - g_object_run_dispose (G_OBJECT (etcta->row)); - etcta->row = NULL; - create_rect_and_text (etcta); - e_canvas_item_move_absolute (etcta->text, 3, 3); - } - break; - } - break; - - default: - return FALSE; - } - return TRUE; -} - -static void -etcta_reflow (GnomeCanvasItem *item, - gint flags) -{ - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item); - - gdouble old_height = etcta->height; - - if (etcta->text) { - g_object_get ( - etcta->text, - "height", &etcta->height, - NULL); - etcta->height += 6; - } - if (etcta->row) { - g_object_get ( - etcta->row, - "height", &etcta->height, - NULL); - } - - if (etcta->rect) { - g_object_set ( - etcta->rect, - "y2", etcta->height - 1, - NULL); - } - - if (old_height != etcta->height) - e_canvas_item_request_parent_reflow (item); -} - -static void -etcta_class_init (ETableClickToAddClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - class->cursor_change = NULL; - class->style_set = etcta_style_set; - - object_class->dispose = etcta_dispose; - object_class->set_property = etcta_set_property; - object_class->get_property = etcta_get_property; - - item_class->realize = etcta_realize; - item_class->unrealize = etcta_unrealize; - item_class->event = etcta_event; - - g_object_class_install_property ( - object_class, - PROP_HEADER, - g_param_spec_object ( - "header", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Model", - NULL, - E_TYPE_TABLE_MODEL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MESSAGE, - g_param_spec_string ( - "message", - "Message", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - NULL, - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE | - G_PARAM_LAX_VALIDATION)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - NULL, - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE | - G_PARAM_LAX_VALIDATION)); - - etcta_signals[CURSOR_CHANGE] = g_signal_new ( - "cursor_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClickToAddClass, cursor_change), - NULL, NULL, - e_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - etcta_signals[STYLE_SET] = g_signal_new ( - "style_set", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClickToAddClass, style_set), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_STYLE); - - gal_a11y_e_table_click_to_add_init (); -} - -static void -etcta_init (ETableClickToAdd *etcta) -{ - AtkObject *a11y; - - etcta->one = NULL; - etcta->model = NULL; - etcta->eth = NULL; - - etcta->message = NULL; - - etcta->row = NULL; - etcta->text = NULL; - etcta->rect = NULL; - - /* Pick some arbitrary defaults. */ - etcta->width = 12; - etcta->height = 6; - - etcta->selection = e_table_selection_model_new (); - g_signal_connect ( - etcta->selection, "cursor_changed", - G_CALLBACK (etcta_cursor_change), etcta); - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etcta), etcta_reflow); - - /* create its a11y object at this time if accessibility is enabled*/ - if (atk_get_root () != NULL) { - a11y = atk_gobject_accessible_for_object (G_OBJECT (etcta)); - atk_object_set_name (a11y, _("click to add")); - } -} - -/* The colors in this need to be themefied. */ -/** - * e_table_click_to_add_commit: - * @etcta: The %ETableClickToAdd to commit. - * - * This routine commits the current thing being edited and returns to - * just displaying the click to add message. - **/ -void -e_table_click_to_add_commit (ETableClickToAdd *etcta) -{ - if (etcta->row) { - e_table_one_commit (E_TABLE_ONE (etcta->one)); - etcta_drop_one (etcta); - g_object_run_dispose (G_OBJECT (etcta->row)); - etcta->row = NULL; - } - create_rect_and_text (etcta); - e_canvas_item_move_absolute (etcta->text, 3, 3); -} diff --git a/widgets/table/e-table-click-to-add.h b/widgets/table/e-table-click-to-add.h deleted file mode 100644 index b92672d387..0000000000 --- a/widgets/table/e-table-click-to-add.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_CLICK_TO_ADD_H_ -#define _E_TABLE_CLICK_TO_ADD_H_ - -#include <libxml/tree.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-table-header.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-item.h> -#include <table/e-table-selection-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_CLICK_TO_ADD \ - (e_table_click_to_add_get_type ()) -#define E_TABLE_CLICK_TO_ADD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_CLICK_TO_ADD, ETableClickToAdd)) -#define E_TABLE_CLICK_TO_ADD_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_CLICK_TO_ADD, ETableClickToAddClass)) -#define E_IS_TABLE_CLICK_TO_ADD(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_CLICK_TO_ADD)) -#define E_IS_TABLE_CLICK_TO_ADD_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_CLICK_TO_ADD)) -#define E_TABLE_CLICK_TO_ADD_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_CLICK_TO_ADD, ETableClickToAddClass)) - -G_BEGIN_DECLS - -typedef struct _ETableClickToAdd ETableClickToAdd; -typedef struct _ETableClickToAddClass ETableClickToAddClass; - -struct _ETableClickToAdd { - GnomeCanvasGroup parent; - - ETableModel *one; /* The ETableOne. */ - - ETableModel *model; /* The backend model. */ - ETableHeader *eth; /* This is just to give to the ETableItem. */ - - gchar *message; - - GnomeCanvasItem *row; /* If row is NULL, we're sitting with - * no data and a "Click here" message. */ - GnomeCanvasItem *text; /* If text is NULL, row shouldn't be. */ - GnomeCanvasItem *rect; /* What the heck. Why not. */ - - gdouble width; - gdouble height; - - ETableSelectionModel *selection; -}; - -struct _ETableClickToAddClass { - GnomeCanvasGroupClass parent_class; - - /* Signals */ - void (*cursor_change) (ETableClickToAdd *etcta, - gint row, - gint col); - void (*style_set) (ETableClickToAdd *etcta, - GtkStyle *previous_style); -}; - -GType e_table_click_to_add_get_type (void) G_GNUC_CONST; -void e_table_click_to_add_commit (ETableClickToAdd *etcta); - -G_END_DECLS - -#endif /* _E_TABLE_CLICK_TO_ADD_H_ */ diff --git a/widgets/table/e-table-col-dnd.h b/widgets/table/e-table-col-dnd.h deleted file mode 100644 index 100a4d94d9..0000000000 --- a/widgets/table/e-table-col-dnd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_COL_DND_H_ -#define _E_TABLE_COL_DND_H_ - -#include <glib.h> - -G_BEGIN_DECLS - -#define TARGET_ETABLE_COL_TYPE "application/x-etable-column-header" - -enum { - TARGET_ETABLE_COL_HEADER -}; - -G_END_DECLS - -#endif /* _E_TABLE_COL_DND_H_ */ diff --git a/widgets/table/e-table-col.c b/widgets/table/e-table-col.c deleted file mode 100644 index 823aba415d..0000000000 --- a/widgets/table/e-table-col.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-table-col.h" - -G_DEFINE_TYPE (ETableCol, e_table_col, G_TYPE_OBJECT) - -enum { - PROP_0, - PROP_COMPARE_COL -}; - -static void -etc_load_icon (ETableCol *etc) -{ - /* FIXME This ignores theme changes. */ - - GtkIconTheme *icon_theme; - gint width, height; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - - etc->pixbuf = gtk_icon_theme_load_icon ( - icon_theme, etc->icon_name, height, 0, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } -} - -static void -etc_dispose (GObject *object) -{ - ETableCol *etc = E_TABLE_COL (object); - - if (etc->ecell) - g_object_unref (etc->ecell); - etc->ecell = NULL; - - if (etc->pixbuf) - g_object_unref (etc->pixbuf); - etc->pixbuf = NULL; - - g_free (etc->text); - etc->text = NULL; - - g_free (etc->icon_name); - etc->icon_name = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_table_col_parent_class)->dispose (object); -} - -static void -etc_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableCol *etc = E_TABLE_COL (object); - - switch (property_id) { - case PROP_COMPARE_COL: - etc->compare_col = g_value_get_int (value); - break; - default: - break; - } -} - -static void -etc_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableCol *etc = E_TABLE_COL (object); - - switch (property_id) { - case PROP_COMPARE_COL: - g_value_set_int (value, etc->compare_col); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_table_col_class_init (ETableColClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etc_dispose; - object_class->set_property = etc_set_property; - object_class->get_property = etc_get_property; - - g_object_class_install_property ( - object_class, - PROP_COMPARE_COL, - g_param_spec_int ( - "compare_col", - "Width", - "Width", - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); -} - -static void -e_table_col_init (ETableCol *etc) -{ - etc->width = 0; - etc->sortable = 1; - etc->groupable = 1; - etc->justification = GTK_JUSTIFY_LEFT; - etc->priority = 0; -} - -/** - * e_table_col_new: - * @col_idx: the column we represent in the model - * @text: a title for this column - * @icon_name: name of the icon to be used for the header, or %NULL - * @expansion: FIXME - * @min_width: minimum width in pixels for this column - * @ecell: the renderer to be used for this column - * @compare: comparision function for the elements stored in this column - * @resizable: whether the column can be resized interactively by the user - * @priority: FIXME - * - * The ETableCol represents a column to be used inside an ETable. The - * ETableCol objects are inserted inside an ETableHeader (which is just a - * collection of ETableCols). The ETableHeader is the definition of the - * order in which columns are shown to the user. - * - * The @text argument is the the text that will be shown as a header to the - * user. @col_idx reflects where the data for this ETableCol object will - * be fetch from an ETableModel. So even if the user changes the order - * of the columns being viewed (the ETableCols in the ETableHeader), the - * column will always point to the same column inside the ETableModel. - * - * The @ecell argument is an ECell object that needs to know how to - * render the data in the ETableModel for this specific row. - * - * Data passed to @compare can be (if not %NULL) a cmp_cache, which - * can be accessed by e_table_sorting_utils_add_to_cmp_cache() and - * e_table_sorting_utils_lookup_cmp_cache(). - * - * Returns: the newly created ETableCol object. - */ -ETableCol * -e_table_col_new (gint col_idx, - const gchar *text, - const gchar *icon_name, - gdouble expansion, - gint min_width, - ECell *ecell, - GCompareDataFunc compare, - gboolean resizable, - gboolean disabled, - gint priority) -{ - ETableCol *etc; - - g_return_val_if_fail (expansion >= 0, NULL); - g_return_val_if_fail (min_width >= 0, NULL); - g_return_val_if_fail (ecell != NULL, NULL); - g_return_val_if_fail (compare != NULL, NULL); - g_return_val_if_fail (text != NULL, NULL); - - etc = g_object_new (E_TYPE_TABLE_COL, NULL); - - etc->col_idx = col_idx; - etc->compare_col = col_idx; - etc->text = g_strdup (text); - etc->icon_name = g_strdup (icon_name); - etc->pixbuf = NULL; - etc->expansion = expansion; - etc->min_width = min_width; - etc->ecell = ecell; - etc->compare = compare; - etc->disabled = disabled; - etc->priority = priority; - - etc->selected = 0; - etc->resizable = resizable; - - g_object_ref (etc->ecell); - - if (etc->icon_name != NULL) - etc_load_icon (etc); - - return etc; -} diff --git a/widgets/table/e-table-col.h b/widgets/table/e-table-col.h deleted file mode 100644 index 042137b40a..0000000000 --- a/widgets/table/e-table-col.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TABLE_COL_H -#define E_TABLE_COL_H - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <table/e-cell.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_COL \ - (e_table_col_get_type ()) -#define E_TABLE_COL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_COL, ETableCol)) -#define E_TABLE_COL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_COL, ETableColClass)) -#define E_IS_TABLE_COL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_COL)) -#define E_IS_TABLE_COL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_COL)) -#define E_TABLE_COL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_COL, ETableColClass)) - -G_BEGIN_DECLS - -typedef enum { - E_TABLE_COL_ARROW_NONE = 0, - E_TABLE_COL_ARROW_UP, - E_TABLE_COL_ARROW_DOWN -} ETableColArrow; - -typedef struct _ETableCol ETableCol; -typedef struct _ETableColClass ETableColClass; - -/* - * Information about a single column - */ -struct _ETableCol { - GObject parent; - - gchar *text; - gchar *icon_name; - GdkPixbuf *pixbuf; - gint min_width; - gint width; - gdouble expansion; - gshort x; - GCompareDataFunc compare; - ETableSearchFunc search; - - guint selected : 1; - guint resizable : 1; - guint disabled : 1; - guint sortable : 1; - guint groupable : 1; - - gint col_idx; - gint compare_col; - gint priority; - - GtkJustification justification; - - ECell *ecell; -}; - -struct _ETableColClass { - GObjectClass parent_class; -}; - -GType e_table_col_get_type (void) G_GNUC_CONST; -ETableCol * e_table_col_new (gint col_idx, - const gchar *text, - const gchar *icon_name, - gdouble expansion, - gint min_width, - ECell *ecell, - GCompareDataFunc compare, - gboolean resizable, - gboolean disabled, - gint priority); - -G_END_DECLS - -#endif /* E_TABLE_COL_H */ - diff --git a/widgets/table/e-table-column-specification.c b/widgets/table/e-table-column-specification.c deleted file mode 100644 index 033b693073..0000000000 --- a/widgets/table/e-table-column-specification.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * e-table-column-specification.c - Savable specification of a column. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-column-specification.h" - -/* workaround for avoiding API breakage */ -#define etcs_get_type e_table_column_specification_get_type -G_DEFINE_TYPE (ETableColumnSpecification, etcs, G_TYPE_OBJECT) - -static void -free_strings (ETableColumnSpecification *etcs) -{ - g_free (etcs->title); - etcs->title = NULL; - g_free (etcs->pixbuf); - etcs->pixbuf = NULL; - g_free (etcs->cell); - etcs->cell = NULL; - g_free (etcs->compare); - etcs->compare = NULL; - g_free (etcs->search); - etcs->search = NULL; - g_free (etcs->sortable); - etcs->sortable = NULL; -} - -static void -etcs_finalize (GObject *object) -{ - ETableColumnSpecification *etcs = E_TABLE_COLUMN_SPECIFICATION (object); - - free_strings (etcs); - - G_OBJECT_CLASS (etcs_parent_class)->finalize (object); -} - -static void -etcs_class_init (ETableColumnSpecificationClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->finalize = etcs_finalize; -} - -static void -etcs_init (ETableColumnSpecification *specification) -{ - specification->model_col = 0; - specification->compare_col = 0; - specification->title = g_strdup (""); - specification->pixbuf = NULL; - - specification->expansion = 0; - specification->minimum_width = 0; - specification->resizable = FALSE; - specification->disabled = FALSE; - - specification->cell = NULL; - specification->compare = NULL; - specification->search = NULL; - specification->priority = 0; -} - -ETableColumnSpecification * -e_table_column_specification_new (void) -{ - return g_object_new (E_TYPE_TABLE_COLUMN_SPECIFICATION, NULL); -} - -void -e_table_column_specification_load_from_node (ETableColumnSpecification *etcs, - const xmlNode *node) -{ - free_strings (etcs); - - etcs->model_col = e_xml_get_integer_prop_by_name (node, (const guchar *)"model_col"); - etcs->compare_col = e_xml_get_integer_prop_by_name_with_default (node, (const guchar *)"compare_col", etcs->model_col); - etcs->title = e_xml_get_string_prop_by_name (node, (const guchar *)"_title"); - etcs->pixbuf = e_xml_get_string_prop_by_name (node, (const guchar *)"pixbuf"); - - etcs->expansion = e_xml_get_double_prop_by_name (node, (const guchar *)"expansion"); - etcs->minimum_width = e_xml_get_integer_prop_by_name (node, (const guchar *)"minimum_width"); - etcs->resizable = e_xml_get_bool_prop_by_name (node, (const guchar *)"resizable"); - etcs->disabled = e_xml_get_bool_prop_by_name (node, (const guchar *)"disabled"); - - etcs->cell = e_xml_get_string_prop_by_name (node, (const guchar *)"cell"); - etcs->compare = e_xml_get_string_prop_by_name (node, (const guchar *)"compare"); - etcs->search = e_xml_get_string_prop_by_name (node, (const guchar *)"search"); - etcs->sortable = e_xml_get_string_prop_by_name (node, (const guchar *)"sortable"); - etcs->priority = e_xml_get_integer_prop_by_name_with_default (node, (const guchar *)"priority", 0); - - if (etcs->title == NULL) - etcs->title = g_strdup (""); -} - -xmlNode * -e_table_column_specification_save_to_node (ETableColumnSpecification *specification, - xmlNode *parent) -{ - xmlNode *node; - if (parent) - node = xmlNewChild (parent, NULL, (const guchar *)"ETableColumn", NULL); - else - node = xmlNewNode (NULL, (const guchar *)"ETableColumn"); - - e_xml_set_integer_prop_by_name (node, (const guchar *)"model_col", specification->model_col); - if (specification->compare_col != specification->model_col) - e_xml_set_integer_prop_by_name (node, (const guchar *)"compare_col", specification->compare_col); - e_xml_set_string_prop_by_name (node, (const guchar *)"_title", specification->title); - e_xml_set_string_prop_by_name (node, (const guchar *)"pixbuf", specification->pixbuf); - - e_xml_set_double_prop_by_name (node, (const guchar *)"expansion", specification->expansion); - e_xml_set_integer_prop_by_name (node, (const guchar *)"minimum_width", specification->minimum_width); - e_xml_set_bool_prop_by_name (node, (const guchar *)"resizable", specification->resizable); - e_xml_set_bool_prop_by_name (node, (const guchar *)"disabled", specification->disabled); - - e_xml_set_string_prop_by_name (node, (const guchar *)"cell", specification->cell); - e_xml_set_string_prop_by_name (node, (const guchar *)"compare", specification->compare); - e_xml_set_string_prop_by_name (node, (const guchar *)"search", specification->search); - if (specification->priority != 0) - e_xml_set_integer_prop_by_name (node, (const guchar *)"priority", specification->priority); - - return node; -} - diff --git a/widgets/table/e-table-column-specification.h b/widgets/table/e-table-column-specification.h deleted file mode 100644 index e20d7de6b5..0000000000 --- a/widgets/table/e-table-column-specification.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_COLUMN_SPECIFICATION_H_ -#define _E_TABLE_COLUMN_SPECIFICATION_H_ - -#include <glib-object.h> -#include <libxml/tree.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_COLUMN_SPECIFICATION \ - (e_table_column_specification_get_type ()) -#define E_TABLE_COLUMN_SPECIFICATION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_COLUMN_SPECIFICATION, ETableColumnSpecification)) -#define E_TABLE_COLUMN_SPECIFICATION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_COLUMN_SPECIFICATION, ETableColumnSpecificationClass)) -#define E_IS_TABLE_COLUMN_SPECIFICATION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_COLUMN_SPECIFICATION)) -#define E_IS_TABLE_COLUMN_SPECIFICATION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_COLUMN_SPECIFICATION)) -#define E_TABLE_COLUMN_SPECIFICATION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_COLUMN_SPECIFICATION, ETableColumnSpecificationClass)) - -G_BEGIN_DECLS - -typedef struct _ETableColumnSpecification ETableColumnSpecification; -typedef struct _ETableColumnSpecificationClass ETableColumnSpecificationClass; - -struct _ETableColumnSpecification { - GObject parent; - - gint model_col; - gint compare_col; - gchar *title; - gchar *pixbuf; - - gdouble expansion; - gint minimum_width; - guint resizable : 1; - guint disabled : 1; - - gchar *cell; - gchar *compare; - gchar *search; - gchar *sortable; - gint priority; -}; - -struct _ETableColumnSpecificationClass { - GObjectClass parent_class; -}; - -GType e_table_column_specification_get_type (void) G_GNUC_CONST; -ETableColumnSpecification * - e_table_column_specification_new (void); -void e_table_column_specification_load_from_node - (ETableColumnSpecification *state, - const xmlNode *node); -xmlNode * e_table_column_specification_save_to_node - (ETableColumnSpecification *state, - xmlNode *parent); - -G_END_DECLS - -#endif /* _E_TABLE_COLUMN_SPECIFICATION_H_ */ diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c deleted file mode 100644 index 3be7539ada..0000000000 --- a/widgets/table/e-table-config.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * FIXME: - * Sort Dialog: when text is selected, the toggle button switches state. - * Make Clear all work. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util-private.h" -#include "e-util/e-util.h" -#include "e-util/e-unicode.h" - -#include "e-table-config.h" -#include "e-table-memory-store.h" -#include "e-table-without.h" - -G_DEFINE_TYPE (ETableConfig, e_table_config, G_TYPE_OBJECT) - -enum { - CHANGED, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_STATE -}; - -enum { - COLUMN_ITEM, - COLUMN_VALUE -}; - -static guint e_table_config_signals[LAST_SIGNAL] = { 0, }; - -static void -config_finalize (GObject *object) -{ - ETableConfig *config = E_TABLE_CONFIG (object); - - if (config->state) - g_object_unref (config->state); - config->state = NULL; - - if (config->source_state) - g_object_unref (config->source_state); - config->source_state = NULL; - - if (config->source_spec) - g_object_unref (config->source_spec); - config->source_spec = NULL; - - g_free (config->header); - config->header = NULL; - - g_slist_free (config->column_names); - config->column_names = NULL; - - g_free (config->domain); - config->domain = NULL; - - G_OBJECT_CLASS (e_table_config_parent_class)->finalize (object); -} - -static void -e_table_config_changed (ETableConfig *config, - ETableState *state) -{ - g_return_if_fail (E_IS_TABLE_CONFIG (config)); - - g_signal_emit (config, e_table_config_signals[CHANGED], 0, state); -} - -static void -config_dialog_changed (ETableConfig *config) -{ - /* enable the apply/ok buttons */ - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (config->dialog_toplevel), - GTK_RESPONSE_APPLY, TRUE); - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (config->dialog_toplevel), - GTK_RESPONSE_OK, TRUE); -} - -static void -config_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableConfig *config = E_TABLE_CONFIG (object); - - switch (property_id) { - case PROP_STATE: - g_value_set_object (value, config->state); - break; - default: - break; - } -} - -static void -e_table_config_class_init (ETableConfigClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - class->changed = NULL; - - object_class->finalize = config_finalize; - object_class->get_property = config_get_property; - - e_table_config_signals[CHANGED] = g_signal_new ( - "changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableConfigClass, changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_object_class_install_property ( - object_class, - PROP_STATE, - g_param_spec_object ( - "state", - "State", - NULL, - E_TYPE_TABLE_STATE, - G_PARAM_READABLE)); -} - -static void -configure_combo_box_add (GtkComboBox *combo_box, - const gchar *item, - const gchar *value) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GHashTable *index; - GtkTreeIter iter; - - model = gtk_combo_box_get_model (combo_box); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - COLUMN_ITEM, item, COLUMN_VALUE, value, -1); - - index = g_object_get_data (G_OBJECT (combo_box), "index"); - g_return_if_fail (index != NULL); - - /* Add an entry to the tree model index. */ - path = gtk_tree_model_get_path (model, &iter); - reference = gtk_tree_row_reference_new (model, path); - g_return_if_fail (reference != NULL); - g_hash_table_insert (index, g_strdup (value), reference); - gtk_tree_path_free (path); -} - -static gchar * -configure_combo_box_get_active (GtkComboBox *combo_box) -{ - GtkTreeIter iter; - gchar *value = NULL; - - if (gtk_combo_box_get_active_iter (combo_box, &iter)) - gtk_tree_model_get ( - gtk_combo_box_get_model (combo_box), &iter, - COLUMN_VALUE, &value, -1); - - if (value != NULL && *value == '\0') { - g_free (value); - value = NULL; - } - - return value; -} - -static void -configure_combo_box_set_active (GtkComboBox *combo_box, - const gchar *value) -{ - GtkTreeRowReference *reference; - GHashTable *index; - - index = g_object_get_data (G_OBJECT (combo_box), "index"); - g_return_if_fail (index != NULL); - - reference = g_hash_table_lookup (index, value); - if (reference != NULL) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - - if (path == NULL) - return; - - if (gtk_tree_model_get_iter (model, &iter, path)) - gtk_combo_box_set_active_iter (combo_box, &iter); - - gtk_tree_path_free (path); - } -} - -static ETableColumnSpecification * -find_column_in_spec (ETableSpecification *spec, - gint model_col) -{ - ETableColumnSpecification **column; - - for (column = spec->columns; *column; column++) { - if ((*column)->disabled) - continue; - if ((*column)->model_col != model_col) - continue; - - return *column; - } - - return NULL; -} - -static gint -find_model_column_by_name (ETableSpecification *spec, - const gchar *s) -{ - ETableColumnSpecification **column; - - for (column = spec->columns; *column; column++) { - - if ((*column)->disabled) - continue; - if (g_ascii_strcasecmp ((*column)->title, s) == 0) - return (*column)->model_col; - } - return -1; -} - -static void -update_sort_and_group_config_dialog (ETableConfig *config, - gboolean is_sort) -{ - ETableConfigSortWidgets *widgets; - gint count, i; - - if (is_sort) { - count = e_table_sort_info_sorting_get_count ( - config->temp_state->sort_info); - widgets = &config->sort[0]; - } else { - count = e_table_sort_info_grouping_get_count ( - config->temp_state->sort_info); - widgets = &config->group[0]; - } - - for (i = 0; i < 4; i++) { - gboolean sensitive = (i <= count); - const gchar *text = ""; - - gtk_widget_set_sensitive (widgets[i].frames, sensitive); - - /* - * Sorting is set, auto select the text - */ - g_signal_handler_block ( - widgets[i].radio_ascending, - widgets[i].toggled_id); - g_signal_handler_block ( - widgets[i].combo, - widgets[i].changed_id); - - if (i < count) { - GtkToggleButton *a, *d; - ETableSortColumn col = - is_sort - ? e_table_sort_info_sorting_get_nth ( - config->temp_state->sort_info, - i) - : e_table_sort_info_grouping_get_nth ( - config->temp_state->sort_info, - i); - - ETableColumnSpecification *column = - find_column_in_spec (config->source_spec, col.column); - - if (!column) { - /* - * This is a bug in the programmer - * stuff, but by the time we arrive - * here, the user has been given a - * warning - */ - continue; - } - - text = column->title; - - /* - * Update radio buttons - */ - a = GTK_TOGGLE_BUTTON ( - widgets[i].radio_ascending); - d = GTK_TOGGLE_BUTTON ( - widgets[i].radio_descending); - - gtk_toggle_button_set_active (col.ascending ? a : d, 1); - } else { - GtkToggleButton *t; - - t = GTK_TOGGLE_BUTTON ( - widgets[i].radio_ascending); - - if (is_sort) - g_return_if_fail ( - widgets[i].radio_ascending != - config->group[i].radio_ascending); - else - g_return_if_fail ( - widgets[i].radio_ascending != - config->sort[i].radio_ascending); - gtk_toggle_button_set_active (t, 1); - } - - /* Set the text */ - configure_combo_box_set_active ( - GTK_COMBO_BOX (widgets[i].combo), text); - - g_signal_handler_unblock ( - widgets[i].radio_ascending, - widgets[i].toggled_id); - g_signal_handler_unblock ( - widgets[i].combo, - widgets[i].changed_id); - } -} - -static void -config_sort_info_update (ETableConfig *config) -{ - ETableSortInfo *info = config->state->sort_info; - GString *res; - gint count, i; - - count = e_table_sort_info_sorting_get_count (info); - res = g_string_new (""); - - for (i = 0; i < count; i++) { - ETableSortColumn col = e_table_sort_info_sorting_get_nth (info, i); - ETableColumnSpecification *column; - - column = find_column_in_spec (config->source_spec, col.column); - if (!column) { - g_warning ("Could not find column model in specification"); - continue; - } - - g_string_append (res, dgettext (config->domain, (column)->title)); - g_string_append_c (res, ' '); - g_string_append ( - res, - col.ascending ? - _("(Ascending)") : _("(Descending)")); - - if ((i + 1) != count) - g_string_append (res, ", "); - } - - if (res->str[0] == 0) - g_string_append (res, _("Not sorted")); - - gtk_label_set_text (GTK_LABEL (config->sort_label), res->str); - - g_string_free (res, TRUE); -} - -static void -config_group_info_update (ETableConfig *config) -{ - ETableSortInfo *info = config->state->sort_info; - GString *res; - gint count, i; - - if (!e_table_sort_info_get_can_group (info)) - return; - - count = e_table_sort_info_grouping_get_count (info); - res = g_string_new (""); - - for (i = 0; i < count; i++) { - ETableSortColumn col = e_table_sort_info_grouping_get_nth (info, i); - ETableColumnSpecification *column; - - column = find_column_in_spec (config->source_spec, col.column); - if (!column) { - g_warning ("Could not find model column in specification"); - continue; - } - - g_string_append (res, dgettext (config->domain, (column)->title)); - g_string_append_c (res, ' '); - g_string_append ( - res, - col.ascending ? - _("(Ascending)") : _("(Descending)")); - - if ((i + 1) != count) - g_string_append (res, ", "); - } - if (res->str[0] == 0) - g_string_append (res, _("No grouping")); - - gtk_label_set_text (GTK_LABEL (config->group_label), res->str); - g_string_free (res, TRUE); -} - -static void -setup_fields (ETableConfig *config) -{ - gint i; - - e_table_model_freeze ((ETableModel *) config->available_model); - e_table_model_freeze ((ETableModel *) config->shown_model); - e_table_without_show_all (config->available_model); - e_table_subset_variable_clear (config->shown_model); - - if (config->temp_state) { - for (i = 0; i < config->temp_state->col_count; i++) { - gint j, idx; - for (j = 0, idx = 0; j < config->temp_state->columns[i]; j++) - if (!config->source_spec->columns[j]->disabled) - idx++; - - e_table_subset_variable_add (config->shown_model, idx); - e_table_without_hide (config->available_model, GINT_TO_POINTER (idx)); - } - } - e_table_model_thaw ((ETableModel *) config->available_model); - e_table_model_thaw ((ETableModel *) config->shown_model); -} - -static void -config_fields_info_update (ETableConfig *config) -{ - ETableColumnSpecification **column; - GString *res = g_string_new (""); - gint i, j; - - for (i = 0; i < config->state->col_count; i++) { - for (j = 0, column = config->source_spec->columns; *column; column++, j++) { - - if ((*column)->disabled) - continue; - - if (config->state->columns[i] != j) - continue; - - g_string_append (res, dgettext (config->domain, (*column)->title)); - if (i + 1 < config->state->col_count) - g_string_append (res, ", "); - - break; - } - } - - gtk_label_set_text (GTK_LABEL (config->fields_label), res->str); - g_string_free (res, TRUE); -} - -static void -do_sort_and_group_config_dialog (ETableConfig *config, - gboolean is_sort) -{ - GtkDialog *dialog; - gint response, running = 1; - - config->temp_state = e_table_state_duplicate (config->state); - - update_sort_and_group_config_dialog (config, is_sort); - - gtk_widget_grab_focus (GTK_WIDGET ( - is_sort - ? config->sort[0].combo - : config->group[0].combo)); - - if (is_sort) - dialog = GTK_DIALOG (config->dialog_sort); - else - dialog = GTK_DIALOG (config->dialog_group_by); - - gtk_window_set_transient_for ( - GTK_WINDOW (dialog), GTK_WINDOW (config->dialog_toplevel)); - - do { - response = gtk_dialog_run (dialog); - switch (response) { - case 0: /* clear fields */ - if (is_sort) { - e_table_sort_info_sorting_truncate ( - config->temp_state->sort_info, 0); - } else { - e_table_sort_info_grouping_truncate ( - config->temp_state->sort_info, 0); - } - update_sort_and_group_config_dialog (config, is_sort); - break; - - case GTK_RESPONSE_OK: - g_object_unref (config->state); - config->state = config->temp_state; - config->temp_state = NULL; - running = 0; - config_dialog_changed (config); - break; - - case GTK_RESPONSE_DELETE_EVENT: - case GTK_RESPONSE_CANCEL: - g_object_unref (config->temp_state); - config->temp_state = NULL; - running = 0; - break; - } - - } while (running); - gtk_widget_hide (GTK_WIDGET (dialog)); - - if (is_sort) - config_sort_info_update (config); - else - config_group_info_update (config); -} - -static void -do_fields_config_dialog (ETableConfig *config) -{ - GtkDialog *dialog; - GtkWidget *widget; - gint response, running = 1; - - dialog = GTK_DIALOG (config->dialog_show_fields); - - gtk_widget_ensure_style (config->dialog_show_fields); - - widget = gtk_dialog_get_content_area (dialog); - gtk_container_set_border_width (GTK_CONTAINER (widget), 0); - - widget = gtk_dialog_get_action_area (dialog); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - - config->temp_state = e_table_state_duplicate (config->state); - - setup_fields (config); - - gtk_window_set_transient_for ( - GTK_WINDOW (config->dialog_show_fields), - GTK_WINDOW (config->dialog_toplevel)); - - do { - response = gtk_dialog_run (GTK_DIALOG (config->dialog_show_fields)); - switch (response) { - case GTK_RESPONSE_OK: - g_object_unref (config->state); - config->state = config->temp_state; - config->temp_state = NULL; - running = 0; - config_dialog_changed (config); - break; - - case GTK_RESPONSE_DELETE_EVENT: - case GTK_RESPONSE_CANCEL: - g_object_unref (config->temp_state); - config->temp_state = NULL; - running = 0; - break; - } - - } while (running); - gtk_widget_hide (GTK_WIDGET (config->dialog_show_fields)); - - config_fields_info_update (config); -} - -static ETableMemoryStoreColumnInfo store_columns[] = { - E_TABLE_MEMORY_STORE_STRING, - E_TABLE_MEMORY_STORE_INTEGER, - E_TABLE_MEMORY_STORE_TERMINATOR -}; - -static ETableModel * -create_store (ETableConfig *config) -{ - gint i; - ETableModel *store; - - store = e_table_memory_store_new (store_columns); - for (i = 0; config->source_spec->columns[i]; i++) { - - gchar *text; - - if (config->source_spec->columns[i]->disabled) - continue; - - text = g_strdup (dgettext ( - config->domain, - config->source_spec->columns[i]->title)); - e_table_memory_store_insert_adopt ( - E_TABLE_MEMORY_STORE (store), -1, NULL, text, i); - } - - return store; -} - -static const gchar *spec = -"<ETableSpecification gettext-domain=\"" GETTEXT_PACKAGE "\"" -" no-headers=\"true\" cursor-mode=\"line\" draw-grid=\"false\" " -" draw-focus=\"true\" selection-mode=\"browse\">" -"<ETableColumn model_col= \"0\" _title=\"Name\" minimum_width=\"30\"" -" resizable=\"true\" cell=\"string\" compare=\"string\"/>" -"<ETableState> <column source=\"0\"/>" -"<grouping/>" -"</ETableState>" -"</ETableSpecification>"; - -static GtkWidget * -e_table_proxy_etable_shown_new (ETableModel *store) -{ - ETableModel *model = NULL; - GtkWidget *widget; - - model = e_table_subset_variable_new (store); - - widget = e_table_new (model, NULL, spec, NULL); - - atk_object_set_name ( - gtk_widget_get_accessible (widget), - _("Show Fields")); - - return widget; -} - -static GtkWidget * -e_table_proxy_etable_available_new (ETableModel *store) -{ - ETableModel *model; - GtkWidget *widget; - - model = e_table_without_new ( - store, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - - e_table_without_show_all (E_TABLE_WITHOUT (model)); - - widget = e_table_new (model, NULL, spec, NULL); - - atk_object_set_name ( - gtk_widget_get_accessible (widget), - _("Available Fields")); - - return widget; -} - -static void -config_button_fields (GtkWidget *widget, - ETableConfig *config) -{ - do_fields_config_dialog (config); -} - -static void -config_button_sort (GtkWidget *widget, - ETableConfig *config) -{ - do_sort_and_group_config_dialog (config, TRUE); -} - -static void -config_button_group (GtkWidget *widget, - ETableConfig *config) -{ - do_sort_and_group_config_dialog (config, FALSE); -} - -static void -dialog_destroyed (gpointer data, - GObject *where_object_was) -{ - ETableConfig *config = data; - g_object_unref (config); -} - -static void -dialog_response (GtkWidget *dialog, - gint response_id, - ETableConfig *config) -{ - if (response_id == GTK_RESPONSE_APPLY - || response_id == GTK_RESPONSE_OK) { - e_table_config_changed (config, config->state); - } - - if (response_id == GTK_RESPONSE_CANCEL - || response_id == GTK_RESPONSE_OK) { - gtk_widget_destroy (dialog); - } -} - -/* - * Invoked by the GtkBuilder auto-connect code - */ -static GtkWidget * -e_table_proxy_gtk_combo_text_new (void) -{ - GtkCellRenderer *renderer; - GtkListStore *store; - GtkWidget *combo_box; - GHashTable *index; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start ( - GTK_CELL_LAYOUT (combo_box), renderer, FALSE); - gtk_cell_layout_add_attribute ( - GTK_CELL_LAYOUT (combo_box), renderer, "text", COLUMN_ITEM); - - /* Embed a reverse-lookup index into the widget. */ - index = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gtk_tree_row_reference_free); - g_object_set_data_full ( - G_OBJECT (combo_box), "index", index, - (GDestroyNotify) g_hash_table_destroy); - - return combo_box; -} - -static void -connect_button (ETableConfig *config, - GtkBuilder *builder, - const gchar *widget_name, - GCallback cback) -{ - GtkWidget *button = e_builder_get_widget (builder, widget_name); - - if (button) - g_signal_connect (button, "clicked", cback, config); -} - -static gint -get_source_model_col_index (ETableConfig *config, - gint idx) -{ - gint visible_index; - ETableModel *src_model; - - src_model = E_TABLE_SUBSET (config->available_model)->source; - - visible_index = e_table_subset_view_to_model_row ( - E_TABLE_SUBSET (config->available_model), idx); - - return GPOINTER_TO_INT (e_table_model_value_at (src_model, 1, visible_index)); -} - -static void -sort_combo_changed (GtkComboBox *combo_box, - ETableConfigSortWidgets *sort) -{ - ETableConfig *config = sort->e_table_config; - ETableSortInfo *sort_info = config->temp_state->sort_info; - ETableConfigSortWidgets *base = &config->sort[0]; - GtkToggleButton *toggle_button; - gint idx = sort - base; - gchar *s; - - s = configure_combo_box_get_active (combo_box); - - if (s != NULL) { - ETableSortColumn c; - gint col; - - col = find_model_column_by_name (config->source_spec, s); - if (col == -1) { - g_warning ("sort: This should not happen (%s)", s); - g_free (s); - return; - } - - toggle_button = GTK_TOGGLE_BUTTON ( - config->sort[idx].radio_ascending); - c.ascending = gtk_toggle_button_get_active (toggle_button); - c.column = col; - e_table_sort_info_sorting_set_nth (sort_info, idx, c); - - update_sort_and_group_config_dialog (config, TRUE); - } else { - e_table_sort_info_sorting_truncate (sort_info, idx); - update_sort_and_group_config_dialog (config, TRUE); - } - - g_free (s); -} - -static void -sort_ascending_toggled (GtkToggleButton *t, - ETableConfigSortWidgets *sort) -{ - ETableConfig *config = sort->e_table_config; - ETableSortInfo *si = config->temp_state->sort_info; - ETableConfigSortWidgets *base = &config->sort[0]; - gint idx = sort - base; - ETableSortColumn c; - - c = e_table_sort_info_sorting_get_nth (si, idx); - c.ascending = gtk_toggle_button_get_active (t); - e_table_sort_info_sorting_set_nth (si, idx, c); -} - -static void -configure_sort_dialog (ETableConfig *config, - GtkBuilder *builder) -{ - GSList *l; - gint i; - - const gchar *algs[] = { - "alignment4", - "alignment3", - "alignment2", - "alignment1", - NULL - }; - - for (i = 0; i < 4; i++) { - gchar buffer[80]; - - snprintf (buffer, sizeof (buffer), "sort-combo-%d", i + 1); - config->sort[i].combo = e_table_proxy_gtk_combo_text_new (); - gtk_widget_show (GTK_WIDGET (config->sort[i].combo)); - gtk_container_add ( - GTK_CONTAINER (e_builder_get_widget ( - builder, algs[i])), config->sort[i].combo); - configure_combo_box_add ( - GTK_COMBO_BOX (config->sort[i].combo), "", ""); - - snprintf (buffer, sizeof (buffer), "frame-sort-%d", i + 1); - config->sort[i].frames = - e_builder_get_widget (builder, buffer); - - snprintf ( - buffer, sizeof (buffer), - "radiobutton-ascending-sort-%d", i + 1); - config->sort[i].radio_ascending = e_builder_get_widget ( - builder, buffer); - - snprintf ( - buffer, sizeof (buffer), - "radiobutton-descending-sort-%d", i + 1); - config->sort[i].radio_descending = e_builder_get_widget ( - builder, buffer); - - config->sort[i].e_table_config = config; - } - - for (l = config->column_names; l; l = l->next) { - gchar *label = l->data; - - for (i = 0; i < 4; i++) { - configure_combo_box_add ( - GTK_COMBO_BOX (config->sort[i].combo), - dgettext (config->domain, label), label); - } - } - - /* - * After we have runtime modified things, signal connect - */ - for (i = 0; i < 4; i++) { - config->sort[i].changed_id = g_signal_connect ( - config->sort[i].combo, - "changed", G_CALLBACK (sort_combo_changed), - &config->sort[i]); - - config->sort[i].toggled_id = g_signal_connect ( - config->sort[i].radio_ascending, - "toggled", G_CALLBACK (sort_ascending_toggled), - &config->sort[i]); - } -} - -static void -group_combo_changed (GtkComboBox *combo_box, - ETableConfigSortWidgets *group) -{ - ETableConfig *config = group->e_table_config; - ETableSortInfo *sort_info = config->temp_state->sort_info; - ETableConfigSortWidgets *base = &config->group[0]; - gint idx = group - base; - gchar *s; - - s = configure_combo_box_get_active (combo_box); - - if (s != NULL) { - GtkToggleButton *toggle_button; - ETableSortColumn c; - gint col; - - col = find_model_column_by_name (config->source_spec, s); - if (col == -1) { - g_warning ("grouping: this should not happen, %s", s); - g_free (s); - return; - } - - toggle_button = GTK_TOGGLE_BUTTON ( - config->group[idx].radio_ascending); - c.ascending = gtk_toggle_button_get_active (toggle_button); - c.column = col; - e_table_sort_info_grouping_set_nth (sort_info, idx, c); - - update_sort_and_group_config_dialog (config, FALSE); - } else { - e_table_sort_info_grouping_truncate (sort_info, idx); - update_sort_and_group_config_dialog (config, FALSE); - } - - g_free (s); -} - -static void -group_ascending_toggled (GtkToggleButton *t, - ETableConfigSortWidgets *group) -{ - ETableConfig *config = group->e_table_config; - ETableSortInfo *si = config->temp_state->sort_info; - ETableConfigSortWidgets *base = &config->group[0]; - gint idx = group - base; - ETableSortColumn c; - - c = e_table_sort_info_grouping_get_nth (si, idx); - c.ascending = gtk_toggle_button_get_active (t); - e_table_sort_info_grouping_set_nth (si, idx, c); -} - -static void -configure_group_dialog (ETableConfig *config, - GtkBuilder *builder) -{ - GSList *l; - gint i; - const gchar *vboxes[] = {"vbox7", "vbox9", "vbox11", "vbox13", NULL}; - - for (i = 0; i < 4; i++) { - gchar buffer[80]; - - snprintf (buffer, sizeof (buffer), "group-combo-%d", i + 1); - config->group[i].combo = e_table_proxy_gtk_combo_text_new (); - gtk_widget_show (GTK_WIDGET (config->group[i].combo)); - gtk_box_pack_start ( - GTK_BOX (e_builder_get_widget (builder, vboxes[i])), - config->group[i].combo, FALSE, FALSE, 0); - - configure_combo_box_add ( - GTK_COMBO_BOX (config->group[i].combo), "", ""); - - snprintf (buffer, sizeof (buffer), "frame-group-%d", i + 1); - config->group[i].frames = - e_builder_get_widget (builder, buffer); - - snprintf ( - buffer, sizeof (buffer), - "radiobutton-ascending-group-%d", i + 1); - config->group[i].radio_ascending = e_builder_get_widget ( - builder, buffer); - - snprintf ( - buffer, sizeof (buffer), - "radiobutton-descending-group-%d", i + 1); - config->group[i].radio_descending = e_builder_get_widget ( - builder, buffer); - - snprintf ( - buffer, sizeof (buffer), - "checkbutton-group-%d", i + 1); - config->group[i].view_check = e_builder_get_widget ( - builder, buffer); - - config->group[i].e_table_config = config; - } - - for (l = config->column_names; l; l = l->next) { - gchar *label = l->data; - - for (i = 0; i < 4; i++) { - configure_combo_box_add ( - GTK_COMBO_BOX (config->group[i].combo), - dgettext (config->domain, label), label); - } - } - - /* - * After we have runtime modified things, signal connect - */ - for (i = 0; i < 4; i++) { - config->group[i].changed_id = g_signal_connect ( - config->group[i].combo, - "changed", G_CALLBACK (group_combo_changed), - &config->group[i]); - - config->group[i].toggled_id = g_signal_connect ( - config->group[i].radio_ascending, - "toggled", G_CALLBACK (group_ascending_toggled), - &config->group[i]); - } -} - -static void -add_column (gint model_row, - gpointer closure) -{ - GList **columns = closure; - *columns = g_list_prepend (*columns, GINT_TO_POINTER (model_row)); -} - -static void -config_button_add (GtkWidget *widget, - ETableConfig *config) -{ - GList *columns = NULL; - GList *column; - gint count; - gint i; - - e_table_selected_row_foreach (config->available, add_column, &columns); - columns = g_list_reverse (columns); - - count = g_list_length (columns); - - config->temp_state->columns = g_renew ( - int, config->temp_state->columns, - config->temp_state->col_count + count); - config->temp_state->expansions = g_renew ( - gdouble, config->temp_state->expansions, - config->temp_state->col_count + count); - i = config->temp_state->col_count; - for (column = columns; column; column = column->next) { - config->temp_state->columns[i] = - get_source_model_col_index ( - config, GPOINTER_TO_INT (column->data)); - config->temp_state->expansions[i] = - config->source_spec->columns - [config->temp_state->columns[i]]->expansion; - i++; - } - config->temp_state->col_count += count; - - g_list_free (columns); - - setup_fields (config); -} - -static void -config_button_remove (GtkWidget *widget, - ETableConfig *config) -{ - GList *columns = NULL; - GList *column; - - e_table_selected_row_foreach (config->shown, add_column, &columns); - - for (column = columns; column; column = column->next) { - gint row = GPOINTER_TO_INT (column->data); - - memmove ( - config->temp_state->columns + row, - config->temp_state->columns + row + 1, - sizeof (gint) * (config->temp_state->col_count - row - 1)); - memmove ( - config->temp_state->expansions + row, - config->temp_state->expansions + row + 1, - sizeof (gdouble) * (config->temp_state->col_count - row - 1)); - config->temp_state->col_count--; - } - config->temp_state->columns = g_renew ( - int, config->temp_state->columns, - config->temp_state->col_count); - config->temp_state->expansions = g_renew ( - gdouble, config->temp_state->expansions, - config->temp_state->col_count); - - g_list_free (columns); - - setup_fields (config); -} - -static void -config_button_up (GtkWidget *widget, - ETableConfig *config) -{ - GList *columns = NULL; - GList *column; - gint *new_shown; - gdouble *new_expansions; - gint next_col; - gdouble next_expansion; - gint i; - - e_table_selected_row_foreach (config->shown, add_column, &columns); - - /* if no columns left, just return */ - if (columns == NULL) - return; - - columns = g_list_reverse (columns); - - new_shown = g_new (int, config->temp_state->col_count); - new_expansions = g_new (double, config->temp_state->col_count); - - column = columns; - - next_col = config->temp_state->columns[0]; - next_expansion = config->temp_state->expansions[0]; - - for (i = 1; i < config->temp_state->col_count; i++) { - if (column && (GPOINTER_TO_INT (column->data) == i)) { - new_expansions[i - 1] = config->temp_state->expansions[i]; - new_shown[i - 1] = config->temp_state->columns[i]; - column = column->next; - } else { - new_shown[i - 1] = next_col; - next_col = config->temp_state->columns[i]; - - new_expansions[i - 1] = next_expansion; - next_expansion = config->temp_state->expansions[i]; - } - } - - new_shown[i - 1] = next_col; - new_expansions[i - 1] = next_expansion; - - g_free (config->temp_state->columns); - g_free (config->temp_state->expansions); - - config->temp_state->columns = new_shown; - config->temp_state->expansions = new_expansions; - - g_list_free (columns); - - setup_fields (config); -} - -static void -config_button_down (GtkWidget *widget, - ETableConfig *config) -{ - GList *columns = NULL; - GList *column; - gint *new_shown; - gdouble *new_expansions; - gint next_col; - gdouble next_expansion; - gint i; - - e_table_selected_row_foreach (config->shown, add_column, &columns); - - /* if no columns left, just return */ - if (columns == NULL) - return; - - new_shown = g_new (gint, config->temp_state->col_count); - new_expansions = g_new (gdouble, config->temp_state->col_count); - - column = columns; - - next_col = - config->temp_state->columns[config->temp_state->col_count - 1]; - next_expansion = - config->temp_state->expansions[config->temp_state->col_count - 1]; - - for (i = config->temp_state->col_count - 1; i > 0; i--) { - if (column && (GPOINTER_TO_INT (column->data) == i - 1)) { - new_expansions[i] = config->temp_state->expansions[i - 1]; - new_shown[i] = config->temp_state->columns[i - 1]; - column = column->next; - } else { - new_shown[i] = next_col; - next_col = config->temp_state->columns[i - 1]; - - new_expansions[i] = next_expansion; - next_expansion = config->temp_state->expansions[i - 1]; - } - } - - new_shown[0] = next_col; - new_expansions[0] = next_expansion; - - g_free (config->temp_state->columns); - g_free (config->temp_state->expansions); - - config->temp_state->columns = new_shown; - config->temp_state->expansions = new_expansions; - - g_list_free (columns); - - setup_fields (config); -} - -static void -configure_fields_dialog (ETableConfig *config, - GtkBuilder *builder) -{ - GtkWidget *scrolled; - GtkWidget *etable; - ETableModel *store = create_store (config); - - /* "custom-available" widget */ - etable = e_table_proxy_etable_available_new (store); - gtk_widget_show (etable); - scrolled = e_builder_get_widget (builder, "available-scrolled"); - gtk_container_add (GTK_CONTAINER (scrolled), etable); - config->available = E_TABLE (etable); - g_object_get ( - config->available, - "model", &config->available_model, - NULL); - gtk_widget_show_all (etable); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (e_builder_get_widget ( - builder, "label-available")), etable); - - /* "custom-shown" widget */ - etable = e_table_proxy_etable_shown_new (store); - gtk_widget_show (etable); - scrolled = e_builder_get_widget (builder, "shown-scrolled"); - gtk_container_add (GTK_CONTAINER (scrolled), etable); - config->shown = E_TABLE (etable); - g_object_get ( - config->shown, - "model", &config->shown_model, - NULL); - gtk_widget_show_all (etable); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (e_builder_get_widget ( - builder, "label-displayed")), etable); - - connect_button ( - config, builder, "button-add", - G_CALLBACK (config_button_add)); - connect_button ( - config, builder, "button-remove", - G_CALLBACK (config_button_remove)); - connect_button ( - config, builder, "button-up", - G_CALLBACK (config_button_up)); - connect_button ( - config, builder, "button-down", - G_CALLBACK (config_button_down)); - - setup_fields (config); - - g_object_unref (store); -} - -static void -setup_gui (ETableConfig *config) -{ - GtkBuilder *builder; - gboolean can_group; - - can_group = e_table_sort_info_get_can_group (config->state->sort_info); - builder = gtk_builder_new (); - e_load_ui_builder_definition (builder, "e-table-config.ui"); - - config->dialog_toplevel = e_builder_get_widget ( - builder, "e-table-config"); - - if (config->header) - gtk_window_set_title ( - GTK_WINDOW (config->dialog_toplevel), - config->header); - - config->dialog_show_fields = e_builder_get_widget ( - builder, "dialog-show-fields"); - config->dialog_group_by = e_builder_get_widget ( - builder, "dialog-group-by"); - config->dialog_sort = e_builder_get_widget ( - builder, "dialog-sort"); - - config->sort_label = e_builder_get_widget ( - builder, "label-sort"); - config->group_label = e_builder_get_widget ( - builder, "label-group"); - config->fields_label = e_builder_get_widget ( - builder, "label-fields"); - - connect_button ( - config, builder, "button-sort", - G_CALLBACK (config_button_sort)); - connect_button ( - config, builder, "button-group", - G_CALLBACK (config_button_group)); - connect_button ( - config, builder, "button-fields", - G_CALLBACK (config_button_fields)); - - if (!can_group) { - GtkWidget *w; - - w = e_builder_get_widget (builder, "button-group"); - if (w) - gtk_widget_hide (w); - - w = e_builder_get_widget (builder, "label3"); - if (w) - gtk_widget_hide (w); - - w = config->group_label; - if (w) - gtk_widget_hide (w); - } - - configure_sort_dialog (config, builder); - configure_group_dialog (config, builder); - configure_fields_dialog (config, builder); - - g_object_weak_ref ( - G_OBJECT (config->dialog_toplevel), - dialog_destroyed, config); - - g_signal_connect ( - config->dialog_toplevel, "response", - G_CALLBACK (dialog_response), config); - - g_object_unref (builder); -} - -static void -e_table_config_init (ETableConfig *config) -{ - config->domain = NULL; -} - -ETableConfig * -e_table_config_construct (ETableConfig *config, - const gchar *header, - ETableSpecification *spec, - ETableState *state, - GtkWindow *parent_window) -{ - ETableColumnSpecification **column; - - g_return_val_if_fail (config != NULL, NULL); - g_return_val_if_fail (header != NULL, NULL); - g_return_val_if_fail (spec != NULL, NULL); - g_return_val_if_fail (state != NULL, NULL); - - config->source_spec = spec; - config->source_state = state; - config->header = g_strdup (header); - - g_object_ref (config->source_spec); - g_object_ref (config->source_state); - - config->state = e_table_state_duplicate (state); - - config->domain = g_strdup (spec->domain); - - for (column = config->source_spec->columns; *column; column++) { - gchar *label = (*column)->title; - - if ((*column)->disabled) - continue; - - config->column_names = g_slist_append ( - config->column_names, label); - } - - setup_gui (config); - - gtk_window_set_transient_for (GTK_WINDOW (config->dialog_toplevel), - parent_window); - - config_sort_info_update (config); - config_group_info_update (config); - config_fields_info_update (config); - - return E_TABLE_CONFIG (config); -} - -/** - * e_table_config_new: - * @header: The title of the dialog for the ETableConfig. - * @spec: The specification for the columns to allow. - * @state: The current state of the configuration. - * - * Creates a new ETable config object. - * - * Returns: The config object. - */ -ETableConfig * -e_table_config_new (const gchar *header, - ETableSpecification *spec, - ETableState *state, - GtkWindow *parent_window) -{ - ETableConfig *config; - GtkDialog *dialog; - GtkWidget *widget; - - config = g_object_new (E_TYPE_TABLE_CONFIG, NULL); - - e_table_config_construct ( - config, header, spec, state, parent_window); - - dialog = GTK_DIALOG (config->dialog_toplevel); - - gtk_widget_ensure_style (config->dialog_toplevel); - - widget = gtk_dialog_get_content_area (dialog); - gtk_container_set_border_width (GTK_CONTAINER (widget), 0); - - widget = gtk_dialog_get_action_area (dialog); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (config->dialog_toplevel), - GTK_RESPONSE_APPLY, FALSE); - gtk_widget_show (config->dialog_toplevel); - - return E_TABLE_CONFIG (config); -} - -/** - * e_table_config_raise: - * @config: The ETableConfig object. - * - * Raises the dialog associated with this ETableConfig object. - */ -void -e_table_config_raise (ETableConfig *config) -{ - GdkWindow *window; - - window = gtk_widget_get_window (GTK_WIDGET (config->dialog_toplevel)); - gdk_window_raise (window); -} - diff --git a/widgets/table/e-table-config.h b/widgets/table/e-table-config.h deleted file mode 100644 index 083160772f..0000000000 --- a/widgets/table/e-table-config.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_CONFIG_H_ -#define _E_TABLE_CONFIG_H_ - -#include <table/e-table-sort-info.h> -#include <table/e-table-specification.h> -#include <table/e-table-without.h> -#include <table/e-table-subset-variable.h> -#include <table/e-table.h> -#include <gtk/gtk.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_CONFIG \ - (e_table_config_get_type ()) -#define E_TABLE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_CONFIG, ETableConfig)) -#define E_TABLE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_CONFIG, ETableConfigClass)) -#define E_IS_TABLE_CONFIG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_CONFIG)) -#define E_IS_TABLE_CONFIG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_CONFIG)) -#define E_TABLE_CONFIG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_CONFIG, ETableConfigClass)) - -G_BEGIN_DECLS - -typedef struct _ETableConfigSortWidgets ETableConfigSortWidgets; - -typedef struct _ETableConfig ETableConfig; -typedef struct _ETableConfigClass ETableConfigClass; - -struct _ETableConfigSortWidgets { - GtkWidget *combo; - GtkWidget *frames; - GtkWidget *radio_ascending; - GtkWidget *radio_descending; - GtkWidget *view_check; /* Only for group dialog */ - guint changed_id, toggled_id; - gpointer e_table_config; -}; - -struct _ETableConfig { - GObject parent; - - gchar *header; - - /* - * Our various dialog boxes - */ - GtkWidget *dialog_toplevel; - GtkWidget *dialog_show_fields; - GtkWidget *dialog_group_by; - GtkWidget *dialog_sort; - - /* - * The state we manipulate - */ - ETableSpecification *source_spec; - ETableState *source_state, *state, *temp_state; - - GtkWidget *sort_label; - GtkWidget *group_label; - GtkWidget *fields_label; - - ETableConfigSortWidgets sort[4]; - ETableConfigSortWidgets group[4]; - - ETable *available; - ETableWithout *available_model; - ETable *shown; - ETableSubsetVariable *shown_model; - gchar *domain; - - /* - * List of valid column names - */ - GSList *column_names; -}; - -struct _ETableConfigClass { - GObjectClass parent_class; - - /* Signals */ - void (*changed) (ETableConfig *config); -}; - -GType e_table_config_get_type (void) G_GNUC_CONST; -ETableConfig * e_table_config_new (const gchar *header, - ETableSpecification *spec, - ETableState *state, - GtkWindow *parent_window); -ETableConfig *e_table_config_construct (ETableConfig *etco, - const gchar *header, - ETableSpecification *spec, - ETableState *state, - GtkWindow *parent_window); -void e_table_config_raise (ETableConfig *config); - -G_END_DECLS - -#endif /* _E_TABLE_CONFIG_H */ diff --git a/widgets/table/e-table-config.ui b/widgets/table/e-table-config.ui deleted file mode 100644 index cfc6cb57fc..0000000000 --- a/widgets/table/e-table-config.ui +++ /dev/null @@ -1,1594 +0,0 @@ -<?xml version="1.0"?> -<interface> - <!-- interface-requires gtk+ 2.12 --> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkDialog" id="dialog-show-fields"> - <property name="title" translatable="yes">Show Fields</property> - <property name="modal">True</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox3"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">8</property> - <child> - <object class="GtkVBox" id="vbox2"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkTable" id="table2"> - <property name="visible">True</property> - <property name="n_columns">5</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkLabel" id="label-available"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">A_vailable Fields:</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="right_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-displayed"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Show these fields in order:</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">5</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkTable" id="table3"> - <property name="visible">True</property> - <property name="n_columns">5</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkVBox" id="vbox4"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="available-scrolled"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="right_attach">2</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox5"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="shown-scrolled"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox4"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkButton" id="button-up"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <child> - <object class="GtkAlignment" id="alignment7"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox19"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image3"> - <property name="visible">True</property> - <property name="stock">gtk-go-up</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label29"> - <property name="visible">True</property> - <property name="label" translatable="yes">Move _Up</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-down"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <child> - <object class="GtkAlignment" id="alignment8"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox20"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image4"> - <property name="visible">True</property> - <property name="stock">gtk-go-down</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label30"> - <property name="visible">True</property> - <property name="label" translatable="yes">Move _Down</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">5</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox6"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkButton" id="button-add"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <child> - <object class="GtkAlignment" id="alignment5"> - <property name="visible">True</property> - <property name="xalign">0.69999998807907104</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox17"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkLabel" id="label31"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Add</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkImage" id="image5"> - <property name="visible">True</property> - <property name="stock">gtk-go-forward</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-remove"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <child> - <object class="GtkAlignment" id="alignment6"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox18"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-go-back</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label27"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Remove</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area3"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="button22"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button20"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">button22</action-widget> - <action-widget response="-5">button20</action-widget> - </action-widgets> - </object> - <object class="GtkDialog" id="dialog-group-by"> - <property name="title" translatable="yes">Group</property> - <property name="modal">True</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox4"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">8</property> - <child> - <object class="GtkVBox" id="vbox24"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkHBox" id="hbox13"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkFrame" id="frame-group-1"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox5"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkVBox" id="vbox7"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkCheckButton" id="checkbutton-group-1"> - <property name="label" translatable="yes">_Show field in View</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox8"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-group-1"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-group-1"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-group-1</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Group Items By</property> - </object> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label8"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label9"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label10"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox14"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label11"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-group-2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox6"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkVBox" id="vbox9"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkCheckButton" id="checkbutton-group-2"> - <property name="label" translatable="yes">Show _field in View</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox10"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-group-2"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-group-2"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-group-2</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label12"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label19"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label18"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox15"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label13"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label32"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-group-3"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox7"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkVBox" id="vbox11"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkCheckButton" id="checkbutton-group-3"> - <property name="label" translatable="yes">Show field i_n View</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox12"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-group-3"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-group-3"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-group-3</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label20"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label17"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox16"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label14"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label16"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label15"> - <property name="visible">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-group-4"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox8"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkVBox" id="vbox13"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkCheckButton" id="checkbutton-group-4"> - <property name="label" translatable="yes">Show field in _View</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox14"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-group-4"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-group-4"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-group-4</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label21"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area4"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="button39"> - <property name="label" translatable="yes">Clear _All</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button42"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button41"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="0">button39</action-widget> - <action-widget response="-6">button42</action-widget> - <action-widget response="-5">button41</action-widget> - </action-widgets> - </object> - <object class="GtkDialog" id="dialog-sort"> - <property name="title" translatable="yes">Sort</property> - <property name="modal">True</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="vbox15"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">8</property> - <child> - <object class="GtkTable" id="table5"> - <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkFrame" id="frame-sort-4"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox9"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="yscale">0</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox17"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-sort-4"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-sort-4"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-sort-4</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label22"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-sort-3"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox10"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="yscale">0</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox19"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-sort-3"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-sort-3"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-sort-3</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label23"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-sort-2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox11"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkAlignment" id="alignment3"> - <property name="visible">True</property> - <property name="yscale">0</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox21"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-sort-2"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-sort-2"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-sort-2</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label24"> - <property name="visible">True</property> - <property name="label" translatable="yes">Then By</property> - </object> - </child> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame-sort-1"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkHBox" id="hbox12"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkAlignment" id="alignment4"> - <property name="visible">True</property> - <property name="yscale">0</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox23"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkRadioButton" id="radiobutton-ascending-sort-1"> - <property name="label" translatable="yes">Ascending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="radiobutton-descending-sort-1"> - <property name="label" translatable="yes">Descending</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton-ascending-sort-1</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label25"> - <property name="visible">True</property> - <property name="label" translatable="yes">Sort Items By</property> - </object> - </child> - </object> - <packing> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="button43"> - <property name="label" translatable="yes">Clear All</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button45"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button44"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="0">button43</action-widget> - <action-widget response="-6">button45</action-widget> - <action-widget response="-5">button44</action-widget> - </action-widgets> - </object> - <object class="GtkDialog" id="e-table-config"> - <property name="title">dialog1</property> - <property name="resizable">False</property> - <property name="modal">True</property> - <property name="window_position">center-on-parent</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox6"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkFrame" id="top-frame"> - <property name="visible">True</property> - <property name="border_width">2</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkTable" id="table1"> - <property name="visible">True</property> - <property name="border_width">2</property> - <property name="n_rows">3</property> - <property name="n_columns">3</property> - <property name="column_spacing">4</property> - <property name="row_spacing">2</property> - <child> - <object class="GtkButton" id="button-sort"> - <property name="label" translatable="yes">_Sort...</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="on_sort_clicked"/> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-group"> - <property name="label" translatable="yes">_Group By...</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="on_group_by_clicked"/> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-sort"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button-fields"> - <property name="label" translatable="yes">_Fields Shown...</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="on_group_by_clicked"/> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-fields"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="justify">center</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="justify">center</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label33"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="justify">center</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label-group"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label26"> - <property name="visible">True</property> - <property name="label" translatable="yes">Description</property> - </object> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area6"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancelbutton2"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="applybutton2"> - <property name="label">gtk-apply</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="okbutton2"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancelbutton2</action-widget> - <action-widget response="-10">applybutton2</action-widget> - <action-widget response="-5">okbutton2</action-widget> - </action-widgets> - </object> -</interface> diff --git a/widgets/table/e-table-defines.h b/widgets/table/e-table-defines.h deleted file mode 100644 index d7b261160b..0000000000 --- a/widgets/table/e-table-defines.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_TABLE_DEFINES__ -#define __E_TABLE_DEFINES__ 1 - -G_BEGIN_DECLS - -#define BUTTON_HEIGHT 10 -#define BUTTON_PADDING 2 -#define GROUP_INDENT (BUTTON_HEIGHT + (BUTTON_PADDING * 2)) - -/* Padding around the contents of a header button */ -#define HEADER_PADDING 3 - -#define MIN_ARROW_SIZE 10 - -G_END_DECLS - -#endif diff --git a/widgets/table/e-table-extras.c b/widgets/table/e-table-extras.c deleted file mode 100644 index d39677bbc8..0000000000 --- a/widgets/table/e-table-extras.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * e-table-extras.c - Set of hash table sort of thingies. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-cell-checkbox.h" -#include "e-cell-date.h" -#include "e-cell-number.h" -#include "e-cell-pixbuf.h" -#include "e-cell-size.h" -#include "e-cell-text.h" -#include "e-cell-tree.h" -#include "e-table-extras.h" -#include "e-table-sorting-utils.h" - -#define E_TABLE_EXTRAS_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TABLE_EXTRAS, ETableExtrasPrivate)) - -struct _ETableExtrasPrivate { - GHashTable *cells; - GHashTable *compares; - GHashTable *icon_names; - GHashTable *searches; -}; - -/* workaround for avoiding API breakage */ -#define ete_get_type e_table_extras_get_type -G_DEFINE_TYPE (ETableExtras, ete, G_TYPE_OBJECT) - -static void -ete_finalize (GObject *object) -{ - ETableExtrasPrivate *priv; - - priv = E_TABLE_EXTRAS_GET_PRIVATE (object); - - if (priv->cells) { - g_hash_table_destroy (priv->cells); - priv->cells = NULL; - } - - if (priv->compares) { - g_hash_table_destroy (priv->compares); - priv->compares = NULL; - } - - if (priv->searches) { - g_hash_table_destroy (priv->searches); - priv->searches = NULL; - } - - if (priv->icon_names) { - g_hash_table_destroy (priv->icon_names); - priv->icon_names = NULL; - } - - G_OBJECT_CLASS (ete_parent_class)->finalize (object); -} - -static void -ete_class_init (ETableExtrasClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ETableExtrasPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = ete_finalize; -} - -static gint -e_strint_compare (gconstpointer data1, - gconstpointer data2) -{ - gint int1 = atoi (data1); - gint int2 = atoi (data2); - - return e_int_compare (GINT_TO_POINTER (int1), GINT_TO_POINTER (int2)); -} - -/* UTF-8 strncasecmp - not optimized */ - -static gint -g_utf8_strncasecmp (const gchar *s1, - const gchar *s2, - guint n) -{ - gunichar c1, c2; - - g_return_val_if_fail (s1 != NULL && g_utf8_validate (s1, -1, NULL), 0); - g_return_val_if_fail (s2 != NULL && g_utf8_validate (s2, -1, NULL), 0); - - while (n && *s1 && *s2) - { - - n -= 1; - - c1 = g_unichar_tolower (g_utf8_get_char (s1)); - c2 = g_unichar_tolower (g_utf8_get_char (s2)); - - /* Collation is locale-dependent, so this - * totally fails to do the right thing. */ - if (c1 != c2) - return c1 < c2 ? -1 : 1; - - s1 = g_utf8_next_char (s1); - s2 = g_utf8_next_char (s2); - } - - if (n == 0 || (*s1 == '\0' && *s2 == '\0')) - return 0; - - return *s1 ? 1 : -1; -} - -static gboolean -e_string_search (gconstpointer haystack, - const gchar *needle) -{ - gint length; - if (haystack == NULL) - return FALSE; - - length = g_utf8_strlen (needle, -1); - if (g_utf8_strncasecmp (haystack, needle, length) == 0) - return TRUE; - else - return FALSE; -} - -static gint -e_table_str_case_compare (gconstpointer x, - gconstpointer y, - gpointer cmp_cache) -{ - const gchar *cx = NULL, *cy = NULL; - - if (!cmp_cache) - return e_str_case_compare (x, y); - - if (x == NULL || y == NULL) { - if (x == y) - return 0; - else - return x ? -1 : 1; - } - - #define prepare_value(_z, _cz) \ - _cz = e_table_sorting_utils_lookup_cmp_cache (cmp_cache, _z); \ - if (!_cz) { \ - gchar *tmp = g_utf8_casefold (_z, -1); \ - _cz = g_utf8_collate_key (tmp, -1); \ - g_free (tmp); \ - \ - e_table_sorting_utils_add_to_cmp_cache ( \ - cmp_cache, _z, (gchar *) _cz); \ - } - - prepare_value (x, cx); - prepare_value (y, cy); - - #undef prepare_value - - return strcmp (cx, cy); -} - -static gint -e_table_collate_compare (gconstpointer x, - gconstpointer y, - gpointer cmp_cache) -{ - const gchar *cx = NULL, *cy = NULL; - - if (!cmp_cache) - return e_collate_compare (x, y); - - if (x == NULL || y == NULL) { - if (x == y) - return 0; - else - return x ? -1 : 1; - } - - #define prepare_value(_z, _cz) \ - _cz = e_table_sorting_utils_lookup_cmp_cache (cmp_cache, _z); \ - if (!_cz) { \ - _cz = g_utf8_collate_key (_z, -1); \ - \ - e_table_sorting_utils_add_to_cmp_cache ( \ - cmp_cache, _z, (gchar *) _cz); \ - } - - prepare_value (x, cx); - prepare_value (y, cy); - - #undef prepare_value - - return strcmp (cx, cy); -} - -static void -safe_unref (gpointer object) -{ - if (object != NULL) - g_object_unref (object); -} - -static void -ete_init (ETableExtras *extras) -{ - ECell *cell, *sub_cell; - - extras->priv = E_TABLE_EXTRAS_GET_PRIVATE (extras); - - extras->priv->cells = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) safe_unref); - - extras->priv->compares = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) NULL); - - extras->priv->icon_names = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - extras->priv->searches = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) NULL); - - e_table_extras_add_compare ( - extras, "string", - (GCompareDataFunc) e_str_compare); - e_table_extras_add_compare ( - extras, "stringcase", - (GCompareDataFunc) e_table_str_case_compare); - e_table_extras_add_compare ( - extras, "collate", - (GCompareDataFunc) e_table_collate_compare); - e_table_extras_add_compare ( - extras, "integer", - (GCompareDataFunc) e_int_compare); - e_table_extras_add_compare ( - extras, "string-integer", - (GCompareDataFunc) e_strint_compare); - - e_table_extras_add_search (extras, "string", e_string_search); - - cell = e_cell_checkbox_new (); - e_table_extras_add_cell (extras, "checkbox", cell); - g_object_unref (cell); - - cell = e_cell_date_new (NULL, GTK_JUSTIFY_LEFT); - e_table_extras_add_cell (extras, "date", cell); - g_object_unref (cell); - - cell = e_cell_number_new (NULL, GTK_JUSTIFY_RIGHT); - e_table_extras_add_cell (extras, "number", cell); - g_object_unref (cell); - - cell = e_cell_pixbuf_new (); - e_table_extras_add_cell (extras, "pixbuf", cell); - g_object_unref (cell); - - cell = e_cell_size_new (NULL, GTK_JUSTIFY_RIGHT); - e_table_extras_add_cell (extras, "size", cell); - g_object_unref (cell); - - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - e_table_extras_add_cell (extras, "string", cell); - g_object_unref (cell); - - sub_cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - cell = e_cell_tree_new (TRUE, sub_cell); - e_table_extras_add_cell (extras, "tree-string", cell); - g_object_unref (sub_cell); - g_object_unref (cell); -} - -ETableExtras * -e_table_extras_new (void) -{ - return g_object_new (E_TYPE_TABLE_EXTRAS, NULL); -} - -void -e_table_extras_add_cell (ETableExtras *extras, - const gchar *id, - ECell *cell) -{ - g_return_if_fail (E_IS_TABLE_EXTRAS (extras)); - g_return_if_fail (id != NULL); - - if (cell != NULL) - g_object_ref_sink (cell); - - g_hash_table_insert (extras->priv->cells, g_strdup (id), cell); -} - -ECell * -e_table_extras_get_cell (ETableExtras *extras, - const gchar *id) -{ - g_return_val_if_fail (E_IS_TABLE_EXTRAS (extras), NULL); - g_return_val_if_fail (id != NULL, NULL); - - return g_hash_table_lookup (extras->priv->cells, id); -} - -void -e_table_extras_add_compare (ETableExtras *extras, - const gchar *id, - GCompareDataFunc compare) -{ - g_return_if_fail (E_IS_TABLE_EXTRAS (extras)); - g_return_if_fail (id != NULL); - - g_hash_table_insert ( - extras->priv->compares, - g_strdup (id), (gpointer) compare); -} - -GCompareDataFunc -e_table_extras_get_compare (ETableExtras *extras, - const gchar *id) -{ - g_return_val_if_fail (E_IS_TABLE_EXTRAS (extras), NULL); - g_return_val_if_fail (id != NULL, NULL); - - return g_hash_table_lookup (extras->priv->compares, id); -} - -void -e_table_extras_add_search (ETableExtras *extras, - const gchar *id, - ETableSearchFunc search) -{ - g_return_if_fail (E_IS_TABLE_EXTRAS (extras)); - g_return_if_fail (id != NULL); - - g_hash_table_insert ( - extras->priv->searches, - g_strdup (id), (gpointer) search); -} - -ETableSearchFunc -e_table_extras_get_search (ETableExtras *extras, - const gchar *id) -{ - g_return_val_if_fail (E_IS_TABLE_EXTRAS (extras), NULL); - g_return_val_if_fail (id != NULL, NULL); - - return g_hash_table_lookup (extras->priv->searches, id); -} - -void -e_table_extras_add_icon_name (ETableExtras *extras, - const gchar *id, - const gchar *icon_name) -{ - g_return_if_fail (E_IS_TABLE_EXTRAS (extras)); - g_return_if_fail (id != NULL); - - g_hash_table_insert ( - extras->priv->icon_names, - g_strdup (id), g_strdup (icon_name)); -} - -const gchar * -e_table_extras_get_icon_name (ETableExtras *extras, - const gchar *id) -{ - g_return_val_if_fail (E_IS_TABLE_EXTRAS (extras), NULL); - g_return_val_if_fail (id != NULL, NULL); - - return g_hash_table_lookup (extras->priv->icon_names, id); -} diff --git a/widgets/table/e-table-extras.h b/widgets/table/e-table-extras.h deleted file mode 100644 index 6b1ed4200f..0000000000 --- a/widgets/table/e-table-extras.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TABLE_EXTRAS_H -#define E_TABLE_EXTRAS_H - -#include <table/e-cell.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_EXTRAS \ - (e_table_extras_get_type ()) -#define E_TABLE_EXTRAS(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_EXTRAS, ETableExtras)) -#define E_TABLE_EXTRAS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_EXTRAS, ETableExtrasClass)) -#define E_IS_TABLE_EXTRAS(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_EXTRAS)) -#define E_IS_TABLE_EXTRAS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_EXTRAS)) -#define E_TABLE_EXTRAS_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_EXTRAS, ETableExtrasClass)) - -G_BEGIN_DECLS - -typedef struct _ETableExtras ETableExtras; -typedef struct _ETableExtrasClass ETableExtrasClass; -typedef struct _ETableExtrasPrivate ETableExtrasPrivate; - -struct _ETableExtras { - GObject parent; - ETableExtrasPrivate *priv; -}; - -struct _ETableExtrasClass { - GObjectClass parent_class; -}; - -GType e_table_extras_get_type (void) G_GNUC_CONST; -ETableExtras * e_table_extras_new (void); -void e_table_extras_add_cell (ETableExtras *extras, - const gchar *id, - ECell *cell); -ECell * e_table_extras_get_cell (ETableExtras *extras, - const gchar *id); -void e_table_extras_add_compare (ETableExtras *extras, - const gchar *id, - GCompareDataFunc compare); -GCompareDataFunc e_table_extras_get_compare (ETableExtras *extras, - const gchar *id); -void e_table_extras_add_search (ETableExtras *extras, - const gchar *id, - ETableSearchFunc search); -ETableSearchFunc - e_table_extras_get_search (ETableExtras *extras, - const gchar *id); -void e_table_extras_add_icon_name (ETableExtras *extras, - const gchar *id, - const gchar *icon_name); -const gchar * e_table_extras_get_icon_name (ETableExtras *extras, - const gchar *id); - -G_END_DECLS - -#endif /* E_TABLE_EXTRAS_H */ diff --git a/widgets/table/e-table-field-chooser-dialog.c b/widgets/table/e-table-field-chooser-dialog.c deleted file mode 100644 index fb005ed30f..0000000000 --- a/widgets/table/e-table-field-chooser-dialog.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-table-field-chooser-dialog.h" - -enum { - PROP_0, - PROP_DND_CODE, - PROP_FULL_HEADER, - PROP_HEADER -}; - -G_DEFINE_TYPE ( - ETableFieldChooserDialog, - e_table_field_chooser_dialog, - GTK_TYPE_DIALOG) - -static void -e_table_field_chooser_dialog_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableFieldChooserDialog *etfcd = E_TABLE_FIELD_CHOOSER_DIALOG (object); - switch (property_id) { - case PROP_DND_CODE: - g_free (etfcd->dnd_code); - etfcd->dnd_code = g_strdup (g_value_get_string (value)); - if (etfcd->etfc) - g_object_set ( - etfcd->etfc, - "dnd_code", etfcd->dnd_code, - NULL); - break; - case PROP_FULL_HEADER: - if (etfcd->full_header) - g_object_unref (etfcd->full_header); - if (g_value_get_object (value)) - etfcd->full_header = E_TABLE_HEADER (g_value_get_object (value)); - else - etfcd->full_header = NULL; - if (etfcd->full_header) - g_object_ref (etfcd->full_header); - if (etfcd->etfc) - g_object_set ( - etfcd->etfc, - "full_header", etfcd->full_header, - NULL); - break; - case PROP_HEADER: - if (etfcd->header) - g_object_unref (etfcd->header); - if (g_value_get_object (value)) - etfcd->header = E_TABLE_HEADER (g_value_get_object (value)); - else - etfcd->header = NULL; - if (etfcd->header) - g_object_ref (etfcd->header); - if (etfcd->etfc) - g_object_set ( - etfcd->etfc, - "header", etfcd->header, - NULL); - break; - default: - break; - } -} - -static void -e_table_field_chooser_dialog_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableFieldChooserDialog *etfcd = E_TABLE_FIELD_CHOOSER_DIALOG (object); - switch (property_id) { - case PROP_DND_CODE: - g_value_set_string (value, etfcd->dnd_code); - break; - case PROP_FULL_HEADER: - g_value_set_object (value, etfcd->full_header); - break; - case PROP_HEADER: - g_value_set_object (value, etfcd->header); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_table_field_chooser_dialog_dispose (GObject *object) -{ - ETableFieldChooserDialog *etfcd = E_TABLE_FIELD_CHOOSER_DIALOG (object); - - if (etfcd->dnd_code) - g_free (etfcd->dnd_code); - etfcd->dnd_code = NULL; - - if (etfcd->full_header) - g_object_unref (etfcd->full_header); - etfcd->full_header = NULL; - - if (etfcd->header) - g_object_unref (etfcd->header); - etfcd->header = NULL; - - G_OBJECT_CLASS (e_table_field_chooser_dialog_parent_class)->dispose (object); -} - -static void -e_table_field_chooser_dialog_response (GtkDialog *dialog, - gint id) -{ - if (id == GTK_RESPONSE_OK) - gtk_widget_destroy (GTK_WIDGET (dialog)); -} - -static void -e_table_field_chooser_dialog_class_init (ETableFieldChooserDialogClass *class) -{ - GObjectClass *object_class; - GtkDialogClass *dialog_class; - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = e_table_field_chooser_dialog_set_property; - object_class->get_property = e_table_field_chooser_dialog_get_property; - object_class->dispose = e_table_field_chooser_dialog_dispose; - - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = e_table_field_chooser_dialog_response; - - g_object_class_install_property ( - object_class, - PROP_DND_CODE, - g_param_spec_string ( - "dnd_code", - "DnD code", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FULL_HEADER, - g_param_spec_object ( - "full_header", - "Full Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEADER, - g_param_spec_object ( - "header", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); -} - -static void -e_table_field_chooser_dialog_init (ETableFieldChooserDialog *e_table_field_chooser_dialog) -{ - GtkDialog *dialog; - GtkWidget *content_area; - GtkWidget *widget; - - dialog = GTK_DIALOG (e_table_field_chooser_dialog); - - e_table_field_chooser_dialog->etfc = NULL; - e_table_field_chooser_dialog->dnd_code = g_strdup (""); - e_table_field_chooser_dialog->full_header = NULL; - e_table_field_chooser_dialog->header = NULL; - - gtk_dialog_add_button (dialog, GTK_STOCK_CLOSE, GTK_RESPONSE_OK); - - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - - widget = e_table_field_chooser_new (); - e_table_field_chooser_dialog->etfc = E_TABLE_FIELD_CHOOSER (widget); - - g_object_set ( - widget, - "dnd_code", e_table_field_chooser_dialog->dnd_code, - "full_header", e_table_field_chooser_dialog->full_header, - "header", e_table_field_chooser_dialog->header, - NULL); - - content_area = gtk_dialog_get_content_area (dialog); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - gtk_widget_show (GTK_WIDGET (widget)); - - gtk_window_set_title (GTK_WINDOW (dialog), _("Add a Column")); -} - -GtkWidget * -e_table_field_chooser_dialog_new (void) -{ - return g_object_new (E_TYPE_TABLE_FIELD_CHOOSER_DIALOG, NULL); -} - diff --git a/widgets/table/e-table-field-chooser-dialog.h b/widgets/table/e-table-field-chooser-dialog.h deleted file mode 100644 index bd378bc89d..0000000000 --- a/widgets/table/e-table-field-chooser-dialog.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_TABLE_FIELD_CHOOSER_DIALOG_H__ -#define __E_TABLE_FIELD_CHOOSER_DIALOG_H__ - -#include <gtk/gtk.h> -#include <table/e-table-field-chooser.h> -#include <table/e-table-header.h> - -#define E_TYPE_TABLE_FIELD_CHOOSER_DIALOG \ - (e_table_field_chooser_dialog_get_type ()) -#define E_TABLE_FIELD_CHOOSER_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_DIALOG, ETableFieldChooserDialog)) -#define E_TABLE_FIELD_CHOOSER_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER_DIALOG, ETableFieldChooserDialogClass)) -#define E_IS_TABLE_FIELD_CHOOSER_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_DIALOG)) -#define E_IS_TABLE_FIELD_CHOOSER_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER_DIALOG)) -#define E_TABLE_FIELD_CHOOSER_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_DIALOG, ETableFieldChooserDialogClass)) - -G_BEGIN_DECLS - -typedef struct _ETableFieldChooserDialog ETableFieldChooserDialog; -typedef struct _ETableFieldChooserDialogClass ETableFieldChooserDialogClass; - -struct _ETableFieldChooserDialog { - GtkDialog parent; - - /* item specific fields */ - ETableFieldChooser *etfc; - gchar *dnd_code; - ETableHeader *full_header; - ETableHeader *header; -}; - -struct _ETableFieldChooserDialogClass { - GtkDialogClass parent_class; -}; - -GType e_table_field_chooser_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * e_table_field_chooser_dialog_new (void); - -G_END_DECLS - -#endif /* __E_TABLE_FIELD_CHOOSER_DIALOG_H__ */ diff --git a/widgets/table/e-table-field-chooser-item.c b/widgets/table/e-table-field-chooser-item.c deleted file mode 100644 index 3c6c33cdcf..0000000000 --- a/widgets/table/e-table-field-chooser-item.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" -#include "misc/e-canvas.h" - -#include "e-table-col-dnd.h" -#include "e-table-defines.h" -#include "e-table-field-chooser-item.h" -#include "e-table-header-utils.h" -#include "e-table-header.h" - -#define d(x) - -#if 0 -enum { - BUTTON_PRESSED, - LAST_SIGNAL -}; - -static guint etfci_signals[LAST_SIGNAL] = { 0, }; -#endif - -/* workaround for avoiding API breakage */ -#define etfci_get_type e_table_field_chooser_item_get_type -G_DEFINE_TYPE (ETableFieldChooserItem, etfci, GNOME_TYPE_CANVAS_ITEM) - -static void etfci_drop_table_header (ETableFieldChooserItem *etfci); -static void etfci_drop_full_header (ETableFieldChooserItem *etfci); - -enum { - PROP_0, - PROP_FULL_HEADER, - PROP_HEADER, - PROP_DND_CODE, - PROP_WIDTH, - PROP_HEIGHT -}; - -static void -etfci_dispose (GObject *object) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (object); - - etfci_drop_table_header (etfci); - etfci_drop_full_header (etfci); - - if (etfci->combined_header) - g_object_unref (etfci->combined_header); - etfci->combined_header = NULL; - - if (etfci->font_desc) - pango_font_description_free (etfci->font_desc); - etfci->font_desc = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etfci_parent_class)->dispose (object); -} - -static gint -etfci_find_button (ETableFieldChooserItem *etfci, - gdouble loc) -{ - gint i; - gint count; - gdouble height = 0; - - count = e_table_header_count (etfci->combined_header); - for (i = 0; i < count; i++) { - ETableCol *ecol; - - ecol = e_table_header_get_column (etfci->combined_header, i); - if (ecol->disabled) - continue; - height += e_table_header_compute_height ( - ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas)); - if (height > loc) - return i; - } - return MAX (0, count - 1); -} - -static void -etfci_rebuild_combined (ETableFieldChooserItem *etfci) -{ - gint count; - GHashTable *hash; - gint i; - - if (etfci->combined_header != NULL) - g_object_unref (etfci->combined_header); - - etfci->combined_header = e_table_header_new (); - - hash = g_hash_table_new (NULL, NULL); - - count = e_table_header_count (etfci->header); - for (i = 0; i < count; i++) { - ETableCol *ecol = e_table_header_get_column (etfci->header, i); - if (ecol->disabled) - continue; - g_hash_table_insert ( - hash, GINT_TO_POINTER (ecol->col_idx), - GINT_TO_POINTER (1)); - } - - count = e_table_header_count (etfci->full_header); - for (i = 0; i < count; i++) { - ETableCol *ecol = e_table_header_get_column (etfci->full_header, i); - if (ecol->disabled) - continue; - if (!(GPOINTER_TO_INT (g_hash_table_lookup ( - hash, GINT_TO_POINTER (ecol->col_idx))))) - e_table_header_add_column (etfci->combined_header, ecol, -1); - } - - g_hash_table_destroy (hash); -} - -static void -etfci_reflow (GnomeCanvasItem *item, - gint flags) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - gdouble old_height; - gint i; - gint count; - gdouble height = 0; - - etfci_rebuild_combined (etfci); - - old_height = etfci->height; - - count = e_table_header_count (etfci->combined_header); - for (i = 0; i < count; i++) { - ETableCol *ecol; - - ecol = e_table_header_get_column (etfci->combined_header, i); - if (ecol->disabled) - continue; - height += e_table_header_compute_height ( - ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas)); - } - - etfci->height = height; - - if (old_height != etfci->height) - e_canvas_item_request_parent_reflow (item); - - gnome_canvas_item_request_update (item); -} - -static void -etfci_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - gdouble x1, y1, x2, y2; - - if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update) - GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update ( - item, i2c, flags); - - x1 = y1 = 0; - x2 = etfci->width; - y2 = etfci->height; - - gnome_canvas_matrix_transform_rect (i2c, &x1, &y1, &x2, &y2); - - if (item->x1 != x1 || - item->y1 != y1 || - item->x2 != x2 || - item->y2 != y2) - { - gnome_canvas_request_redraw ( - item->canvas, item->x1, - item->y1, item->x2, item->y2); - item->x1 = x1; - item->y1 = y1; - item->x2 = x2; - item->y2 = y2; -/* FIXME: Group Child bounds !? */ -#if 0 - gnome_canvas_group_child_bounds ( - GNOME_CANVAS_GROUP (item->parent), item); -#endif - } - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, item->x2, item->y2); -} - -static void -etfci_font_load (ETableFieldChooserItem *etfci) -{ - GtkWidget *widget; - GtkStyle *style; - - if (etfci->font_desc) - pango_font_description_free (etfci->font_desc); - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas); - style = gtk_widget_get_style (widget); - etfci->font_desc = pango_font_description_copy (style->font_desc); -} - -static void -etfci_drop_full_header (ETableFieldChooserItem *etfci) -{ - GObject *header; - - if (!etfci->full_header) - return; - - header = G_OBJECT (etfci->full_header); - if (etfci->full_header_structure_change_id) - g_signal_handler_disconnect ( - header, etfci->full_header_structure_change_id); - if (etfci->full_header_dimension_change_id) - g_signal_handler_disconnect ( - header, etfci->full_header_dimension_change_id); - etfci->full_header_structure_change_id = 0; - etfci->full_header_dimension_change_id = 0; - - if (header) - g_object_unref (header); - etfci->full_header = NULL; - etfci->height = 0; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -full_header_structure_changed (ETableHeader *header, - ETableFieldChooserItem *etfci) -{ - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -full_header_dimension_changed (ETableHeader *header, - gint col, - ETableFieldChooserItem *etfci) -{ - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -etfci_add_full_header (ETableFieldChooserItem *etfci, - ETableHeader *header) -{ - etfci->full_header = header; - g_object_ref (etfci->full_header); - - etfci->full_header_structure_change_id = g_signal_connect ( - header, "structure_change", - G_CALLBACK (full_header_structure_changed), etfci); - etfci->full_header_dimension_change_id = g_signal_connect ( - header, "dimension_change", - G_CALLBACK (full_header_dimension_changed), etfci); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -etfci_drop_table_header (ETableFieldChooserItem *etfci) -{ - GObject *header; - - if (!etfci->header) - return; - - header = G_OBJECT (etfci->header); - if (etfci->table_header_structure_change_id) - g_signal_handler_disconnect ( - header, etfci->table_header_structure_change_id); - if (etfci->table_header_dimension_change_id) - g_signal_handler_disconnect ( - header, etfci->table_header_dimension_change_id); - etfci->table_header_structure_change_id = 0; - etfci->table_header_dimension_change_id = 0; - - if (header) - g_object_unref (header); - etfci->header = NULL; - etfci->height = 0; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -table_header_structure_changed (ETableHeader *header, - ETableFieldChooserItem *etfci) -{ - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -table_header_dimension_changed (ETableHeader *header, - gint col, - ETableFieldChooserItem *etfci) -{ - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -etfci_add_table_header (ETableFieldChooserItem *etfci, - ETableHeader *header) -{ - etfci->header = header; - g_object_ref (etfci->header); - - etfci->table_header_structure_change_id = g_signal_connect ( - header, "structure_change", - G_CALLBACK (table_header_structure_changed), etfci); - etfci->table_header_dimension_change_id = g_signal_connect ( - header, "dimension_change", - G_CALLBACK (table_header_dimension_changed), etfci); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -etfci_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - ETableFieldChooserItem *etfci; - - item = GNOME_CANVAS_ITEM (object); - etfci = E_TABLE_FIELD_CHOOSER_ITEM (object); - - switch (property_id) { - case PROP_FULL_HEADER: - etfci_drop_full_header (etfci); - if (g_value_get_object (value)) - etfci_add_full_header ( - etfci, E_TABLE_HEADER ( - g_value_get_object (value))); - break; - - case PROP_HEADER: - etfci_drop_table_header (etfci); - if (g_value_get_object (value)) - etfci_add_table_header ( - etfci, E_TABLE_HEADER ( - g_value_get_object (value))); - break; - - case PROP_DND_CODE: - g_free (etfci->dnd_code); - etfci->dnd_code = g_strdup (g_value_get_string (value)); - break; - - case PROP_WIDTH: - etfci->width = g_value_get_double (value); - gnome_canvas_item_request_update (item); - break; - } -} - -static void -etfci_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableFieldChooserItem *etfci; - - etfci = E_TABLE_FIELD_CHOOSER_ITEM (object); - - switch (property_id) { - - case PROP_DND_CODE: - g_value_set_string (value, etfci->dnd_code); - break; - case PROP_WIDTH: - g_value_set_double (value, etfci->width); - break; - case PROP_HEIGHT: - g_value_set_double (value, etfci->height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -etfci_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETableFieldChooserItem *etfci) -{ - if (etfci->drag_col != -1) { - gchar *string = g_strdup_printf ("%d", etfci->drag_col); - gtk_selection_data_set ( - selection_data, - GDK_SELECTION_TYPE_STRING, - sizeof (string[0]), - (guchar *) string, - strlen (string)); - g_free (string); - } -} - -static void -etfci_drag_end (GtkWidget *canvas, - GdkDragContext *context, - ETableFieldChooserItem *etfci) -{ - etfci->drag_col = -1; -} - -static void -etfci_realize (GnomeCanvasItem *item) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - - if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize) - (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item); - - if (!etfci->font_desc) - etfci_font_load (etfci); - - etfci->drag_end_id = g_signal_connect ( - item->canvas, "drag_end", - G_CALLBACK (etfci_drag_end), etfci); - etfci->drag_data_get_id = g_signal_connect ( - item->canvas, "drag_data_get", - G_CALLBACK (etfci_drag_data_get), etfci); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etfci)); -} - -static void -etfci_unrealize (GnomeCanvasItem *item) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - - if (etfci->font_desc) - pango_font_description_free (etfci->font_desc); - etfci->font_desc = NULL; - - g_signal_handler_disconnect (item->canvas, etfci->drag_end_id); - etfci->drag_end_id = 0; - g_signal_handler_disconnect (item->canvas, etfci->drag_data_get_id); - etfci->drag_data_get_id = 0; - - if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize)(item); -} - -static void -etfci_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - GnomeCanvas *canvas = item->canvas; - gint rows; - gint y1, y2; - gint row; - - if (etfci->combined_header == NULL) - return; - - rows = e_table_header_count (etfci->combined_header); - - y1 = y2 = 0; - for (row = 0; row < rows; row++, y1 = y2) { - ETableCol *ecol; - - ecol = e_table_header_get_column (etfci->combined_header, row); - - if (ecol->disabled) - continue; - - y2 += e_table_header_compute_height (ecol, GTK_WIDGET (canvas)); - - if (y1 > (y + height)) - break; - - if (y2 < y) - continue; - - cairo_save (cr); - - e_table_header_draw_button ( - cr, ecol, - GTK_WIDGET (canvas), - -x, y1 - y, - width, height, - etfci->width, y2 - y1, - E_TABLE_COL_ARROW_NONE); - - cairo_restore (cr); - } -} - -static GnomeCanvasItem * -etfci_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - return item; -} - -static gboolean -etfci_maybe_start_drag (ETableFieldChooserItem *etfci, - gint x, - gint y) -{ - if (!etfci->maybe_drag) - return FALSE; - - if (MAX (abs (etfci->click_x - x), - abs (etfci->click_y - y)) <= 3) - return FALSE; - - return TRUE; -} - -static void -etfci_start_drag (ETableFieldChooserItem *etfci, - GdkEvent *event, - gdouble x, - gdouble y) -{ - GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas); - GtkTargetList *list; - GdkDragContext *context; - ETableCol *ecol; - cairo_surface_t *cs; - cairo_t *cr; - gint drag_col; - gint button_height; - - GtkTargetEntry etfci_drag_types[] = { - { (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER }, - }; - - if (etfci->combined_header == NULL) - return; - - drag_col = etfci_find_button (etfci, y); - - if (drag_col < 0 || drag_col > e_table_header_count (etfci->combined_header)) - return; - - ecol = e_table_header_get_column (etfci->combined_header, drag_col); - - if (ecol->disabled) - return; - - etfci->drag_col = ecol->col_idx; - - etfci_drag_types[0].target = g_strdup_printf ( - "%s-%s", etfci_drag_types[0].target, etfci->dnd_code); - d (g_print ("etfci - %s\n", etfci_drag_types[0].target)); - list = gtk_target_list_new (etfci_drag_types, G_N_ELEMENTS (etfci_drag_types)); - context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event); - g_free ((gpointer) etfci_drag_types[0].target); - - button_height = e_table_header_compute_height (ecol, widget); - cs = cairo_image_surface_create ( - CAIRO_FORMAT_ARGB32, - etfci->width, button_height); - cr = cairo_create (cs); - - e_table_header_draw_button ( - cr, ecol, - widget, 0, 0, - etfci->width, button_height, - etfci->width, button_height, - E_TABLE_COL_ARROW_NONE); - - gtk_drag_set_icon_surface (context, cs); - - cairo_surface_destroy (cs); - cairo_destroy (cr); - etfci->maybe_drag = FALSE; -} - -/* - * Handles the events on the ETableFieldChooserItem - */ -static gint -etfci_event (GnomeCanvasItem *item, - GdkEvent *e) -{ - ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); - GnomeCanvas *canvas = item->canvas; - gint x, y; - - switch (e->type) { - case GDK_MOTION_NOTIFY: - gnome_canvas_w2c (canvas, e->motion.x, e->motion.y, &x, &y); - - if (etfci_maybe_start_drag (etfci, x, y)) - etfci_start_drag (etfci, e, x, y); - break; - - case GDK_BUTTON_PRESS: - gnome_canvas_w2c (canvas, e->button.x, e->button.y, &x, &y); - - if (e->button.button == 1) { - etfci->click_x = x; - etfci->click_y = y; - etfci->maybe_drag = TRUE; - } - break; - - case GDK_BUTTON_RELEASE: { - etfci->maybe_drag = FALSE; - break; - } - - default: - return FALSE; - } - return TRUE; -} - -static void -etfci_class_init (ETableFieldChooserItemClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etfci_dispose; - object_class->set_property = etfci_set_property; - object_class->get_property = etfci_get_property; - - item_class->update = etfci_update; - item_class->realize = etfci_realize; - item_class->unrealize = etfci_unrealize; - item_class->draw = etfci_draw; - item_class->point = etfci_point; - item_class->event = etfci_event; - - g_object_class_install_property ( - object_class, - PROP_DND_CODE, - g_param_spec_string ( - "dnd_code", - "DnD code", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FULL_HEADER, - g_param_spec_object ( - "full_header", - "Full Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEADER, - g_param_spec_object ( - "header", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - NULL, - 0, G_MAXDOUBLE, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - NULL, - 0, G_MAXDOUBLE, 0, - G_PARAM_READABLE)); -} - -static void -etfci_init (ETableFieldChooserItem *etfci) -{ - etfci->full_header = NULL; - etfci->header = NULL; - etfci->combined_header = NULL; - - etfci->height = etfci->width = 0; - - etfci->font_desc = NULL; - - etfci->full_header_structure_change_id = 0; - etfci->full_header_dimension_change_id = 0; - etfci->table_header_structure_change_id = 0; - etfci->table_header_dimension_change_id = 0; - - etfci->dnd_code = NULL; - - etfci->maybe_drag = 0; - etfci->drag_end_id = 0; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etfci), etfci_reflow); -} - diff --git a/widgets/table/e-table-field-chooser-item.h b/widgets/table/e-table-field-chooser-item.h deleted file mode 100644 index f08b94ac6f..0000000000 --- a/widgets/table/e-table-field-chooser-item.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_FIELD_CHOOSER_ITEM_H_ -#define _E_TABLE_FIELD_CHOOSER_ITEM_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <libxml/tree.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_FIELD_CHOOSER_ITEM \ - (e_table_field_chooser_item_get_type ()) -#define E_TABLE_FIELD_CHOOSER_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_ITEM, ETableFieldChooserItem)) -#define E_TABLE_FIELD_CHOOSER_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER_ITEM, ETableFieldChooserItemClass)) -#define E_IS_TABLE_FIELD_CHOOSER_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_ITEM)) -#define E_IS_TABLE_FIELD_CHOOSER_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER_ITEM)) -#define E_TABLE_FIELD_CHOOSER_ITEM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER_ITEM, ETableFieldChooserItemClass)) - -G_BEGIN_DECLS - -typedef struct _ETableFieldChooserItem ETableFieldChooserItem; -typedef struct _ETableFieldChooserItemClass ETableFieldChooserItemClass; - -struct _ETableFieldChooserItem { - GnomeCanvasItem parent; - - ETableHeader *full_header; - ETableHeader *header; - ETableHeader *combined_header; - - gdouble height, width; - - PangoFontDescription *font_desc; - - /* - * Ids - */ - gint full_header_structure_change_id, full_header_dimension_change_id; - gint table_header_structure_change_id, table_header_dimension_change_id; - - gchar *dnd_code; - - /* - * For dragging columns - */ - guint maybe_drag : 1; - gint click_x, click_y; - gint drag_col; - guint drag_data_get_id; - guint drag_end_id; -}; - -struct _ETableFieldChooserItemClass { - GnomeCanvasItemClass parent_class; -}; - -GType e_table_field_chooser_item_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* _E_TABLE_FIELD_CHOOSER_ITEM_H_ */ diff --git a/widgets/table/e-table-field-chooser.c b/widgets/table/e-table-field-chooser.c deleted file mode 100644 index 50f8267109..0000000000 --- a/widgets/table/e-table-field-chooser.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" - -#include "misc/e-canvas.h" - -#include "e-table-field-chooser.h" -#include "e-table-field-chooser-item.h" - -static void e_table_field_chooser_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void e_table_field_chooser_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void e_table_field_chooser_dispose (GObject *object); - -enum { - PROP_0, - PROP_FULL_HEADER, - PROP_HEADER, - PROP_DND_CODE -}; - -G_DEFINE_TYPE (ETableFieldChooser, e_table_field_chooser, GTK_TYPE_VBOX) - -static void -e_table_field_chooser_class_init (ETableFieldChooserClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - object_class->set_property = e_table_field_chooser_set_property; - object_class->get_property = e_table_field_chooser_get_property; - object_class->dispose = e_table_field_chooser_dispose; - - g_object_class_install_property ( - object_class, - PROP_DND_CODE, - g_param_spec_string ( - "dnd_code", - "DnD code", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FULL_HEADER, - g_param_spec_object ( - "full_header", - "Full Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEADER, - g_param_spec_object ( - "header", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); -} - -static void -ensure_nonzero_step_increments (ETableFieldChooser *etfc) -{ - GtkAdjustment *va, *ha; - - va = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (etfc->canvas)); - ha = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (etfc->canvas)); - - /* - it looks pretty complicated to get height of column header - so use 16 pixels which should be OK - */ - if (va) - gtk_adjustment_set_step_increment (va, 16.0); - if (ha) - gtk_adjustment_set_step_increment (ha, 16.0); -} - -static void allocate_callback (GtkWidget *canvas, GtkAllocation *allocation, ETableFieldChooser *etfc) -{ - gdouble height; - etfc->last_alloc = *allocation; - gnome_canvas_item_set ( - etfc->item, - "width", (gdouble) allocation->width, - NULL); - g_object_get ( - etfc->item, - "height", &height, - NULL); - height = MAX (height, allocation->height); - gnome_canvas_set_scroll_region (GNOME_CANVAS (etfc->canvas), 0, 0, allocation->width - 1, height - 1); - gnome_canvas_item_set ( - etfc->rect, - "x2", (gdouble) allocation->width, - "y2", (gdouble) height, - NULL); - ensure_nonzero_step_increments (etfc); -} - -static void resize (GnomeCanvas *canvas, ETableFieldChooser *etfc) -{ - gdouble height; - g_object_get ( - etfc->item, - "height", &height, - NULL); - - height = MAX (height, etfc->last_alloc.height); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (etfc->canvas), 0, 0, etfc->last_alloc.width - 1, height - 1); - gnome_canvas_item_set ( - etfc->rect, - "x2", (gdouble) etfc->last_alloc.width, - "y2", (gdouble) height, - NULL); - ensure_nonzero_step_increments (etfc); -} - -static GtkWidget * -create_content (GnomeCanvas **canvas) -{ - GtkWidget *vbox_top; - GtkWidget *label1; - GtkWidget *scrolledwindow1; - GtkWidget *canvas_buttons; - - g_return_val_if_fail (canvas != NULL, NULL); - - vbox_top = gtk_vbox_new (FALSE, 4); - gtk_widget_show (vbox_top); - - label1 = gtk_label_new (_("To add a column to your table, drag it into\nthe location in which you want it to appear.")); - gtk_widget_show (label1); - gtk_box_pack_start (GTK_BOX (vbox_top), label1, FALSE, FALSE, 0); - gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_CENTER); - - scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow1); - gtk_box_pack_start (GTK_BOX (vbox_top), scrolledwindow1, TRUE, TRUE, 0); - gtk_widget_set_can_focus (scrolledwindow1, FALSE); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - canvas_buttons = e_canvas_new (); - gtk_widget_show (canvas_buttons); - gtk_container_add (GTK_CONTAINER (scrolledwindow1), canvas_buttons); - gtk_widget_set_can_focus (canvas_buttons, FALSE); - gtk_widget_set_can_default (canvas_buttons, FALSE); - - *canvas = GNOME_CANVAS (canvas_buttons); - - return vbox_top; -} - -static void -e_table_field_chooser_init (ETableFieldChooser *etfc) -{ - GtkWidget *widget; - - widget = create_content (&etfc->canvas); - if (!widget) { - return; - } - - gtk_widget_set_size_request (widget, -1, 250); - gtk_box_pack_start (GTK_BOX (etfc), widget, TRUE, TRUE, 0); - - etfc->rect = gnome_canvas_item_new ( - gnome_canvas_root (GNOME_CANVAS (etfc->canvas)), - gnome_canvas_rect_get_type (), - "x1", (gdouble) 0, - "y1", (gdouble) 0, - "x2", (gdouble) 100, - "y2", (gdouble) 100, - "fill_color", "white", - NULL); - - etfc->item = gnome_canvas_item_new ( - gnome_canvas_root (etfc->canvas), - e_table_field_chooser_item_get_type (), - "width", (gdouble) 100, - "full_header", etfc->full_header, - "header", etfc->header, - "dnd_code", etfc->dnd_code, - NULL); - - g_signal_connect ( - etfc->canvas, "reflow", - G_CALLBACK (resize), etfc); - - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (etfc->canvas), - 0, 0, 100, 100); - - /* Connect the signals */ - g_signal_connect ( - etfc->canvas, "size_allocate", - G_CALLBACK (allocate_callback), etfc); - - gtk_widget_show_all (widget); -} - -static void -e_table_field_chooser_dispose (GObject *object) -{ - ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object); - - g_free (etfc->dnd_code); - etfc->dnd_code = NULL; - - if (etfc->full_header) - g_object_unref (etfc->full_header); - etfc->full_header = NULL; - - if (etfc->header) - g_object_unref (etfc->header); - etfc->header = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_table_field_chooser_parent_class)->dispose (object); -} - -GtkWidget * -e_table_field_chooser_new (void) -{ - return g_object_new (E_TYPE_TABLE_FIELD_CHOOSER, NULL); -} - -static void -e_table_field_chooser_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object); - - switch (property_id) { - case PROP_DND_CODE: - g_free (etfc->dnd_code); - etfc->dnd_code = g_strdup (g_value_get_string (value)); - if (etfc->item) - g_object_set ( - etfc->item, - "dnd_code", etfc->dnd_code, - NULL); - break; - case PROP_FULL_HEADER: - if (etfc->full_header) - g_object_unref (etfc->full_header); - if (g_value_get_object (value)) - etfc->full_header = E_TABLE_HEADER (g_value_get_object (value)); - else - etfc->full_header = NULL; - if (etfc->full_header) - g_object_ref (etfc->full_header); - if (etfc->item) - g_object_set ( - etfc->item, - "full_header", etfc->full_header, - NULL); - break; - case PROP_HEADER: - if (etfc->header) - g_object_unref (etfc->header); - if (g_value_get_object (value)) - etfc->header = E_TABLE_HEADER (g_value_get_object (value)); - else - etfc->header = NULL; - if (etfc->header) - g_object_ref (etfc->header); - if (etfc->item) - g_object_set ( - etfc->item, - "header", etfc->header, - NULL); - break; - default: - break; - } -} - -static void -e_table_field_chooser_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object); - - switch (property_id) { - case PROP_DND_CODE: - g_value_set_string (value, etfc->dnd_code); - break; - case PROP_FULL_HEADER: - g_value_set_object (value, etfc->full_header); - break; - case PROP_HEADER: - g_value_set_object (value, etfc->header); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} diff --git a/widgets/table/e-table-field-chooser.h b/widgets/table/e-table-field-chooser.h deleted file mode 100644 index a594fa2ae5..0000000000 --- a/widgets/table/e-table-field-chooser.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_TABLE_FIELD_CHOOSER_H__ -#define __E_TABLE_FIELD_CHOOSER_H__ - -#include <gtk/gtk.h> -#include <table/e-table-header.h> -#include <libgnomecanvas/libgnomecanvas.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_FIELD_CHOOSER \ - (e_table_field_chooser_get_type ()) -#define E_TABLE_FIELD_CHOOSER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER, ETableFieldChooser)) -#define E_TABLE_FIELD_CHOOSER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER, ETableFieldChooserClass)) -#define E_IS_TABLE_FIELD_CHOOSER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER)) -#define E_IS_TABLE_FIELD_CHOOSER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_FIELD_CHOOSER)) -#define E_TABLE_FIELD_CHOOSER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_FIELD_CHOOSER, ETableFieldChooserClass)) - -G_BEGIN_DECLS - -typedef struct _ETableFieldChooser ETableFieldChooser; -typedef struct _ETableFieldChooserClass ETableFieldChooserClass; - -struct _ETableFieldChooser { - GtkBox parent; - - /* item specific fields */ - GnomeCanvas *canvas; - GnomeCanvasItem *item; - - GnomeCanvasItem *rect; - GtkAllocation last_alloc; - - gchar *dnd_code; - ETableHeader *full_header; - ETableHeader *header; -}; - -struct _ETableFieldChooserClass { - GtkBoxClass parent_class; -}; - -GType e_table_field_chooser_get_type (void) G_GNUC_CONST; -GtkWidget * e_table_field_chooser_new (void); - -G_END_DECLS - -#endif /* __E_TABLE_FIELD_CHOOSER_H__ */ diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c deleted file mode 100644 index 27f3116d26..0000000000 --- a/widgets/table/e-table-group-container.c +++ /dev/null @@ -1,1668 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "text/e-text.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas-utils.h" -#include "misc/e-canvas.h" -#include "e-util/e-unicode.h" - -#include "e-table-defines.h" -#include "e-table-group-container.h" -#include "e-table-group-leaf.h" -#include "e-table-item.h" -#include "e-table-sorting-utils.h" - -#define TITLE_HEIGHT 16 - -/* workaround for avoiding API breakage */ -#define etgc_get_type e_table_group_container_get_type -G_DEFINE_TYPE (ETableGroupContainer, etgc, E_TYPE_TABLE_GROUP) - -enum { - PROP_0, - PROP_HEIGHT, - PROP_WIDTH, - PROP_MINIMUM_WIDTH, - PROP_FROZEN, - PROP_TABLE_ALTERNATING_ROW_COLORS, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - PROP_TABLE_VERTICAL_DRAW_GRID, - PROP_TABLE_DRAW_FOCUS, - PROP_CURSOR_MODE, - PROP_SELECTION_MODEL, - PROP_LENGTH_THRESHOLD, - PROP_UNIFORM_ROW_HEIGHT -}; - -static EPrintable * -etgc_get_printable (ETableGroup *etg); - -static void -e_table_group_container_child_node_free (ETableGroupContainer *etgc, - ETableGroupContainerChildNode *child_node) -{ - ETableGroup *etg = E_TABLE_GROUP (etgc); - ETableGroup *child = child_node->child; - - g_object_run_dispose (G_OBJECT (child)); - e_table_model_free_value ( - etg->model, etgc->ecol->col_idx, - child_node->key); - g_free (child_node->string); - g_object_run_dispose (G_OBJECT (child_node->text)); - g_object_run_dispose (G_OBJECT (child_node->rect)); -} - -static void -e_table_group_container_list_free (ETableGroupContainer *etgc) -{ - ETableGroupContainerChildNode *child_node; - GList *list; - - for (list = etgc->children; list; list = g_list_next (list)) { - child_node = (ETableGroupContainerChildNode *) list->data; - e_table_group_container_child_node_free (etgc, child_node); - } - - g_list_free (etgc->children); - etgc->children = NULL; -} - -static void -etgc_dispose (GObject *object) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); - - if (etgc->children) - e_table_group_container_list_free (etgc); - - if (etgc->font_desc) - pango_font_description_free (etgc->font_desc); - etgc->font_desc = NULL; - - if (etgc->ecol) - g_object_unref (etgc->ecol); - etgc->ecol = NULL; - - if (etgc->sort_info) - g_object_unref (etgc->sort_info); - etgc->sort_info = NULL; - - if (etgc->selection_model) - g_object_unref (etgc->selection_model); - etgc->selection_model = NULL; - - if (etgc->rect) - g_object_run_dispose (G_OBJECT (etgc->rect)); - etgc->rect = NULL; - - G_OBJECT_CLASS (etgc_parent_class)->dispose (object); -} - -/** - * e_table_group_container_construct - * @parent: The %GnomeCanvasGroup to create a child of. - * @etgc: The %ETableGroupContainer. - * @full_header: The full header of the %ETable. - * @header: The current header of the %ETable. - * @model: The %ETableModel of the %ETable. - * @sort_info: The %ETableSortInfo of the %ETable. - * @n: Which grouping level this is (Starts at 0 and sends n + 1 to any child %ETableGroups. - * - * This routine constructs the new %ETableGroupContainer. - */ -void -e_table_group_container_construct (GnomeCanvasGroup *parent, - ETableGroupContainer *etgc, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n) -{ - ETableCol *col; - ETableSortColumn column = e_table_sort_info_grouping_get_nth (sort_info, n); - GtkWidget *widget; - GtkStyle *style; - - col = e_table_header_get_column_by_col_idx (full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - - e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model); - etgc->ecol = col; - g_object_ref (etgc->ecol); - etgc->sort_info = sort_info; - g_object_ref (etgc->sort_info); - etgc->n = n; - etgc->ascending = column.ascending; - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etgc)->canvas); - style = gtk_widget_get_style (widget); - etgc->font_desc = pango_font_description_copy (style->font_desc); - - etgc->open = TRUE; -} - -/** - * e_table_group_container_new - * @parent: The %GnomeCanvasGroup to create a child of. - * @full_header: The full header of the %ETable. - * @header: The current header of the %ETable. - * @model: The %ETableModel of the %ETable. - * @sort_info: The %ETableSortInfo of the %ETable. - * @n: Which grouping level this is (Starts at 0 and sends n + 1 to any child %ETableGroups. - * - * %ETableGroupContainer is an %ETableGroup which groups by the nth - * grouping of the %ETableSortInfo. It creates %ETableGroups as - * children. - * - * Returns: The new %ETableGroupContainer. - */ -ETableGroup * -e_table_group_container_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n) -{ - ETableGroupContainer *etgc; - - g_return_val_if_fail (parent != NULL, NULL); - - etgc = g_object_new (E_TYPE_TABLE_GROUP_CONTAINER, NULL); - - e_table_group_container_construct ( - parent, etgc, full_header, header, - model, sort_info, n); - return E_TABLE_GROUP (etgc); -} - -static gint -etgc_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item); - gboolean return_val = TRUE; - gboolean change_focus = FALSE; - gboolean use_col = FALSE; - gint start_col = 0; - gint old_col; - EFocus direction = E_FOCUS_START; - - switch (event->type) { - case GDK_KEY_PRESS: - if (event->key.keyval == GDK_KEY_Tab || - event->key.keyval == GDK_KEY_KP_Tab || - event->key.keyval == GDK_KEY_ISO_Left_Tab) { - change_focus = TRUE; - use_col = TRUE; - start_col = (event->key.state & GDK_SHIFT_MASK) ? -1 : 0; - direction = (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START; - } else if (event->key.keyval == GDK_KEY_Left || - event->key.keyval == GDK_KEY_KP_Left) { - change_focus = TRUE; - use_col = TRUE; - start_col = -1; - direction = E_FOCUS_END; - } else if (event->key.keyval == GDK_KEY_Right || - event->key.keyval == GDK_KEY_KP_Right) { - change_focus = TRUE; - use_col = TRUE; - start_col = 0; - direction = E_FOCUS_START; - } else if (event->key.keyval == GDK_KEY_Down || - event->key.keyval == GDK_KEY_KP_Down) { - change_focus = TRUE; - use_col = FALSE; - direction = E_FOCUS_START; - } else if (event->key.keyval == GDK_KEY_Up || - event->key.keyval == GDK_KEY_KP_Up) { - change_focus = TRUE; - use_col = FALSE; - direction = E_FOCUS_END; - } else if (event->key.keyval == GDK_KEY_Return || - event->key.keyval == GDK_KEY_KP_Enter) { - change_focus = TRUE; - use_col = FALSE; - direction = E_FOCUS_START; - } - if (change_focus) { - GList *list; - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node; - ETableGroup *child; - - child_node = (ETableGroupContainerChildNode *) list->data; - child = child_node->child; - - if (e_table_group_get_focus (child)) { - old_col = e_table_group_get_focus_column (child); - if (old_col == -1) - old_col = 0; - if (start_col == -1) - start_col = e_table_header_count (e_table_group_get_header (child)) - 1; - - if (direction == E_FOCUS_END) - list = list->prev; - else - list = list->next; - - if (list) { - child_node = (ETableGroupContainerChildNode *) list->data; - child = child_node->child; - if (use_col) - e_table_group_set_focus (child, direction, start_col); - else - e_table_group_set_focus (child, direction, old_col); - return 1; - } else { - return 0; - } - } - } - if (direction == E_FOCUS_END) - list = g_list_last (etgc->children); - else - list = etgc->children; - if (list) { - ETableGroupContainerChildNode *child_node; - ETableGroup *child; - - child_node = (ETableGroupContainerChildNode *) list->data; - child = child_node->child; - - if (start_col == -1) - start_col = e_table_header_count (e_table_group_get_header (child)) - 1; - - e_table_group_set_focus (child, direction, start_col); - return 1; - } - } - return_val = FALSE; - break; - default: - return_val = FALSE; - break; - } - if (return_val == FALSE) { - if (GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->event) - return GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->event (item, event); - } - return return_val; - -} - -/* Realize handler for the text item */ -static void -etgc_realize (GnomeCanvasItem *item) -{ - ETableGroupContainer *etgc; - - if (GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize) (item); - - etgc = E_TABLE_GROUP_CONTAINER (item); - - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); -} - -/* Unrealize handler for the etgc item */ -static void -etgc_unrealize (GnomeCanvasItem *item) -{ - if (GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize) - (* GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize) (item); -} - -static void -compute_text (ETableGroupContainer *etgc, - ETableGroupContainerChildNode *child_node) -{ - gchar *text; - - if (etgc->ecol->text) { - /* Translators: This text is used as a special row when an ETable - * has turned on grouping on a column, which has set a title. - * The first %s is replaced with a column title. - * The second %s is replaced with an actual group value. - * Finally the %d is replaced with count of items in this group. - * Example: "Family name: Smith (13 items)" - */ - text = g_strdup_printf ( - ngettext ( - "%s: %s (%d item)", - "%s: %s (%d items)", - child_node->count), - etgc->ecol->text, child_node->string, - (gint) child_node->count); - } else { - /* Translators: This text is used as a special row when an ETable - * has turned on grouping on a column, which doesn't have set a title. - * The %s is replaced with an actual group value. - * The %d is replaced with count of items in this group. - * Example: "Smith (13 items)" - */ - text = g_strdup_printf ( - ngettext ( - "%s (%d item)", - "%s (%d items)", - child_node->count), - child_node->string, - (gint) child_node->count); - } - gnome_canvas_item_set ( - child_node->text, - "text", text, - NULL); - g_free (text); -} - -static void -child_cursor_change (ETableGroup *etg, - gint row, - ETableGroupContainer *etgc) -{ - e_table_group_cursor_change (E_TABLE_GROUP (etgc), row); -} - -static void -child_cursor_activated (ETableGroup *etg, - gint row, - ETableGroupContainer *etgc) -{ - e_table_group_cursor_activated (E_TABLE_GROUP (etgc), row); -} - -static void -child_double_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETableGroupContainer *etgc) -{ - e_table_group_double_click (E_TABLE_GROUP (etgc), row, col, event); -} - -static gboolean -child_right_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETableGroupContainer *etgc) -{ - return e_table_group_right_click (E_TABLE_GROUP (etgc), row, col, event); -} - -static gboolean -child_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETableGroupContainer *etgc) -{ - return e_table_group_click (E_TABLE_GROUP (etgc), row, col, event); -} - -static gboolean -child_key_press (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETableGroupContainer *etgc) -{ - return e_table_group_key_press (E_TABLE_GROUP (etgc), row, col, event); -} - -static gboolean -child_start_drag (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETableGroupContainer *etgc) -{ - return e_table_group_start_drag (E_TABLE_GROUP (etgc), row, col, event); -} - -static ETableGroupContainerChildNode * -create_child_node (ETableGroupContainer *etgc, - gpointer val) -{ - ETableGroup *child; - ETableGroupContainerChildNode *child_node; - ETableGroup *etg = E_TABLE_GROUP (etgc); - - child_node = g_new (ETableGroupContainerChildNode, 1); - child_node->rect = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etgc), - gnome_canvas_rect_get_type (), - "fill_color", "grey70", - "outline_color", "grey50", - NULL); - child_node->text = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etgc), - e_text_get_type (), - "fill_color", "black", - NULL); - child = e_table_group_new ( - GNOME_CANVAS_GROUP (etgc), etg->full_header, - etg->header, etg->model, etgc->sort_info, etgc->n + 1); - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (child), - "alternating_row_colors", etgc->alternating_row_colors, - "horizontal_draw_grid", etgc->horizontal_draw_grid, - "vertical_draw_grid", etgc->vertical_draw_grid, - "drawfocus", etgc->draw_focus, - "cursor_mode", etgc->cursor_mode, - "selection_model", etgc->selection_model, - "length_threshold", etgc->length_threshold, - "uniform_row_height", etgc->uniform_row_height, - "minimum_width", etgc->minimum_width - GROUP_INDENT, - NULL); - - g_signal_connect ( - child, "cursor_change", - G_CALLBACK (child_cursor_change), etgc); - g_signal_connect ( - child, "cursor_activated", - G_CALLBACK (child_cursor_activated), etgc); - g_signal_connect ( - child, "double_click", - G_CALLBACK (child_double_click), etgc); - g_signal_connect ( - child, "right_click", - G_CALLBACK (child_right_click), etgc); - g_signal_connect ( - child, "click", - G_CALLBACK (child_click), etgc); - g_signal_connect ( - child, "key_press", - G_CALLBACK (child_key_press), etgc); - g_signal_connect ( - child, "start_drag", - G_CALLBACK (child_start_drag), etgc); - child_node->child = child; - child_node->key = e_table_model_duplicate_value (etg->model, etgc->ecol->col_idx, val); - child_node->string = e_table_model_value_to_string (etg->model, etgc->ecol->col_idx, val); - child_node->count = 0; - - return child_node; -} - -static void -etgc_add (ETableGroup *etg, - gint row) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - gpointer val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, row); - GCompareDataFunc comp = etgc->ecol->compare; - gpointer cmp_cache = e_table_sorting_utils_create_cmp_cache (); - GList *list = etgc->children; - ETableGroup *child; - ETableGroupContainerChildNode *child_node; - gint i = 0; - - for (; list; list = g_list_next (list), i++) { - gint comp_val; - - child_node = list->data; - comp_val = (*comp)(child_node->key, val, cmp_cache); - if (comp_val == 0) { - e_table_sorting_utils_free_cmp_cache (cmp_cache); - child = child_node->child; - child_node->count++; - e_table_group_add (child, row); - compute_text (etgc, child_node); - return; - } - if ((comp_val > 0 && etgc->ascending) || - (comp_val < 0 && (!etgc->ascending))) - break; - } - e_table_sorting_utils_free_cmp_cache (cmp_cache); - child_node = create_child_node (etgc, val); - child = child_node->child; - child_node->count = 1; - e_table_group_add (child, row); - - if (list) - etgc->children = g_list_insert (etgc->children, child_node, i); - else - etgc->children = g_list_append (etgc->children, child_node); - - compute_text (etgc, child_node); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); -} - -static void -etgc_add_array (ETableGroup *etg, - const gint *array, - gint count) -{ - gint i; - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - gpointer lastval = NULL; - gint laststart = 0; - GCompareDataFunc comp = etgc->ecol->compare; - gpointer cmp_cache; - ETableGroupContainerChildNode *child_node; - ETableGroup *child; - - if (count <= 0) - return; - - e_table_group_container_list_free (etgc); - etgc->children = NULL; - cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - lastval = e_table_model_value_at (etg->model, etgc->ecol->col_idx, array[0]); - - for (i = 1; i < count; i++) { - gpointer val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, array[i]); - gint comp_val; - - comp_val = (*comp)(lastval, val, cmp_cache); - if (comp_val != 0) { - child_node = create_child_node (etgc, lastval); - child = child_node->child; - - e_table_group_add_array (child, array + laststart, i - laststart); - child_node->count = i - laststart; - - etgc->children = g_list_append (etgc->children, child_node); - compute_text (etgc, child_node); - laststart = i; - lastval = val; - } - } - - e_table_sorting_utils_free_cmp_cache (cmp_cache); - - child_node = create_child_node (etgc, lastval); - child = child_node->child; - - e_table_group_add_array (child, array + laststart, i - laststart); - child_node->count = i - laststart; - - etgc->children = g_list_append (etgc->children, child_node); - compute_text (etgc, child_node); - - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); -} - -static void -etgc_add_all (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - ESorter *sorter = etgc->selection_model->sorter; - gint *array; - gint count; - - e_sorter_get_sorted_to_model_array (sorter, &array, &count); - - etgc_add_array (etg, array, count); -} - -static gboolean -etgc_remove (ETableGroup *etg, - gint row) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list; - - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = list->data; - ETableGroup *child = child_node->child; - - if (e_table_group_remove (child, row)) { - child_node->count--; - if (child_node->count == 0) { - e_table_group_container_child_node_free (etgc, child_node); - etgc->children = g_list_remove (etgc->children, child_node); - g_free (child_node); - } else - compute_text (etgc, child_node); - - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); - - return TRUE; - } - } - return FALSE; -} - -static gint -etgc_row_count (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list; - gint count = 0; - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroup *group = ((ETableGroupContainerChildNode *) list->data)->child; - gint this_count = e_table_group_row_count (group); - count += this_count; - } - return count; -} - -static void -etgc_increment (ETableGroup *etg, - gint position, - gint amount) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list; - - for (list = etgc->children; list; list = g_list_next (list)) - e_table_group_increment ( - ((ETableGroupContainerChildNode *) list->data)->child, - position, amount); -} - -static void -etgc_decrement (ETableGroup *etg, - gint position, - gint amount) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list; - - for (list = etgc->children; list; list = g_list_next (list)) - e_table_group_decrement ( - ((ETableGroupContainerChildNode *) list->data)->child, - position, amount); -} - -static void -etgc_set_focus (ETableGroup *etg, - EFocus direction, - gint view_col) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - if (etgc->children) { - if (direction == E_FOCUS_END) - e_table_group_set_focus ( - ((ETableGroupContainerChildNode *) g_list_last (etgc->children)->data)->child, - direction, view_col); - else - e_table_group_set_focus ( - ((ETableGroupContainerChildNode *) etgc->children->data)->child, - direction, view_col); - } -} - -static gint -etgc_get_focus_column (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - if (etgc->children) { - GList *list; - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - if (e_table_group_get_focus (child)) { - return e_table_group_get_focus_column (child); - } - } - } - return 0; -} - -static void -etgc_compute_location (ETableGroup *etg, - gint *x, - gint *y, - gint *prow, - gint *pcol) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - gint row = -1, col = -1; - - *x -= GROUP_INDENT; - *y -= TITLE_HEIGHT; - - if (*x >= 0 && *y >= 0 && etgc->children) { - GList *list; - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - - e_table_group_compute_location (child, x, y, &row, &col); - if (row != -1 && col != -1) - break; - } - } - - if (prow) - *prow = row; - if (pcol) - *pcol = col; -} - -static void -etgc_get_mouse_over (ETableGroup *etg, - gint *row, - gint *col) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - - if (row) - *row = -1; - if (col) - *col = -1; - - if (etgc->children) { - gint row_plus = 0; - GList *list; - - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - - e_table_group_get_mouse_over (child, row, col); - - if ((!row || *row != -1) && (!col || *col != -1)) { - if (row) - *row += row_plus; - return; - } - - row_plus += e_table_group_row_count (child); - } - } -} - -static void -etgc_get_cell_geometry (ETableGroup *etg, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - - gint ypos; - - ypos = 0; - - if (etgc->children) { - GList *list; - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - gint thisy; - - e_table_group_get_cell_geometry (child, row, col, x, &thisy, width, height); - ypos += thisy; - if ((*row == -1) || (*col == -1)) { - ypos += TITLE_HEIGHT; - *x += GROUP_INDENT; - *y = ypos; - return; - } - } - } -} - -static void etgc_thaw (ETableGroup *etg) -{ - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etg)); -} - -static void -etgc_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); - GList *list; - - switch (property_id) { - case PROP_FROZEN: - if (g_value_get_boolean (value)) - etg->frozen = TRUE; - else { - etg->frozen = FALSE; - etgc_thaw (etg); - } - break; - case PROP_MINIMUM_WIDTH: - case PROP_WIDTH: - etgc->minimum_width = g_value_get_double (value); - - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "minimum_width", etgc->minimum_width - GROUP_INDENT, - NULL); - } - break; - case PROP_LENGTH_THRESHOLD: - etgc->length_threshold = g_value_get_int (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "length_threshold", etgc->length_threshold, - NULL); - } - break; - case PROP_UNIFORM_ROW_HEIGHT: - etgc->uniform_row_height = g_value_get_boolean (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "uniform_row_height", etgc->uniform_row_height, - NULL); - } - break; - - case PROP_SELECTION_MODEL: - if (etgc->selection_model) - g_object_unref (etgc->selection_model); - etgc->selection_model = E_SELECTION_MODEL (g_value_get_object (value)); - if (etgc->selection_model) - g_object_ref (etgc->selection_model); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "selection_model", etgc->selection_model, - NULL); - } - break; - - case PROP_TABLE_ALTERNATING_ROW_COLORS: - etgc->alternating_row_colors = g_value_get_boolean (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "alternating_row_colors", etgc->alternating_row_colors, - NULL); - } - break; - - case PROP_TABLE_HORIZONTAL_DRAW_GRID: - etgc->horizontal_draw_grid = g_value_get_boolean (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "horizontal_draw_grid", etgc->horizontal_draw_grid, - NULL); - } - break; - - case PROP_TABLE_VERTICAL_DRAW_GRID: - etgc->vertical_draw_grid = g_value_get_boolean (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "vertical_draw_grid", etgc->vertical_draw_grid, - NULL); - } - break; - - case PROP_TABLE_DRAW_FOCUS: - etgc->draw_focus = g_value_get_boolean (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "drawfocus", etgc->draw_focus, - NULL); - } - break; - - case PROP_CURSOR_MODE: - etgc->cursor_mode = g_value_get_int (value); - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - g_object_set ( - child_node->child, - "cursor_mode", etgc->cursor_mode, - NULL); - } - break; - default: - break; - } -} - -static void -etgc_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); - - switch (property_id) { - case PROP_FROZEN: - g_value_set_boolean (value, etg->frozen); - break; - case PROP_HEIGHT: - g_value_set_double (value, etgc->height); - break; - case PROP_WIDTH: - g_value_set_double (value, etgc->width); - break; - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, etgc->minimum_width); - break; - case PROP_UNIFORM_ROW_HEIGHT: - g_value_set_boolean (value, etgc->uniform_row_height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -etgc_class_init (ETableGroupContainerClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS (class); - - object_class->dispose = etgc_dispose; - object_class->set_property = etgc_set_property; - object_class->get_property = etgc_get_property; - - item_class->event = etgc_event; - item_class->realize = etgc_realize; - item_class->unrealize = etgc_unrealize; - - e_group_class->add = etgc_add; - e_group_class->add_array = etgc_add_array; - e_group_class->add_all = etgc_add_all; - e_group_class->remove = etgc_remove; - e_group_class->increment = etgc_increment; - e_group_class->decrement = etgc_decrement; - e_group_class->row_count = etgc_row_count; - e_group_class->set_focus = etgc_set_focus; - e_group_class->get_focus_column = etgc_get_focus_column; - e_group_class->get_printable = etgc_get_printable; - e_group_class->compute_location = etgc_compute_location; - e_group_class->get_mouse_over = etgc_get_mouse_over; - e_group_class->get_cell_geometry = etgc_get_cell_geometry; - - g_object_class_install_property ( - object_class, - PROP_TABLE_ALTERNATING_ROW_COLORS, - g_param_spec_boolean ( - "alternating_row_colors", - "Alternating Row Colors", - "Alternating Row Colors", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - g_param_spec_boolean ( - "horizontal_draw_grid", - "Horizontal Draw Grid", - "Horizontal Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_VERTICAL_DRAW_GRID, - g_param_spec_boolean ( - "vertical_draw_grid", - "Vertical Draw Grid", - "Vertical Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_DRAW_FOCUS, - g_param_spec_boolean ( - "drawfocus", - "Draw focus", - "Draw focus", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_MODE, - g_param_spec_int ( - "cursor_mode", - "Cursor mode", - "Cursor mode", - E_CURSOR_LINE, - E_CURSOR_SPREADSHEET, - E_CURSOR_LINE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTION_MODEL, - g_param_spec_object ( - "selection_model", - "Selection model", - "Selection model", - E_TYPE_SELECTION_MODEL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_LENGTH_THRESHOLD, - g_param_spec_int ( - "length_threshold", - "Length Threshold", - "Length Threshold", - -1, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UNIFORM_ROW_HEIGHT, - g_param_spec_boolean ( - "uniform_row_height", - "Uniform row height", - "Uniform row height", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FROZEN, - g_param_spec_boolean ( - "frozen", - "Frozen", - "Frozen", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_WIDTH, - g_param_spec_double ( - "minimum_width", - "Minimum width", - "Minimum Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); -} - -static void -etgc_reflow (GnomeCanvasItem *item, - gint flags) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item); - gboolean frozen; - - g_object_get ( - etgc, - "frozen", &frozen, - NULL); - - if (frozen) - return; - - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) { - gdouble running_height = 0; - gdouble running_width = 0; - gdouble old_height; - gdouble old_width; - - old_height = etgc->height; - old_width = etgc->width; - if (etgc->children == NULL) { - } else { - GList *list; - gdouble extra_height = 0; - gdouble item_height = 0; - gdouble item_width = 0; - - if (etgc->font_desc) { - PangoContext *context; - PangoFontMetrics *metrics; - - context = gtk_widget_get_pango_context (GTK_WIDGET (item->canvas)); - metrics = pango_context_get_metrics (context, etgc->font_desc, NULL); - extra_height += - PANGO_PIXELS (pango_font_metrics_get_ascent (metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (metrics)) + - BUTTON_PADDING * 2; - pango_font_metrics_unref (metrics); - } - - extra_height = MAX (extra_height, BUTTON_HEIGHT + BUTTON_PADDING * 2); - - running_height = extra_height; - - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - - g_object_get ( - child, - "width", &item_width, - NULL); - - if (item_width > running_width) - running_width = item_width; - } - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; - ETableGroup *child = child_node->child; - g_object_get ( - child, - "height", &item_height, - NULL); - - e_canvas_item_move_absolute ( - GNOME_CANVAS_ITEM (child_node->text), - GROUP_INDENT, - running_height - GROUP_INDENT - BUTTON_PADDING); - - e_canvas_item_move_absolute ( - GNOME_CANVAS_ITEM (child), - GROUP_INDENT, - running_height); - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (child_node->rect), - "x1", (gdouble) 0, - "x2", (gdouble) running_width + GROUP_INDENT, - "y1", (gdouble) running_height - extra_height, - "y2", (gdouble) running_height + item_height, - NULL); - - running_height += item_height + extra_height; - } - running_height -= extra_height; - } - if (running_height != old_height || running_width != old_width) { - etgc->height = running_height; - etgc->width = running_width; - e_canvas_item_request_parent_reflow (item); - } - } -} - -static void -etgc_init (ETableGroupContainer *container) -{ - container->children = NULL; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (container), etgc_reflow); - - container->alternating_row_colors = 1; - container->horizontal_draw_grid = 1; - container->vertical_draw_grid = 1; - container->draw_focus = 1; - container->cursor_mode = E_CURSOR_SIMPLE; - container->length_threshold = -1; - container->selection_model = NULL; - container->uniform_row_height = FALSE; -} - -void -e_table_group_apply_to_leafs (ETableGroup *etg, - ETableGroupLeafFn fn, - gpointer closure) -{ - if (E_IS_TABLE_GROUP_CONTAINER (etg)) { - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list; - - /* Protect from unrefs in the callback functions */ - g_object_ref (etg); - - for (list = etgc->children; list; list = list->next) { - ETableGroupContainerChildNode *child_node = list->data; - - e_table_group_apply_to_leafs (child_node->child, fn, closure); - } - - g_object_unref (etg); - } else if (E_IS_TABLE_GROUP_LEAF (etg)) { - (*fn) (E_TABLE_GROUP_LEAF (etg)->item, closure); - } else { - g_error ( - "Unknown ETableGroup found: %s", - g_type_name (G_TYPE_FROM_INSTANCE (etg))); - } -} - -typedef struct { - ETableGroupContainer *etgc; - GList *child; - EPrintable *child_printable; -} ETGCPrintContext; - -#define CHECK(x) if((x) == -1) return -1; - -#if 0 -static gint -gp_draw_rect (GtkPrintContext *context, - gdouble x, - gdouble y, - gdouble width, - gdouble height) -{ - cairo_t *cr; - cr = gtk_print_context_get_cairo_context (context); - cairo_move_to (cr, x, y); - cairo_rectangle (cr, x, y, x + width, y + height); - cairo_fill (cr); -} -#endif - -#define TEXT_HEIGHT (12) -#define TEXT_AREA_HEIGHT (TEXT_HEIGHT + 4) - -static void -e_table_group_container_print_page (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble height, - gboolean quantize, - ETGCPrintContext *groupcontext) -{ - cairo_t *cr = NULL; - GtkPageSetup *setup; - gdouble yd; - gdouble page_height, page_margin; - gdouble child_height, child_margin = 0; - ETableGroupContainerChildNode *child_node; - GList *child; - EPrintable *child_printable; - gchar *string; - PangoLayout *layout; - PangoFontDescription *desc; - - child_printable = groupcontext->child_printable; - child = groupcontext->child; - setup = gtk_print_context_get_page_setup (context); - page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS); - page_margin = gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_POINTS) + gtk_page_setup_get_top_margin (setup, GTK_UNIT_POINTS); - yd = page_height - page_margin; - - if (child_printable) { - if (child) - child_node = child->data; - else - child_node = NULL; - g_object_ref (child_printable); - } else { - if (!child) { - return; - } else { - child_node = child->data; - child_printable = e_table_group_get_printable (child_node->child); - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - } - - layout = gtk_print_context_create_pango_layout (context); - - desc = pango_font_description_new (); - pango_font_description_set_family_static (desc, "Helvetica"); - pango_font_description_set_size (desc, TEXT_HEIGHT); - pango_layout_set_font_description (layout, desc); - pango_font_description_free (desc); - - while (1) { - child_height = e_printable_height (child_printable, context, width,yd, quantize); - if (child_height < 0) - child_height = -child_height; - if (cr && yd < 2 * TEXT_AREA_HEIGHT + 20 + child_height) { - cairo_show_page (cr); - cairo_translate (cr, -2 * TEXT_AREA_HEIGHT, -TEXT_AREA_HEIGHT); - break; - } - - cr = gtk_print_context_get_cairo_context (context); - cairo_save (cr); - cairo_rectangle (cr, 0.0, 0.0, width, TEXT_AREA_HEIGHT); - cairo_rectangle (cr, 0.0, 0.0, 2 * TEXT_AREA_HEIGHT, child_height + 2 * TEXT_AREA_HEIGHT); - cairo_set_source_rgb (cr, .7, .7, .7); - cairo_fill (cr); - cairo_restore (cr); - child_margin = TEXT_AREA_HEIGHT; - - cairo_save (cr); - cairo_rectangle (cr, 2 * TEXT_AREA_HEIGHT, TEXT_AREA_HEIGHT, width - 2 * TEXT_AREA_HEIGHT, TEXT_AREA_HEIGHT); - cairo_clip (cr); - cairo_restore (cr); - - if (child_node) { - cairo_move_to (cr, 0, 0); - if (groupcontext->etgc->ecol->text) - string = g_strdup_printf ( - "%s : %s (%d item%s)", - groupcontext->etgc->ecol->text, - child_node->string, - (gint) child_node->count, - child_node->count == 1 ? "" : "s"); - else - string = g_strdup_printf ( - "%s (%d item%s)", - child_node->string, - (gint) child_node->count, - child_node->count == 1 ? "" : "s"); - pango_layout_set_text (layout, string, -1); - pango_cairo_show_layout (cr, layout); - g_free (string); - } - - cairo_translate (cr, 2 * TEXT_AREA_HEIGHT, TEXT_AREA_HEIGHT); - cairo_move_to (cr, 0, 0); - cairo_save (cr); - cairo_rectangle (cr, 0, child_margin, width - 2 * TEXT_AREA_HEIGHT, child_height + child_margin + 20); - cairo_clip (cr); - - e_printable_print_page (child_printable, context, width - 2 * TEXT_AREA_HEIGHT, child_margin, quantize); - yd -= child_height + TEXT_AREA_HEIGHT; - - if (e_printable_data_left (child_printable)) { - cairo_restore (cr); - cairo_translate (cr, -2 * TEXT_AREA_HEIGHT, -TEXT_AREA_HEIGHT); - break; - } - - child = child->next; - if (!child) { - child_printable = NULL; - break; - } - - child_node = child->data; - if (child_printable) - g_object_unref (child_printable); - - child_printable = e_table_group_get_printable (child_node->child); - cairo_restore (cr); - cairo_translate (cr, -2 * TEXT_AREA_HEIGHT, child_height + child_margin + 20); - - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - if (groupcontext->child_printable) - g_object_unref (groupcontext->child_printable); - groupcontext->child_printable = child_printable; - groupcontext->child = child; - - g_object_unref (layout); -} - -static gboolean -e_table_group_container_data_left (EPrintable *ep, - ETGCPrintContext *groupcontext) -{ - g_signal_stop_emission_by_name (ep, "data_left"); - return groupcontext->child != NULL; -} - -static void -e_table_group_container_reset (EPrintable *ep, - ETGCPrintContext *groupcontext) -{ - groupcontext->child = groupcontext->etgc->children; - if (groupcontext->child_printable) - g_object_unref (groupcontext->child_printable); - groupcontext->child_printable = NULL; -} - -static gdouble -e_table_group_container_height (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantize, - ETGCPrintContext *groupcontext) -{ - gdouble height = 0; - gdouble child_height; - gdouble yd = max_height; - ETableGroupContainerChildNode *child_node; - GList *child; - EPrintable *child_printable; - - child_printable = groupcontext->child_printable; - child = groupcontext->child; - - if (child_printable) - g_object_ref (child_printable); - else { - if (!child) { - g_signal_stop_emission_by_name (ep, "height"); - return 0; - } else { - child_node = child->data; - child_printable = e_table_group_get_printable (child_node->child); - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - } - - if (yd != -1 && yd < TEXT_AREA_HEIGHT) - return 0; - - while (1) { - child_height = e_printable_height (child_printable, context, width - 36, yd - (yd == -1 ? 0 : TEXT_AREA_HEIGHT), quantize); - - height -= child_height + TEXT_AREA_HEIGHT; - - if (yd != -1) { - if (!e_printable_will_fit (child_printable, context, width - 36, yd - (yd == -1 ? 0 : TEXT_AREA_HEIGHT), quantize)) { - break; - } - - yd += child_height + TEXT_AREA_HEIGHT; - } - - child = child->next; - if (!child) { - break; - } - - child_node = child->data; - if (child_printable) - g_object_unref (child_printable); - child_printable = e_table_group_get_printable (child_node->child); - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - if (child_printable) - g_object_unref (child_printable); - g_signal_stop_emission_by_name (ep, "height"); - return height; -} - -static gboolean -e_table_group_container_will_fit (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantize, - ETGCPrintContext *groupcontext) -{ - gboolean will_fit = TRUE; - gdouble child_height; - gdouble yd = max_height; - ETableGroupContainerChildNode *child_node; - GList *child; - EPrintable *child_printable; - - child_printable = groupcontext->child_printable; - child = groupcontext->child; - - if (child_printable) - g_object_ref (child_printable); - else { - if (!child) { - g_signal_stop_emission_by_name (ep, "will_fit"); - return will_fit; - } else { - child_node = child->data; - child_printable = e_table_group_get_printable (child_node->child); - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - } - - if (yd != -1 && yd < TEXT_AREA_HEIGHT) - will_fit = FALSE; - else { - while (1) { - child_height = e_printable_height (child_printable, context, width - 36, yd - (yd == -1 ? 0 : TEXT_AREA_HEIGHT), quantize); - - if (yd != -1) { - if (!e_printable_will_fit (child_printable, context, width - 36, yd - (yd == -1 ? 0 : TEXT_AREA_HEIGHT), quantize)) { - will_fit = FALSE; - break; - } - - yd += child_height + TEXT_AREA_HEIGHT; - } - - child = child->next; - if (!child) { - break; - } - - child_node = child->data; - if (child_printable) - g_object_unref (child_printable); - child_printable = e_table_group_get_printable (child_node->child); - if (child_printable) - g_object_ref (child_printable); - e_printable_reset (child_printable); - } - } - - if (child_printable) - g_object_unref (child_printable); - - g_signal_stop_emission_by_name (ep, "will_fit"); - return will_fit; -} - -static void -e_table_group_container_printable_destroy (gpointer data, - GObject *where_object_was) - -{ - ETGCPrintContext *groupcontext = data; - - g_object_unref (groupcontext->etgc); - if (groupcontext->child_printable) - g_object_ref (groupcontext->child_printable); - g_free (groupcontext); -} - -static EPrintable * -etgc_get_printable (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - EPrintable *printable = e_printable_new (); - ETGCPrintContext *groupcontext; - - groupcontext = g_new (ETGCPrintContext, 1); - groupcontext->etgc = etgc; - g_object_ref (etgc); - groupcontext->child = etgc->children; - groupcontext->child_printable = NULL; - - g_signal_connect ( - printable, "print_page", - G_CALLBACK (e_table_group_container_print_page), - groupcontext); - g_signal_connect ( - printable, "data_left", - G_CALLBACK (e_table_group_container_data_left), - groupcontext); - g_signal_connect ( - printable, "reset", - G_CALLBACK (e_table_group_container_reset), - groupcontext); - g_signal_connect ( - printable, "height", - G_CALLBACK (e_table_group_container_height), - groupcontext); - g_signal_connect ( - printable, "will_fit", - G_CALLBACK (e_table_group_container_will_fit), - groupcontext); - g_object_weak_ref ( - G_OBJECT (printable), - e_table_group_container_printable_destroy, - groupcontext); - - return printable; -} diff --git a/widgets/table/e-table-group-container.h b/widgets/table/e-table-group-container.h deleted file mode 100644 index ac5f7c9033..0000000000 --- a/widgets/table/e-table-group-container.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_GROUP_CONTAINER_H_ -#define _E_TABLE_GROUP_CONTAINER_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-table-model.h> -#include <table/e-table-header.h> -#include <table/e-table-group.h> -#include <table/e-table-item.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_GROUP_CONTAINER \ - (e_table_group_container_get_type ()) -#define E_TABLE_GROUP_CONTAINER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_GROUP_CONTAINER, ETableGroupContainer)) -#define E_TABLE_GROUP_CONTAINER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_GROUP_CONTAINER, ETableGroupContainerClass)) -#define E_IS_TABLE_GROUP_CONTAINER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_GROUP_CONTAINER)) -#define E_IS_TABLE_GROUP_CONTAINER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_GROUP_CONTAINER)) -#define E_TABLE_GROUP_CONTAINER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_GROUP_CONTAINER, ETableGroupContainerClass)) - -G_BEGIN_DECLS - -typedef struct _ETableGroupContainer ETableGroupContainer; -typedef struct _ETableGroupContainerClass ETableGroupContainerClass; - -typedef struct _ETableGroupContainerChildNode ETableGroupContainerChildNode; - -struct _ETableGroupContainer { - ETableGroup group; - - /* - * The ETableCol used to group this set - */ - ETableCol *ecol; - gint ascending; - - /* - * List of ETableGroups we stack - */ - GList *children; - - /* - * The canvas rectangle that contains the children - */ - GnomeCanvasItem *rect; - - PangoFontDescription *font_desc; - - gdouble width, height, minimum_width; - - ETableSortInfo *sort_info; - gint n; - gint length_threshold; - - ESelectionModel *selection_model; - - guint alternating_row_colors : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint uniform_row_height : 1; - ECursorMode cursor_mode; - - /* - * State: the ETableGroup is open or closed - */ - guint open : 1; -}; - -struct _ETableGroupContainerClass { - ETableGroupClass parent_class; -}; - -struct _ETableGroupContainerChildNode { - ETableGroup *child; - gpointer key; - gchar *string; - GnomeCanvasItem *text; - GnomeCanvasItem *rect; - gint count; -}; - -GType e_table_group_container_get_type - (void) G_GNUC_CONST; -ETableGroup * e_table_group_container_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n); -void e_table_group_container_construct - (GnomeCanvasGroup *parent, - ETableGroupContainer *etgc, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n); - -G_END_DECLS - -#endif /* _E_TABLE_GROUP_CONTAINER_H_ */ diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c deleted file mode 100644 index 2da75bf006..0000000000 --- a/widgets/table/e-table-group-leaf.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas.h" - -#include "e-table-item.h" -#include "e-table-group-leaf.h" -#include "e-table-sorted.h" -#include "e-table-sorted-variable.h" - -/* workaround for avoiding APi breakage */ -#define etgl_get_type e_table_group_leaf_get_type -G_DEFINE_TYPE (ETableGroupLeaf, etgl, E_TYPE_TABLE_GROUP) - -enum { - PROP_0, - PROP_HEIGHT, - PROP_WIDTH, - PROP_MINIMUM_WIDTH, - PROP_FROZEN, - PROP_TABLE_ALTERNATING_ROW_COLORS, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - PROP_TABLE_VERTICAL_DRAW_GRID, - PROP_TABLE_DRAW_FOCUS, - PROP_CURSOR_MODE, - PROP_LENGTH_THRESHOLD, - PROP_SELECTION_MODEL, - PROP_UNIFORM_ROW_HEIGHT -}; - -static void -etgl_dispose (GObject *object) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); - - if (etgl->ets) { - g_object_unref (etgl->ets); - etgl->ets = NULL; - } - - if (etgl->item) { - if (etgl->etgl_cursor_change_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_cursor_change_id); - if (etgl->etgl_cursor_activated_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_cursor_activated_id); - if (etgl->etgl_double_click_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_double_click_id); - if (etgl->etgl_right_click_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_right_click_id); - if (etgl->etgl_click_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_click_id); - if (etgl->etgl_key_press_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_key_press_id); - if (etgl->etgl_start_drag_id != 0) - g_signal_handler_disconnect ( - etgl->item, - etgl->etgl_start_drag_id); - - etgl->etgl_cursor_change_id = 0; - etgl->etgl_cursor_activated_id = 0; - etgl->etgl_double_click_id = 0; - etgl->etgl_right_click_id = 0; - etgl->etgl_click_id = 0; - etgl->etgl_key_press_id = 0; - etgl->etgl_start_drag_id = 0; - - g_object_run_dispose (G_OBJECT (etgl->item)); - etgl->item = NULL; - } - - if (etgl->selection_model) { - g_object_unref (etgl->selection_model); - etgl->selection_model = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etgl_parent_class)->dispose (object); -} - -static void -e_table_group_leaf_construct (GnomeCanvasGroup *parent, - ETableGroupLeaf *etgl, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info) -{ - etgl->is_grouped = - (e_table_sort_info_grouping_get_count (sort_info) > 0); - - if (etgl->is_grouped) - etgl->ets = E_TABLE_SUBSET ( - e_table_sorted_variable_new ( - model, full_header, sort_info)); - else - etgl->ets = E_TABLE_SUBSET ( - e_table_sorted_new ( - model, full_header, sort_info)); - - e_table_group_construct ( - parent, E_TABLE_GROUP (etgl), full_header, header, model); -} - -/** - * e_table_group_leaf_new - * @parent: The %GnomeCanvasGroup to create a child of. - * @full_header: The full header of the %ETable. - * @header: The current header of the %ETable. - * @model: The %ETableModel of the %ETable. - * @sort_info: The %ETableSortInfo of the %ETable. - * - * %ETableGroupLeaf is an %ETableGroup which simply contains an - * %ETableItem. - * - * Returns: The new %ETableGroupLeaf. - */ -ETableGroup * -e_table_group_leaf_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info) -{ - ETableGroupLeaf *etgl; - - g_return_val_if_fail (parent != NULL, NULL); - - etgl = g_object_new (E_TYPE_TABLE_GROUP_LEAF, NULL); - - e_table_group_leaf_construct ( - parent, etgl, full_header, - header, model, sort_info); - - return E_TABLE_GROUP (etgl); -} - -static void -etgl_cursor_change (GObject *object, - gint row, - ETableGroupLeaf *etgl) -{ - if (row < E_TABLE_SUBSET (etgl->ets)->n_map) - e_table_group_cursor_change ( - E_TABLE_GROUP (etgl), - E_TABLE_SUBSET (etgl->ets)->map_table[row]); -} - -static void -etgl_cursor_activated (GObject *object, - gint view_row, - ETableGroupLeaf *etgl) -{ - if (view_row < E_TABLE_SUBSET (etgl->ets)->n_map) - e_table_group_cursor_activated ( - E_TABLE_GROUP (etgl), - E_TABLE_SUBSET (etgl->ets)->map_table[view_row]); -} - -static void -etgl_double_click (GObject *object, - gint model_row, - gint model_col, - GdkEvent *event, - ETableGroupLeaf *etgl) -{ - e_table_group_double_click ( - E_TABLE_GROUP (etgl), model_row, model_col, event); -} - -static gboolean -etgl_key_press (GObject *object, - gint row, - gint col, - GdkEvent *event, - ETableGroupLeaf *etgl) -{ - if (row < E_TABLE_SUBSET (etgl->ets)->n_map && row >= 0) - return e_table_group_key_press ( - E_TABLE_GROUP (etgl), - E_TABLE_SUBSET (etgl->ets)->map_table[row], - col, event); - else - return FALSE; -} - -static gboolean -etgl_start_drag (GObject *object, - gint model_row, - gint model_col, - GdkEvent *event, - ETableGroupLeaf *etgl) -{ - return e_table_group_start_drag ( - E_TABLE_GROUP (etgl), model_row, model_col, event); -} - -static gboolean -etgl_right_click (GObject *object, - gint view_row, - gint model_col, - GdkEvent *event, - ETableGroupLeaf *etgl) -{ - if (view_row < E_TABLE_SUBSET (etgl->ets)->n_map) - return e_table_group_right_click ( - E_TABLE_GROUP (etgl), - E_TABLE_SUBSET (etgl->ets)->map_table[view_row], - model_col, event); - else - return FALSE; -} - -static gboolean -etgl_click (GObject *object, - gint row, - gint col, - GdkEvent *event, - ETableGroupLeaf *etgl) -{ - if (row < E_TABLE_SUBSET (etgl->ets)->n_map) - return e_table_group_click ( - E_TABLE_GROUP (etgl), - E_TABLE_SUBSET (etgl->ets)->map_table[row], - col, event); - else - return FALSE; -} - -static void -etgl_reflow (GnomeCanvasItem *item, - gint flags) -{ - ETableGroupLeaf *leaf = E_TABLE_GROUP_LEAF (item); - - g_object_get (leaf->item, "height", &leaf->height, NULL); - g_object_get (leaf->item, "width", &leaf->width, NULL); - - e_canvas_item_request_parent_reflow (item); -} - -static void -etgl_realize (GnomeCanvasItem *item) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (item); - - if (GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize) - GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item); - - etgl->item = E_TABLE_ITEM (gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etgl), - e_table_item_get_type (), - "ETableHeader", E_TABLE_GROUP (etgl)->header, - "ETableModel", etgl->ets, - "alternating_row_colors", etgl->alternating_row_colors, - "horizontal_draw_grid", etgl->horizontal_draw_grid, - "vertical_draw_grid", etgl->vertical_draw_grid, - "drawfocus", etgl->draw_focus, - "cursor_mode", etgl->cursor_mode, - "minimum_width", etgl->minimum_width, - "length_threshold", etgl->length_threshold, - "selection_model", etgl->selection_model, - "uniform_row_height", etgl->uniform_row_height, - NULL)); - - etgl->etgl_cursor_change_id = g_signal_connect ( - etgl->item, "cursor_change", - G_CALLBACK (etgl_cursor_change), etgl); - - etgl->etgl_cursor_activated_id = g_signal_connect ( - etgl->item, "cursor_activated", - G_CALLBACK (etgl_cursor_activated), etgl); - - etgl->etgl_double_click_id = g_signal_connect ( - etgl->item, "double_click", - G_CALLBACK (etgl_double_click), etgl); - - etgl->etgl_right_click_id = g_signal_connect ( - etgl->item, "right_click", - G_CALLBACK (etgl_right_click), etgl); - - etgl->etgl_click_id = g_signal_connect ( - etgl->item, "click", - G_CALLBACK (etgl_click), etgl); - - etgl->etgl_key_press_id = g_signal_connect ( - etgl->item, "key_press", - G_CALLBACK (etgl_key_press), etgl); - - etgl->etgl_start_drag_id = g_signal_connect ( - etgl->item, "start_drag", - G_CALLBACK (etgl_start_drag), etgl); - - e_canvas_item_request_reflow (item); -} - -static void -etgl_add (ETableGroup *etg, - gint row) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - e_table_subset_variable_add ( - E_TABLE_SUBSET_VARIABLE (etgl->ets), row); - } -} - -static void -etgl_add_array (ETableGroup *etg, - const gint *array, - gint count) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - e_table_subset_variable_add_array ( - E_TABLE_SUBSET_VARIABLE (etgl->ets), array, count); - } -} - -static void -etgl_add_all (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - e_table_subset_variable_add_all ( - E_TABLE_SUBSET_VARIABLE (etgl->ets)); - } -} - -static gboolean -etgl_remove (ETableGroup *etg, - gint row) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - return e_table_subset_variable_remove ( - E_TABLE_SUBSET_VARIABLE (etgl->ets), row); - } - return FALSE; -} - -static void -etgl_increment (ETableGroup *etg, - gint position, - gint amount) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - e_table_subset_variable_increment ( - E_TABLE_SUBSET_VARIABLE (etgl->ets), - position, amount); - } -} - -static void -etgl_decrement (ETableGroup *etg, - gint position, - gint amount) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (E_IS_TABLE_SUBSET_VARIABLE (etgl->ets)) { - e_table_subset_variable_decrement ( - E_TABLE_SUBSET_VARIABLE (etgl->ets), - position, amount); - } -} - -static gint -etgl_row_count (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - return e_table_model_row_count (E_TABLE_MODEL (etgl->ets)); -} - -static void -etgl_set_focus (ETableGroup *etg, - EFocus direction, - gint view_col) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (direction == E_FOCUS_END) { - e_table_item_set_cursor ( - etgl->item, view_col, - e_table_model_row_count (E_TABLE_MODEL (etgl->ets)) - 1); - } else { - e_table_item_set_cursor (etgl->item, view_col, 0); - } -} - -static gint -etgl_get_focus_column (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - return e_table_item_get_focused_column (etgl->item); -} - -static EPrintable * -etgl_get_printable (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - return e_table_item_get_printable (etgl->item); -} - -static void -etgl_compute_location (ETableGroup *etg, - gint *x, - gint *y, - gint *row, - gint *col) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - e_table_item_compute_location (etgl->item, x, y, row, col); -} - -static void -etgl_get_mouse_over (ETableGroup *etg, - gint *row, - gint *col) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - if (etgl->item && etgl->item->motion_row > -1 && etgl->item->motion_col > -1) { - if (row) - *row = etgl->item->motion_row; - if (col) - *col = etgl->item->motion_col; - } -} - -static void -etgl_get_cell_geometry (ETableGroup *etg, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - - e_table_item_get_cell_geometry (etgl->item, row, col, x, y, width, height); -} - -static void -etgl_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); - - switch (property_id) { - case PROP_FROZEN: - etg->frozen = g_value_get_boolean (value); - break; - case PROP_MINIMUM_WIDTH: - case PROP_WIDTH: - etgl->minimum_width = g_value_get_double (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "minimum_width", etgl->minimum_width, - NULL); - } - break; - case PROP_LENGTH_THRESHOLD: - etgl->length_threshold = g_value_get_int (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "length_threshold", etgl->length_threshold, - NULL); - } - break; - case PROP_SELECTION_MODEL: - if (etgl->selection_model) - g_object_unref (etgl->selection_model); - etgl->selection_model = E_SELECTION_MODEL (g_value_get_object (value)); - if (etgl->selection_model) { - g_object_ref (etgl->selection_model); - } - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "selection_model", etgl->selection_model, - NULL); - } - break; - - case PROP_UNIFORM_ROW_HEIGHT: - etgl->uniform_row_height = g_value_get_boolean (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "uniform_row_height", etgl->uniform_row_height, - NULL); - } - break; - - case PROP_TABLE_ALTERNATING_ROW_COLORS: - etgl->alternating_row_colors = g_value_get_boolean (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "alternating_row_colors", etgl->alternating_row_colors, - NULL); - } - break; - - case PROP_TABLE_HORIZONTAL_DRAW_GRID: - etgl->horizontal_draw_grid = g_value_get_boolean (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "horizontal_draw_grid", etgl->horizontal_draw_grid, - NULL); - } - break; - - case PROP_TABLE_VERTICAL_DRAW_GRID: - etgl->vertical_draw_grid = g_value_get_boolean (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "vertical_draw_grid", etgl->vertical_draw_grid, - NULL); - } - break; - - case PROP_TABLE_DRAW_FOCUS: - etgl->draw_focus = g_value_get_boolean (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "drawfocus", etgl->draw_focus, - NULL); - } - break; - - case PROP_CURSOR_MODE: - etgl->cursor_mode = g_value_get_int (value); - if (etgl->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etgl->item), - "cursor_mode", etgl->cursor_mode, - NULL); - } - break; - default: - break; - } -} - -static void -etgl_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); - - switch (property_id) { - case PROP_FROZEN: - g_value_set_boolean (value, etg->frozen); - break; - case PROP_HEIGHT: - g_value_set_double (value, etgl->height); - break; - case PROP_WIDTH: - g_value_set_double (value, etgl->width); - break; - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, etgl->minimum_width); - break; - case PROP_UNIFORM_ROW_HEIGHT: - g_value_set_boolean (value, etgl->uniform_row_height); - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -etgl_class_init (ETableGroupLeafClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etgl_dispose; - object_class->set_property = etgl_set_property; - object_class->get_property = etgl_get_property; - - item_class->realize = etgl_realize; - - e_group_class->add = etgl_add; - e_group_class->add_array = etgl_add_array; - e_group_class->add_all = etgl_add_all; - e_group_class->remove = etgl_remove; - e_group_class->increment = etgl_increment; - e_group_class->decrement = etgl_decrement; - e_group_class->row_count = etgl_row_count; - e_group_class->set_focus = etgl_set_focus; - e_group_class->get_focus_column = etgl_get_focus_column; - e_group_class->get_printable = etgl_get_printable; - e_group_class->compute_location = etgl_compute_location; - e_group_class->get_mouse_over = etgl_get_mouse_over; - e_group_class->get_cell_geometry = etgl_get_cell_geometry; - - g_object_class_install_property ( - object_class, - PROP_TABLE_ALTERNATING_ROW_COLORS, - g_param_spec_boolean ( - "alternating_row_colors", - "Alternating Row Colors", - "Alternating Row Colors", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - g_param_spec_boolean ( - "horizontal_draw_grid", - "Horizontal Draw Grid", - "Horizontal Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_VERTICAL_DRAW_GRID, - g_param_spec_boolean ( - "vertical_draw_grid", - "Vertical Draw Grid", - "Vertical Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_DRAW_FOCUS, - g_param_spec_boolean ( - "drawfocus", - "Draw focus", - "Draw focus", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_MODE, - g_param_spec_int ( - "cursor_mode", - "Cursor mode", - "Cursor mode", - E_CURSOR_LINE, - E_CURSOR_SPREADSHEET, - E_CURSOR_LINE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_LENGTH_THRESHOLD, - g_param_spec_int ( - "length_threshold", - "Length Threshold", - "Length Threshold", - -1, G_MAXINT, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTION_MODEL, - g_param_spec_object ( - "selection_model", - "Selection model", - "Selection model", - E_TYPE_SELECTION_MODEL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_WIDTH, - g_param_spec_double ( - "minimum_width", - "Minimum width", - "Minimum Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FROZEN, - g_param_spec_boolean ( - "frozen", - "Frozen", - "Frozen", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UNIFORM_ROW_HEIGHT, - g_param_spec_boolean ( - "uniform_row_height", - "Uniform row height", - "Uniform row height", - FALSE, - G_PARAM_READWRITE)); -} - -static void -etgl_init (ETableGroupLeaf *etgl) -{ - etgl->width = 1; - etgl->height = 1; - etgl->minimum_width = 0; - - etgl->ets = NULL; - etgl->item = NULL; - - etgl->etgl_cursor_change_id = 0; - etgl->etgl_cursor_activated_id = 0; - etgl->etgl_double_click_id = 0; - etgl->etgl_right_click_id = 0; - etgl->etgl_click_id = 0; - etgl->etgl_key_press_id = 0; - etgl->etgl_start_drag_id = 0; - - etgl->alternating_row_colors = 1; - etgl->horizontal_draw_grid = 1; - etgl->vertical_draw_grid = 1; - etgl->draw_focus = 1; - etgl->cursor_mode = E_CURSOR_SIMPLE; - etgl->length_threshold = -1; - - etgl->selection_model = NULL; - etgl->uniform_row_height = FALSE; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etgl), etgl_reflow); -} - diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h deleted file mode 100644 index beed62e7d1..0000000000 --- a/widgets/table/e-table-group-leaf.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_GROUP_LEAF_H_ -#define _E_TABLE_GROUP_LEAF_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-table-group.h> -#include <table/e-table-subset.h> -#include <table/e-table-item.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_GROUP_LEAF \ - (e_table_group_leaf_get_type ()) -#define E_TABLE_GROUP_LEAF(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_GROUP_LEAF, ETableGroupLeaf)) -#define E_TABLE_GROUP_LEAF_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_GROUP_LEAF, ETableGroupLeafClass)) -#define E_IS_TABLE_GROUP_LEAF(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_GROUP_LEAF)) -#define E_IS_TABLE_GROUP_LEAF_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_GROUP_LEAF)) -#define E_TABLE_GROUP_LEAF_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_GROUP_LEAF, ETableGroupLeafClass)) - -G_BEGIN_DECLS - -typedef struct _ETableGroupLeaf ETableGroupLeaf; -typedef struct _ETableGroupLeafClass ETableGroupLeafClass; - -struct _ETableGroupLeaf { - ETableGroup group; - - /* - * Item. - */ - ETableItem *item; - - gdouble height; - gdouble width; - gdouble minimum_width; - - gint length_threshold; - - ETableSubset *ets; - guint is_grouped : 1; - - guint alternating_row_colors : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint uniform_row_height : 1; - ECursorMode cursor_mode; - - gint etgl_cursor_change_id; - gint etgl_cursor_activated_id; - gint etgl_double_click_id; - gint etgl_right_click_id; - gint etgl_click_id; - gint etgl_key_press_id; - gint etgl_start_drag_id; - - ESelectionModel *selection_model; -}; - -struct _ETableGroupLeafClass { - ETableGroupClass parent_class; -}; - -GType e_table_group_leaf_get_type (void) G_GNUC_CONST; -ETableGroup * e_table_group_leaf_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info); - -G_END_DECLS - -#endif /* _E_TABLE_GROUP_LEAF_H_ */ - diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c deleted file mode 100644 index 032ec7dd88..0000000000 --- a/widgets/table/e-table-group.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "e-util/e-util.h" - -#include "e-table-group.h" -#include "e-table-group-container.h" -#include "e-table-group-leaf.h" -#include "e-table-item.h" - -/* workaround for avoiding API breakage*/ -#define etg_get_type e_table_group_get_type -G_DEFINE_TYPE (ETableGroup, etg, GNOME_TYPE_CANVAS_GROUP) - -#define ETG_CLASS(e) (E_TABLE_GROUP_CLASS(G_OBJECT_GET_CLASS(e))) - -enum { - CURSOR_CHANGE, - CURSOR_ACTIVATED, - DOUBLE_CLICK, - RIGHT_CLICK, - CLICK, - KEY_PRESS, - START_DRAG, - LAST_SIGNAL -}; - -static guint etg_signals[LAST_SIGNAL] = { 0, }; - -static gboolean etg_get_focus (ETableGroup *etg); - -static void -etg_dispose (GObject *object) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - - if (etg->header) { - g_object_unref (etg->header); - etg->header = NULL; - } - - if (etg->full_header) { - g_object_unref (etg->full_header); - etg->full_header = NULL; - } - - if (etg->model) { - g_object_unref (etg->model); - etg->model = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etg_parent_class)->dispose (object); -} - -/** - * e_table_group_new - * @parent: The %GnomeCanvasGroup to create a child of. - * @full_header: The full header of the %ETable. - * @header: The current header of the %ETable. - * @model: The %ETableModel of the %ETable. - * @sort_info: The %ETableSortInfo of the %ETable. - * @n: The grouping information object to group by. - * - * %ETableGroup is a collection of rows of an %ETable. It's a - * %GnomeCanvasItem. There are two different forms. If n < the - * number of groupings in the given %ETableSortInfo, then the - * %ETableGroup will need to contain other %ETableGroups, thus it - * creates an %ETableGroupContainer. Otherwise, it will just contain - * an %ETableItem, and thus it creates an %ETableGroupLeaf. - * - * Returns: The new %ETableGroup. - */ -ETableGroup * -e_table_group_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n) -{ - g_return_val_if_fail (model != NULL, NULL); - - if (n < e_table_sort_info_grouping_get_count (sort_info)) { - return e_table_group_container_new ( - parent, full_header, header, model, sort_info, n); - } else { - return e_table_group_leaf_new ( - parent, full_header, header, model, sort_info); - } -} - -/** - * e_table_group_construct - * @parent: The %GnomeCanvasGroup to create a child of. - * @etg: The %ETableGroup to construct. - * @full_header: The full header of the %ETable. - * @header: The current header of the %ETable. - * @model: The %ETableModel of the %ETable. - * - * This routine does the base construction of the %ETableGroup. - */ -void -e_table_group_construct (GnomeCanvasGroup *parent, - ETableGroup *etg, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model) -{ - etg->full_header = full_header; - g_object_ref (etg->full_header); - etg->header = header; - g_object_ref (etg->header); - etg->model = model; - g_object_ref (etg->model); - g_object_set (etg, "parent", parent, NULL); -} - -/** - * e_table_group_add - * @etg: The %ETableGroup to add a row to - * @row: The row to add. - * - * This routine adds the given row from the %ETableModel to this set - * of rows. - */ -void -e_table_group_add (ETableGroup *etg, - gint row) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->add != NULL); - ETG_CLASS (etg)->add (etg, row); -} - -/** - * e_table_group_add_array - * @etg: The %ETableGroup to add to - * @array: The array to add. - * @count: The number of times to add - * - * This routine adds all the rows in the array to this set of rows. - * It assumes that the array is already sorted properly. - */ -void -e_table_group_add_array (ETableGroup *etg, - const gint *array, - gint count) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->add_array != NULL); - ETG_CLASS (etg)->add_array (etg, array, count); -} - -/** - * e_table_group_add_all - * @etg: The %ETableGroup to add to - * - * This routine adds all the rows from the %ETableModel to this set - * of rows. - */ -void -e_table_group_add_all (ETableGroup *etg) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->add_all != NULL); - ETG_CLASS (etg)->add_all (etg); -} - -/** - * e_table_group_remove - * @etg: The %ETableGroup to remove a row from - * @row: The row to remove. - * - * This routine removes the given row from the %ETableModel from this - * set of rows. - * - * Returns: TRUE if the row was deleted and FALSE if the row was not - * found. - */ -gboolean -e_table_group_remove (ETableGroup *etg, - gint row) -{ - g_return_val_if_fail (etg != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE); - - g_return_val_if_fail (ETG_CLASS (etg)->remove != NULL, FALSE); - return ETG_CLASS (etg)->remove (etg, row); -} - -/** - * e_table_group_increment - * @etg: The %ETableGroup to increment - * @position: The position to increment from - * @amount: The amount to increment. - * - * This routine adds amount to all rows greater than or equal to - * position. This is to handle when a row gets inserted into the - * model. - */ -void -e_table_group_increment (ETableGroup *etg, - gint position, - gint amount) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->increment != NULL); - ETG_CLASS (etg)->increment (etg, position, amount); -} - -/** - * e_table_group_increment - * @etg: The %ETableGroup to decrement - * @position: The position to decrement from - * @amount: The amount to decrement - * - * This routine removes amount from all rows greater than or equal to - * position. This is to handle when a row gets deleted from the - * model. - */ -void -e_table_group_decrement (ETableGroup *etg, - gint position, - gint amount) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->decrement != NULL); - ETG_CLASS (etg)->decrement (etg, position, amount); -} - -/** - * e_table_group_increment - * @etg: The %ETableGroup to count - * - * This routine calculates the number of rows shown in this group. - * - * Returns: The number of rows. - */ -gint -e_table_group_row_count (ETableGroup *etg) -{ - g_return_val_if_fail (etg != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), -1); - - g_return_val_if_fail (ETG_CLASS (etg)->row_count != NULL, -1); - return ETG_CLASS (etg)->row_count (etg); -} - -/** - * e_table_group_set_focus - * @etg: The %ETableGroup to set - * @direction: The direction the focus is coming from. - * @view_col: The column to set the focus in. - * - * Sets the focus to this widget. Places the focus in the view column - * coming from direction direction. - */ -void -e_table_group_set_focus (ETableGroup *etg, - EFocus direction, - gint view_col) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->set_focus != NULL); - ETG_CLASS (etg)->set_focus (etg, direction, view_col); -} - -/** - * e_table_group_get_focus - * @etg: The %ETableGroup to check - * - * Calculates if this group has the focus. - * - * Returns: TRUE if this group has the focus. - */ -gboolean -e_table_group_get_focus (ETableGroup *etg) -{ - g_return_val_if_fail (etg != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE); - - g_return_val_if_fail (ETG_CLASS (etg)->get_focus != NULL, FALSE); - return ETG_CLASS (etg)->get_focus (etg); -} - -/** - * e_table_group_get_focus_column - * @etg: The %ETableGroup to check - * - * Calculates which column in this group has the focus. - * - * Returns: The column index (view column). - */ -gint -e_table_group_get_focus_column (ETableGroup *etg) -{ - g_return_val_if_fail (etg != NULL, -1); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), -1); - - g_return_val_if_fail (ETG_CLASS (etg)->get_focus_column != NULL, -1); - return ETG_CLASS (etg)->get_focus_column (etg); -} - -/** - * e_table_group_get_printable - * @etg: %ETableGroup which will be printed - * - * This routine creates and returns an %EPrintable that can be used to - * print the given %ETableGroup. - * - * Returns: The %EPrintable. - */ -EPrintable * -e_table_group_get_printable (ETableGroup *etg) -{ - g_return_val_if_fail (etg != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL); - - g_return_val_if_fail (ETG_CLASS (etg)->get_printable != NULL, NULL); - return ETG_CLASS (etg)->get_printable (etg); -} - -/** - * e_table_group_compute_location - * @eti: %ETableGroup to look in. - * @x: A pointer to the x location to find in the %ETableGroup. - * @y: A pointer to the y location to find in the %ETableGroup. - * @row: A pointer to the location to store the found row in. - * @col: A pointer to the location to store the found col in. - * - * This routine locates the pixel location (*x, *y) in the - * %ETableGroup. If that location is in the %ETableGroup, *row and - * *col are set to the view row and column where it was found. If - * that location is not in the %ETableGroup, the height of the - * %ETableGroup is removed from the value y points to. - */ -void -e_table_group_compute_location (ETableGroup *etg, - gint *x, - gint *y, - gint *row, - gint *col) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->compute_location != NULL); - ETG_CLASS (etg)->compute_location (etg, x, y, row, col); -} - -void -e_table_group_get_mouse_over (ETableGroup *etg, - gint *row, - gint *col) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->get_mouse_over != NULL); - ETG_CLASS (etg)->get_mouse_over (etg, row, col); -} - -/** - * e_table_group_get_position - * @eti: %ETableGroup to look in. - * @x: A pointer to the location to store the found x location in. - * @y: A pointer to the location to store the found y location in. - * @row: A pointer to the row number to find. - * @col: A pointer to the col number to find. - * - * This routine finds the view cell (row, col) in the #ETableGroup. - * If that location is in the #ETableGroup *@x and *@y are set to the - * upper left hand corner of the cell found. If that location is not - * in the #ETableGroup, the number of rows in the #ETableGroup is - * removed from the value row points to. - */ -void -e_table_group_get_cell_geometry (ETableGroup *etg, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - g_return_if_fail (ETG_CLASS (etg)->get_cell_geometry != NULL); - ETG_CLASS (etg)->get_cell_geometry (etg, row, col, x, y, width, height); -} - -/** - * e_table_group_cursor_change - * @eti: %ETableGroup to emit the signal on - * @row: The new cursor row (model row) - * - * This routine emits the "cursor_change" signal. - */ -void -e_table_group_cursor_change (ETableGroup *e_table_group, - gint row) -{ - g_return_if_fail (e_table_group != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (e_table_group)); - - g_signal_emit ( - e_table_group, - etg_signals[CURSOR_CHANGE], 0, - row); -} - -/** - * e_table_group_cursor_activated - * @eti: %ETableGroup to emit the signal on - * @row: The cursor row (model row) - * - * This routine emits the "cursor_activated" signal. - */ -void -e_table_group_cursor_activated (ETableGroup *e_table_group, - gint row) -{ - g_return_if_fail (e_table_group != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (e_table_group)); - - g_signal_emit ( - e_table_group, - etg_signals[CURSOR_ACTIVATED], 0, - row); -} - -/** - * e_table_group_double_click - * @eti: %ETableGroup to emit the signal on - * @row: The row clicked on (model row) - * @col: The col clicked on (model col) - * @event: The event that caused this signal - * - * This routine emits the "double_click" signal. - */ -void -e_table_group_double_click (ETableGroup *e_table_group, - gint row, - gint col, - GdkEvent *event) -{ - g_return_if_fail (e_table_group != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (e_table_group)); - - g_signal_emit ( - e_table_group, - etg_signals[DOUBLE_CLICK], 0, - row, col, event); -} - -/** - * e_table_group_right_click - * @eti: %ETableGroup to emit the signal on - * @row: The row clicked on (model row) - * @col: The col clicked on (model col) - * @event: The event that caused this signal - * - * This routine emits the "right_click" signal. - */ -gboolean -e_table_group_right_click (ETableGroup *e_table_group, - gint row, - gint col, - GdkEvent *event) -{ - gboolean return_val = FALSE; - - g_return_val_if_fail (e_table_group != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE); - - g_signal_emit ( - e_table_group, - etg_signals[RIGHT_CLICK], 0, - row, col, event, &return_val); - - return return_val; -} - -/** - * e_table_group_click - * @eti: %ETableGroup to emit the signal on - * @row: The row clicked on (model row) - * @col: The col clicked on (model col) - * @event: The event that caused this signal - * - * This routine emits the "click" signal. - */ -gboolean -e_table_group_click (ETableGroup *e_table_group, - gint row, - gint col, - GdkEvent *event) -{ - gboolean return_val = FALSE; - - g_return_val_if_fail (e_table_group != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE); - - g_signal_emit ( - e_table_group, - etg_signals[CLICK], 0, - row, col, event, &return_val); - - return return_val; -} - -/** - * e_table_group_key_press - * @eti: %ETableGroup to emit the signal on - * @row: The cursor row (model row) - * @col: The cursor col (model col) - * @event: The event that caused this signal - * - * This routine emits the "key_press" signal. - */ -gboolean -e_table_group_key_press (ETableGroup *e_table_group, - gint row, - gint col, - GdkEvent *event) -{ - gboolean return_val = FALSE; - - g_return_val_if_fail (e_table_group != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE); - - g_signal_emit ( - e_table_group, - etg_signals[KEY_PRESS], 0, - row, col, event, &return_val); - - return return_val; -} - -/** - * e_table_group_start_drag - * @eti: %ETableGroup to emit the signal on - * @row: The cursor row (model row) - * @col: The cursor col (model col) - * @event: The event that caused this signal - * - * This routine emits the "start_drag" signal. - */ -gboolean -e_table_group_start_drag (ETableGroup *e_table_group, - gint row, - gint col, - GdkEvent *event) -{ - gboolean return_val = FALSE; - - g_return_val_if_fail (e_table_group != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE); - - g_signal_emit ( - e_table_group, - etg_signals[START_DRAG], 0, - row, col, event, &return_val); - - return return_val; -} - -/** - * e_table_group_get_header - * @eti: %ETableGroup to check - * - * This routine returns the %ETableGroup's header. - * - * Returns: The %ETableHeader. - */ -ETableHeader * -e_table_group_get_header (ETableGroup *etg) -{ - g_return_val_if_fail (etg != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL); - - return etg->header; -} - -static gint -etg_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - ETableGroup *etg = E_TABLE_GROUP (item); - gboolean return_val = TRUE; - - switch (event->type) { - - case GDK_FOCUS_CHANGE: - etg->has_focus = event->focus_change.in; - return_val = FALSE; - break; - - default: - return_val = FALSE; - } - if (return_val == FALSE) { - if (GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->event) - return GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->event (item, event); - } - return return_val; - -} - -static gboolean -etg_get_focus (ETableGroup *etg) -{ - return etg->has_focus; -} - -static void -etg_class_init (ETableGroupClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etg_dispose; - - item_class->event = etg_event; - - class->cursor_change = NULL; - class->cursor_activated = NULL; - class->double_click = NULL; - class->right_click = NULL; - class->click = NULL; - class->key_press = NULL; - class->start_drag = NULL; - - class->add = NULL; - class->add_array = NULL; - class->add_all = NULL; - class->remove = NULL; - class->row_count = NULL; - class->increment = NULL; - class->decrement = NULL; - class->set_focus = NULL; - class->get_focus = etg_get_focus; - class->get_printable = NULL; - class->compute_location = NULL; - class->get_mouse_over = NULL; - class->get_cell_geometry = NULL; - - etg_signals[CURSOR_CHANGE] = g_signal_new ( - "cursor_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, cursor_change), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - etg_signals[CURSOR_ACTIVATED] = g_signal_new ( - "cursor_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, cursor_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - etg_signals[DOUBLE_CLICK] = g_signal_new ( - "double_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, double_click), - NULL, NULL, - e_marshal_NONE__INT_INT_BOXED, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - etg_signals[RIGHT_CLICK] = g_signal_new ( - "right_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, right_click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - etg_signals[CLICK] = g_signal_new ( - "click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - etg_signals[KEY_PRESS] = g_signal_new ( - "key_press", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, key_press), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - etg_signals[START_DRAG] = g_signal_new ( - "start_drag", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableGroupClass, start_drag), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); -} - -static void -etg_init (ETableGroup *etg) -{ - /* nothing to do */ -} diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h deleted file mode 100644 index 5731dfdeaf..0000000000 --- a/widgets/table/e-table-group.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_GROUP_H_ -#define _E_TABLE_GROUP_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-table-model.h> -#include <table/e-table-header.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-defines.h> -#include <e-util/e-util.h> -#include <misc/e-printable.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_GROUP \ - (e_table_group_get_type ()) -#define E_TABLE_GROUP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_GROUP, ETableGroup)) -#define E_TABLE_GROUP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_GROUP, ETableGroupClass)) -#define E_IS_TABLE_GROUP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_GROUP)) -#define E_IS_TABLE_GROUP_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_GROUP)) -#define E_TABLE_GROUP_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_GROUP, ETableGroupClass)) - -G_BEGIN_DECLS - -typedef struct _ETableGroup ETableGroup; -typedef struct _ETableGroupClass ETableGroupClass; - -struct _ETableGroup { - GnomeCanvasGroup group; - - /* - * The full header. - */ - ETableHeader *full_header; - ETableHeader *header; - - /* - * The model we pull data from. - */ - ETableModel *model; - - /* - * Whether we should add indentation and open/close markers, - * or if we just act as containers of subtables. - */ - guint transparent : 1; - - guint has_focus : 1; - - guint frozen : 1; -}; - -struct _ETableGroupClass { - GnomeCanvasGroupClass parent_class; - - /* Signals */ - void (*cursor_change) (ETableGroup *etg, - gint row); - void (*cursor_activated) (ETableGroup *etg, - gint row); - void (*double_click) (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - gboolean (*right_click) (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - gboolean (*click) (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - gboolean (*key_press) (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - gint (*start_drag) (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - - /* Virtual functions. */ - void (*add) (ETableGroup *etg, - gint row); - void (*add_array) (ETableGroup *etg, - const gint *array, - gint count); - void (*add_all) (ETableGroup *etg); - gboolean (*remove) (ETableGroup *etg, - gint row); - gint (*row_count) (ETableGroup *etg); - void (*increment) (ETableGroup *etg, - gint position, - gint amount); - void (*decrement) (ETableGroup *etg, - gint position, - gint amount); - void (*set_focus) (ETableGroup *etg, - EFocus direction, - gint view_col); - gboolean (*get_focus) (ETableGroup *etg); - gint (*get_focus_column) (ETableGroup *etg); - EPrintable * (*get_printable) (ETableGroup *etg); - void (*compute_location) (ETableGroup *etg, - gint *x, - gint *y, - gint *row, - gint *col); - void (*get_mouse_over) (ETableGroup *etg, - gint *row, - gint *col); - void (*get_cell_geometry) (ETableGroup *etg, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height); -}; - -GType e_table_group_get_type (void) G_GNUC_CONST; -ETableGroup * e_table_group_new (GnomeCanvasGroup *parent, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info, - gint n); -void e_table_group_construct (GnomeCanvasGroup *parent, - ETableGroup *etg, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model); - -/* Virtual functions */ -void e_table_group_add (ETableGroup *etg, - gint row); -void e_table_group_add_array (ETableGroup *etg, - const gint *array, - gint count); -void e_table_group_add_all (ETableGroup *etg); -gboolean e_table_group_remove (ETableGroup *etg, - gint row); -void e_table_group_increment (ETableGroup *etg, - gint position, - gint amount); -void e_table_group_decrement (ETableGroup *etg, - gint position, - gint amount); -gint e_table_group_row_count (ETableGroup *etg); -void e_table_group_set_focus (ETableGroup *etg, - EFocus direction, - gint view_col); -gboolean e_table_group_get_focus (ETableGroup *etg); -gint e_table_group_get_focus_column (ETableGroup *etg); -ETableHeader * e_table_group_get_header (ETableGroup *etg); -EPrintable * e_table_group_get_printable (ETableGroup *etg); -void e_table_group_compute_location (ETableGroup *etg, - gint *x, - gint *y, - gint *row, - gint *col); -void e_table_group_get_mouse_over (ETableGroup *etg, - gint *row, - gint *col); -void e_table_group_get_cell_geometry (ETableGroup *etg, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height); - -/* For emitting the signals */ -void e_table_group_cursor_change (ETableGroup *etg, - gint row); -void e_table_group_cursor_activated (ETableGroup *etg, - gint row); -void e_table_group_double_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); -gboolean e_table_group_right_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); -gboolean e_table_group_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); -gboolean e_table_group_key_press (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); -gint e_table_group_start_drag (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event); - -typedef void (*ETableGroupLeafFn) (gpointer e_table_item, gpointer closure); -void e_table_group_apply_to_leafs (ETableGroup *etg, - ETableGroupLeafFn fn, - gpointer closure); - -G_END_DECLS - -#endif /* _E_TABLE_GROUP_H_ */ diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c deleted file mode 100644 index 44d3979e1c..0000000000 --- a/widgets/table/e-table-header-item.c +++ /dev/null @@ -1,2227 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@gnu.org> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk/gdkkeysyms.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" -#include "misc/e-canvas.h" - -#include "e-popup-menu.h" -#include "e-table.h" -#include "e-table-col-dnd.h" -#include "e-table-config.h" -#include "e-table-defines.h" -#include "e-table-field-chooser-dialog.h" -#include "e-table-header.h" -#include "e-table-header-utils.h" - -#include "e-table-header-item.h" - -#include "arrow-up.xpm" -#include "arrow-down.xpm" - -enum { - BUTTON_PRESSED, - LAST_SIGNAL -}; - -static guint ethi_signals[LAST_SIGNAL] = { 0, }; - -#define ARROW_DOWN_HEIGHT 16 -#define ARROW_PTR 7 - -/* Defines the tolerance for proximity of the column division to the cursor position */ -#define TOLERANCE 4 - -#define ETHI_RESIZING(x) ((x)->resize_col != -1) - -#define ethi_get_type e_table_header_item_get_type -G_DEFINE_TYPE (ETableHeaderItem, ethi, GNOME_TYPE_CANVAS_ITEM) - -#define d(x) - -static void ethi_drop_table_header (ETableHeaderItem *ethi); - -/* - * They display the arrows for the drop location. - */ - -static GtkWidget *arrow_up, *arrow_down; - -enum { - PROP_0, - PROP_TABLE_HEADER, - PROP_FULL_HEADER, - PROP_DND_CODE, - PROP_TABLE_FONT_DESC, - PROP_SORT_INFO, - PROP_TABLE, - PROP_TREE -}; - -enum { - ET_SCROLL_UP = 1 << 0, - ET_SCROLL_DOWN = 1 << 1, - ET_SCROLL_LEFT = 1 << 2, - ET_SCROLL_RIGHT = 1 << 3 -}; - -static void scroll_off (ETableHeaderItem *ethi); -static void scroll_on (ETableHeaderItem *ethi, guint scroll_direction); - -static void -ethi_dispose (GObject *object) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (object); - - ethi_drop_table_header (ethi); - - scroll_off (ethi); - - if (ethi->resize_cursor) { - g_object_unref (ethi->resize_cursor); - ethi->resize_cursor = NULL; - } - - if (ethi->dnd_code) { - g_free (ethi->dnd_code); - ethi->dnd_code = NULL; - } - - if (ethi->sort_info) { - if (ethi->sort_info_changed_id) - g_signal_handler_disconnect ( - ethi->sort_info, ethi->sort_info_changed_id); - if (ethi->group_info_changed_id) - g_signal_handler_disconnect ( - ethi->sort_info, ethi->group_info_changed_id); - g_object_unref (ethi->sort_info); - ethi->sort_info = NULL; - } - - if (ethi->full_header) - g_object_unref (ethi->full_header); - ethi->full_header = NULL; - - if (ethi->etfcd.widget) - g_object_remove_weak_pointer ( - G_OBJECT (ethi->etfcd.widget), ði->etfcd.pointer); - - if (ethi->config) - g_object_unref (ethi->config); - ethi->config = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (ethi_parent_class)->dispose (object); -} - -static gint -e_table_header_item_get_height (ETableHeaderItem *ethi) -{ - ETableHeader *eth; - gint numcols, col; - gint maxheight; - - g_return_val_if_fail (ethi != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER_ITEM (ethi), 0); - - eth = ethi->eth; - numcols = e_table_header_count (eth); - - maxheight = 0; - - for (col = 0; col < numcols; col++) { - ETableCol *ecol = e_table_header_get_column (eth, col); - gint height; - - height = e_table_header_compute_height ( - ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas)); - - if (height > maxheight) - maxheight = height; - } - - return maxheight; -} - -static void -ethi_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); - gdouble x1, y1, x2, y2; - - if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update) - GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update ( - item, i2c, flags); - - if (ethi->sort_info) - ethi->group_indent_width = - e_table_sort_info_grouping_get_count (ethi->sort_info) - * GROUP_INDENT; - else - ethi->group_indent_width = 0; - - ethi->width = - e_table_header_total_width (ethi->eth) + - ethi->group_indent_width; - - x1 = y1 = 0; - x2 = ethi->width; - y2 = ethi->height; - - gnome_canvas_matrix_transform_rect (i2c, &x1, &y1, &x2, &y2); - - if (item->x1 != x1 || - item->y1 != y1 || - item->x2 != x2 || - item->y2 != y2) { - gnome_canvas_request_redraw ( - item->canvas, - item->x1, item->y1, - item->x2, item->y2); - item->x1 = x1; - item->y1 = y1; - item->x2 = x2; - item->y2 = y2; - } - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, item->x2, item->y2); -} - -static void -ethi_font_set (ETableHeaderItem *ethi, - PangoFontDescription *font_desc) -{ - if (ethi->font_desc) - pango_font_description_free (ethi->font_desc); - - ethi->font_desc = pango_font_description_copy (font_desc); - - ethi->height = e_table_header_item_get_height (ethi); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (ethi)); -} - -static void -ethi_drop_table_header (ETableHeaderItem *ethi) -{ - GObject *header; - - if (!ethi->eth) - return; - - header = G_OBJECT (ethi->eth); - g_signal_handler_disconnect (header, ethi->structure_change_id); - g_signal_handler_disconnect (header, ethi->dimension_change_id); - - g_object_unref (header); - ethi->eth = NULL; - ethi->width = 0; -} - -static void -structure_changed (ETableHeader *header, - ETableHeaderItem *ethi) -{ - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static void -dimension_changed (ETableHeader *header, - gint col, - ETableHeaderItem *ethi) -{ - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static void -ethi_add_table_header (ETableHeaderItem *ethi, - ETableHeader *header) -{ - ethi->eth = header; - g_object_ref (ethi->eth); - - ethi->height = e_table_header_item_get_height (ethi); - - ethi->structure_change_id = g_signal_connect ( - header, "structure_change", - G_CALLBACK (structure_changed), ethi); - ethi->dimension_change_id = g_signal_connect ( - header, "dimension_change", - G_CALLBACK (dimension_changed), ethi); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (ethi)); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static void -ethi_sort_info_changed (ETableSortInfo *sort_info, - ETableHeaderItem *ethi) -{ - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static void -ethi_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - ETableHeaderItem *ethi; - - item = GNOME_CANVAS_ITEM (object); - ethi = E_TABLE_HEADER_ITEM (object); - - switch (property_id) { - case PROP_TABLE_HEADER: - ethi_drop_table_header (ethi); - ethi_add_table_header (ethi, E_TABLE_HEADER (g_value_get_object (value))); - break; - - case PROP_FULL_HEADER: - if (ethi->full_header) - g_object_unref (ethi->full_header); - ethi->full_header = E_TABLE_HEADER (g_value_get_object (value)); - if (ethi->full_header) - g_object_ref (ethi->full_header); - break; - - case PROP_DND_CODE: - g_free (ethi->dnd_code); - ethi->dnd_code = g_strdup (g_value_get_string (value)); - break; - - case PROP_TABLE_FONT_DESC: - ethi_font_set (ethi, g_value_get_boxed (value)); - break; - - case PROP_SORT_INFO: - if (ethi->sort_info) { - if (ethi->sort_info_changed_id) - g_signal_handler_disconnect ( - ethi->sort_info, - ethi->sort_info_changed_id); - - if (ethi->group_info_changed_id) - g_signal_handler_disconnect ( - ethi->sort_info, - ethi->group_info_changed_id); - g_object_unref (ethi->sort_info); - } - ethi->sort_info = g_value_get_object (value); - g_object_ref (ethi->sort_info); - ethi->sort_info_changed_id = - g_signal_connect ( - ethi->sort_info, "sort_info_changed", - G_CALLBACK (ethi_sort_info_changed), ethi); - ethi->group_info_changed_id = - g_signal_connect ( - ethi->sort_info, "group_info_changed", - G_CALLBACK (ethi_sort_info_changed), ethi); - break; - case PROP_TABLE: - if (g_value_get_object (value)) - ethi->table = E_TABLE (g_value_get_object (value)); - else - ethi->table = NULL; - break; - case PROP_TREE: - if (g_value_get_object (value)) - ethi->tree = E_TREE (g_value_get_object (value)); - else - ethi->tree = NULL; - break; - } - gnome_canvas_item_request_update (item); -} - -static void -ethi_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableHeaderItem *ethi; - - ethi = E_TABLE_HEADER_ITEM (object); - - switch (property_id) { - case PROP_FULL_HEADER: - g_value_set_object (value, ethi->full_header); - break; - case PROP_DND_CODE: - g_value_set_string (value, ethi->dnd_code); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gint -ethi_find_col_by_x (ETableHeaderItem *ethi, - gint x) -{ - const gint cols = e_table_header_count (ethi->eth); - gint x1 = 0; - gint col; - - d (g_print ("%s:%d: x = %d, x1 = %d\n", __FUNCTION__, __LINE__, x, x1)); - - x1 += ethi->group_indent_width; - - if (x < x1) { - d (g_print ("%s:%d: Returning 0\n", __FUNCTION__, __LINE__)); - return 0; - } - - for (col = 0; col < cols; col++) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, col); - - if ((x >= x1) && (x <= x1 + ecol->width)) { - d (g_print ("%s:%d: Returning %d\n", __FUNCTION__, __LINE__, col)); - return col; - } - - x1 += ecol->width; - } - d (g_print ("%s:%d: Returning %d\n", __FUNCTION__, __LINE__, cols - 1)); - return cols - 1; -} - -static gint -ethi_find_col_by_x_nearest (ETableHeaderItem *ethi, - gint x) -{ - const gint cols = e_table_header_count (ethi->eth); - gint x1 = 0; - gint col; - - x1 += ethi->group_indent_width; - - if (x < x1) - return 0; - - for (col = 0; col < cols; col++) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, col); - - x1 += (ecol->width / 2); - - if (x <= x1) - return col; - - x1 += (ecol->width + 1) / 2; - } - return col; -} - -static void -ethi_remove_drop_marker (ETableHeaderItem *ethi) -{ - if (ethi->drag_mark == -1) - return; - - gtk_widget_hide (arrow_up); - gtk_widget_hide (arrow_down); - - ethi->drag_mark = -1; -} - -static GtkWidget * -make_shaped_window_from_xpm (const gchar **xpm) -{ - GdkPixbuf *pixbuf; - GtkWidget *win, *pix; - - pixbuf = gdk_pixbuf_new_from_xpm_data (xpm); - - win = gtk_window_new (GTK_WINDOW_POPUP); - gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_NOTIFICATION); - - pix = gtk_image_new_from_pixbuf (pixbuf); - gtk_widget_realize (win); - gtk_container_add (GTK_CONTAINER (win), pix); - - g_object_unref (pixbuf); - - return win; -} - -static void -ethi_add_drop_marker (ETableHeaderItem *ethi, - gint col, - gboolean recreate) -{ - GnomeCanvas *canvas; - GtkAdjustment *adjustment; - GdkWindow *window; - gint rx, ry; - gint x; - - if (!recreate && ethi->drag_mark == col) - return; - - ethi->drag_mark = col; - - x = e_table_header_col_diff (ethi->eth, 0, col); - if (col > 0) - x += ethi->group_indent_width; - - if (!arrow_up) { - arrow_up = make_shaped_window_from_xpm (arrow_up_xpm); - arrow_down = make_shaped_window_from_xpm (arrow_down_xpm); - } - - canvas = GNOME_CANVAS_ITEM (ethi)->canvas; - window = gtk_widget_get_window (GTK_WIDGET (canvas)); - gdk_window_get_origin (window, &rx, &ry); - - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)); - rx -= gtk_adjustment_get_value (adjustment); - - adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)); - ry -= gtk_adjustment_get_value (adjustment); - - gtk_window_move ( - GTK_WINDOW (arrow_down), - rx + x - ARROW_PTR, - ry - ARROW_DOWN_HEIGHT); - gtk_widget_show_all (arrow_down); - - gtk_window_move ( - GTK_WINDOW (arrow_up), - rx + x - ARROW_PTR, - ry + ethi->height); - gtk_widget_show_all (arrow_up); -} - -static void -ethi_add_destroy_marker (ETableHeaderItem *ethi) -{ - gdouble x1; - - if (ethi->remove_item) - g_object_run_dispose (G_OBJECT (ethi->remove_item)); - - x1 = (gdouble) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col); - if (ethi->drag_col > 0) - x1 += ethi->group_indent_width; - - ethi->remove_item = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root), - gnome_canvas_rect_get_type (), - "x1", x1 + 1, - "y1", (gdouble) 1, - "x2", (gdouble) x1 + e_table_header_col_diff ( - ethi->eth, ethi->drag_col, ethi->drag_col + 1) - 2, - - "y2", (gdouble) ethi->height - 2, - "fill_color_rgba", 0xFF000080, - NULL); -} - -static void -ethi_remove_destroy_marker (ETableHeaderItem *ethi) -{ - if (!ethi->remove_item) - return; - - g_object_run_dispose (G_OBJECT (ethi->remove_item)); - ethi->remove_item = NULL; -} - -#if 0 -static gboolean -moved (ETableHeaderItem *ethi, - guint col, - guint model_col) -{ - if (col == -1) - return TRUE; - ecol = e_table_header_get_column (ethi->eth, col); - if (ecol->col_idx == model_col) - return FALSE; - if (col > 0) { - ecol = e_table_header_get_column (ethi->eth, col - 1); - if (ecol->col_idx == model_col) - return FALSE; - } - return TRUE; -} -#endif - -static void -do_drag_motion (ETableHeaderItem *ethi, - GdkDragContext *context, - gint x, - gint y, - guint time, - gboolean recreate) -{ - if ((x >= 0) && (x <= (ethi->width)) && - (y >= 0) && (y <= (ethi->height))) { - GdkDragAction suggested_action; - gint col; - d (g_print ("In header\n")); - - col = ethi_find_col_by_x_nearest (ethi, x); - suggested_action = gdk_drag_context_get_suggested_action (context); - - if (ethi->drag_col != -1 && (col == ethi->drag_col || - col == ethi->drag_col + 1)) { - if (ethi->drag_col != -1) - ethi_remove_destroy_marker (ethi); - - ethi_remove_drop_marker (ethi); - gdk_drag_status (context, suggested_action, time); - } - else if (col != -1) { - if (ethi->drag_col != -1) - ethi_remove_destroy_marker (ethi); - - ethi_add_drop_marker (ethi, col, recreate); - gdk_drag_status (context, suggested_action, time); - } else { - ethi_remove_drop_marker (ethi); - if (ethi->drag_col != -1) - ethi_add_destroy_marker (ethi); - } - } else { - ethi_remove_drop_marker (ethi); - if (ethi->drag_col != -1) - ethi_add_destroy_marker (ethi); - } -} - -static gboolean -scroll_timeout (gpointer data) -{ - ETableHeaderItem *ethi = data; - gint dx = 0; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gdouble hadjustment_value; - gdouble vadjustment_value; - gdouble page_size; - gdouble lower; - gdouble upper; - gdouble value; - - if (ethi->scroll_direction & ET_SCROLL_RIGHT) - dx += 20; - if (ethi->scroll_direction & ET_SCROLL_LEFT) - dx -= 20; - - scrollable = GTK_SCROLLABLE (GNOME_CANVAS_ITEM (ethi)->canvas); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - hadjustment_value = gtk_adjustment_get_value (adjustment); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - vadjustment_value = gtk_adjustment_get_value (adjustment); - - value = hadjustment_value; - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - page_size = gtk_adjustment_get_page_size (adjustment); - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - - gtk_adjustment_set_value ( - adjustment, CLAMP ( - hadjustment_value + dx, lower, upper - page_size)); - - hadjustment_value = gtk_adjustment_get_value (adjustment); - - if (hadjustment_value != value) - do_drag_motion ( - ethi, - ethi->last_drop_context, - ethi->last_drop_x + hadjustment_value, - ethi->last_drop_y + vadjustment_value, - ethi->last_drop_time, - TRUE); - - return TRUE; -} - -static void -scroll_on (ETableHeaderItem *ethi, - guint scroll_direction) -{ - if (ethi->scroll_idle_id == 0 || scroll_direction != ethi->scroll_direction) { - if (ethi->scroll_idle_id != 0) - g_source_remove (ethi->scroll_idle_id); - ethi->scroll_direction = scroll_direction; - ethi->scroll_idle_id = g_timeout_add (100, scroll_timeout, ethi); - } -} - -static void -scroll_off (ETableHeaderItem *ethi) -{ - if (ethi->scroll_idle_id) { - g_source_remove (ethi->scroll_idle_id); - ethi->scroll_idle_id = 0; - } -} - -static void -context_destroyed (gpointer data) -{ - ETableHeaderItem *ethi = data; - - ethi->last_drop_x = 0; - ethi->last_drop_y = 0; - ethi->last_drop_time = 0; - ethi->last_drop_context = NULL; - scroll_off (ethi); - - g_object_unref (ethi); -} - -static void -context_connect (ETableHeaderItem *ethi, - GdkDragContext *context) -{ - if (g_dataset_get_data (context, "e-table-header-item") == NULL) - g_dataset_set_data_full ( - context, "e-table-header-item", - g_object_ref (ethi), context_destroyed); -} - -static gboolean -ethi_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETableHeaderItem *ethi) -{ - GtkAllocation allocation; - GtkAdjustment *adjustment; - GList *targets; - gdouble hadjustment_value; - gdouble vadjustment_value; - gchar *droptype, *headertype; - guint direction = 0; - - gdk_drag_status (context, 0, time); - - targets = gdk_drag_context_list_targets (context); - droptype = gdk_atom_name (GDK_POINTER_TO_ATOM (targets->data)); - headertype = g_strdup_printf ( - "%s-%s", TARGET_ETABLE_COL_TYPE, ethi->dnd_code); - - if (strcmp (droptype, headertype) != 0) { - g_free (headertype); - return FALSE; - } - - g_free (headertype); - - gtk_widget_get_allocation (widget, &allocation); - - if (x < 20) - direction |= ET_SCROLL_LEFT; - if (x > allocation.width - 20) - direction |= ET_SCROLL_RIGHT; - - ethi->last_drop_x = x; - ethi->last_drop_y = y; - ethi->last_drop_time = time; - ethi->last_drop_context = context; - context_connect (ethi, context); - - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (widget)); - hadjustment_value = gtk_adjustment_get_value (adjustment); - - adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (widget)); - vadjustment_value = gtk_adjustment_get_value (adjustment); - - do_drag_motion ( - ethi, context, - x + hadjustment_value, - y + vadjustment_value, - time, FALSE); - - if (direction != 0) - scroll_on (ethi, direction); - else - scroll_off (ethi); - - return TRUE; -} - -static void -ethi_drag_end (GtkWidget *canvas, - GdkDragContext *context, - ETableHeaderItem *ethi) -{ - ethi_remove_drop_marker (ethi); - ethi_remove_destroy_marker (ethi); - ethi->drag_col = -1; - scroll_off (ethi); -} - -static void -ethi_drag_data_received (GtkWidget *canvas, - GdkDragContext *drag_context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - ETableHeaderItem *ethi) -{ - const guchar *data; - gint found = FALSE; - gint count; - gint column; - gint drop_col; - gint i; - - data = gtk_selection_data_get_data (selection_data); - - if (data != NULL) { - count = e_table_header_count (ethi->eth); - column = atoi ((gchar *) data); - drop_col = ethi->drop_col; - ethi->drop_col = -1; - - if (column >= 0) { - for (i = 0; i < count; i++) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, i); - if (ecol->col_idx == column) { - e_table_header_move (ethi->eth, i, drop_col); - found = TRUE; - break; - } - } - if (!found) { - count = e_table_header_count (ethi->full_header); - for (i = 0; i < count; i++) { - ETableCol *ecol; - - ecol = e_table_header_get_column ( - ethi->full_header, i); - - if (ecol->col_idx == column) { - e_table_header_add_column ( - ethi->eth, ecol, - drop_col); - break; - } - } - } - } - } - ethi_remove_drop_marker (ethi); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static void -ethi_drag_data_get (GtkWidget *canvas, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETableHeaderItem *ethi) -{ - if (ethi->drag_col != -1) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, ethi->drag_col); - - gchar *string = g_strdup_printf ("%d", ecol->col_idx); - gtk_selection_data_set ( - selection_data, - GDK_SELECTION_TYPE_STRING, - sizeof (string[0]), - (guchar *) string, - strlen (string)); - g_free (string); - } -} - -static gboolean -ethi_drag_drop (GtkWidget *canvas, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETableHeaderItem *ethi) -{ - gboolean successful = FALSE; - - if ((x >= 0) && (x <= (ethi->width)) && - (y >= 0) && (y <= (ethi->height))) { - gint col; - - col = ethi_find_col_by_x_nearest (ethi, x); - - ethi_add_drop_marker (ethi, col, FALSE); - - ethi->drop_col = col; - - if (col != -1) { - gchar *target = g_strdup_printf ( - "%s-%s", TARGET_ETABLE_COL_TYPE, ethi->dnd_code); - d (g_print ("ethi - %s\n", target)); - gtk_drag_get_data ( - canvas, context, - gdk_atom_intern (target, FALSE), - time); - g_free (target); - } - } - gtk_drag_finish (context, successful, successful, time); - scroll_off (ethi); - return successful; -} - -static void -ethi_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - ETableHeaderItem *ethi) -{ - ethi_remove_drop_marker (ethi); - if (ethi->drag_col != -1) - ethi_add_destroy_marker (ethi); -} - -static void -ethi_realize (GnomeCanvasItem *item) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); - GtkStyle *style; - GtkTargetEntry ethi_drop_types[] = { - { (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER }, - }; - - if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize) - (*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item); - - style = gtk_widget_get_style (GTK_WIDGET (item->canvas)); - - if (!ethi->font_desc) - ethi_font_set (ethi, style->font_desc); - - /* - * Now, configure DnD - */ - ethi_drop_types[0].target = g_strdup_printf ( - "%s-%s", ethi_drop_types[0].target, ethi->dnd_code); - gtk_drag_dest_set ( - GTK_WIDGET (item->canvas), 0, ethi_drop_types, - G_N_ELEMENTS (ethi_drop_types), GDK_ACTION_MOVE); - g_free ((gpointer) ethi_drop_types[0].target); - - /* Drop signals */ - ethi->drag_motion_id = g_signal_connect ( - item->canvas, "drag_motion", - G_CALLBACK (ethi_drag_motion), ethi); - ethi->drag_leave_id = g_signal_connect ( - item->canvas, "drag_leave", - G_CALLBACK (ethi_drag_leave), ethi); - ethi->drag_drop_id = g_signal_connect ( - item->canvas, "drag_drop", - G_CALLBACK (ethi_drag_drop), ethi); - ethi->drag_data_received_id = g_signal_connect ( - item->canvas, "drag_data_received", - G_CALLBACK (ethi_drag_data_received), ethi); - - /* Drag signals */ - ethi->drag_end_id = g_signal_connect ( - item->canvas, "drag_end", - G_CALLBACK (ethi_drag_end), ethi); - ethi->drag_data_get_id = g_signal_connect ( - item->canvas, "drag_data_get", - G_CALLBACK (ethi_drag_data_get), ethi); - -} - -static void -ethi_unrealize (GnomeCanvasItem *item) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); - - if (ethi->font_desc != NULL) { - pango_font_description_free (ethi->font_desc); - ethi->font_desc = NULL; - } - - g_signal_handler_disconnect (item->canvas, ethi->drag_motion_id); - g_signal_handler_disconnect (item->canvas, ethi->drag_leave_id); - g_signal_handler_disconnect (item->canvas, ethi->drag_drop_id); - g_signal_handler_disconnect (item->canvas, ethi->drag_data_received_id); - - g_signal_handler_disconnect (item->canvas, ethi->drag_end_id); - g_signal_handler_disconnect (item->canvas, ethi->drag_data_get_id); - - gtk_drag_dest_unset (GTK_WIDGET (item->canvas)); - - if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item); -} - -static void -ethi_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); - GnomeCanvas *canvas = item->canvas; - const gint cols = e_table_header_count (ethi->eth); - gint x1, x2; - gint col; - GHashTable *arrows = g_hash_table_new (NULL, NULL); - GtkStyleContext *context; - - if (ethi->sort_info) { - gint length; - gint i; - - length = e_table_sort_info_grouping_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column; - - column = e_table_sort_info_grouping_get_nth ( - ethi->sort_info, i); - - g_hash_table_insert ( - arrows, - GINT_TO_POINTER ((gint) column.column), - GINT_TO_POINTER ( - column.ascending ? - E_TABLE_COL_ARROW_DOWN : - E_TABLE_COL_ARROW_UP)); - } - - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column; - - column = e_table_sort_info_sorting_get_nth ( - ethi->sort_info, i); - - g_hash_table_insert ( - arrows, - GINT_TO_POINTER ((gint) column.column), - GINT_TO_POINTER ( - column.ascending ? - E_TABLE_COL_ARROW_DOWN : - E_TABLE_COL_ARROW_UP)); - } - } - - ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width; - x1 = x2 = 0; - x2 += ethi->group_indent_width; - - context = gtk_widget_get_style_context (GTK_WIDGET (canvas)); - - for (col = 0; col < cols; col++, x1 = x2) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, col); - gint col_width; - GtkRegionFlags flags = 0; - - col_width = ecol->width; - - x2 += col_width; - - if (x1 > (x + width)) - break; - - if (x2 < x) - continue; - - if (x2 <= x1) - continue; - - if (((col + 1) % 2) == 0) - flags |= GTK_REGION_EVEN; - else - flags |= GTK_REGION_ODD; - - if (col == 0) - flags |= GTK_REGION_FIRST; - - if (col + 1 == cols) - flags |= GTK_REGION_LAST; - - gtk_style_context_save (context); - gtk_style_context_add_region ( - context, GTK_STYLE_REGION_COLUMN_HEADER, flags); - - e_table_header_draw_button ( - cr, ecol, GTK_WIDGET (canvas), - x1 - x, -y, width, height, - x2 - x1, ethi->height, - (ETableColArrow) g_hash_table_lookup ( - arrows, GINT_TO_POINTER (ecol->col_idx))); - - gtk_style_context_restore (context); - } - - g_hash_table_destroy (arrows); -} - -static GnomeCanvasItem * -ethi_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - return item; -} - -/* - * is_pointer_on_division: - * - * Returns whether @pos is a column header division; If @the_total is not NULL, - * then the actual position is returned here. If @return_ecol is not NULL, - * then the ETableCol that actually contains this point is returned here - */ -static gboolean -is_pointer_on_division (ETableHeaderItem *ethi, - gint pos, - gint *the_total, - gint *return_col) -{ - const gint cols = e_table_header_count (ethi->eth); - gint col, total; - - total = 0; - for (col = 0; col < cols; col++) { - ETableCol *ecol = e_table_header_get_column (ethi->eth, col); - - if (col == 0) - total += ethi->group_indent_width; - - total += ecol->width; - - if ((total - TOLERANCE < pos) && (pos < total + TOLERANCE)) { - if (return_col) - *return_col = col; - if (the_total) - *the_total = total; - - return TRUE; - } - if (return_col) - *return_col = col; - - if (total > pos + TOLERANCE) - return FALSE; - } - - return FALSE; -} - -#define convert(c,sx,sy,x,y) gnome_canvas_w2c (c,sx,sy,x,y) - -static void -set_cursor (ETableHeaderItem *ethi, - gint pos) -{ - GnomeCanvas *canvas; - GdkWindow *window; - gboolean resizable = FALSE; - gint col; - - canvas = GNOME_CANVAS_ITEM (ethi)->canvas; - window = gtk_widget_get_window (GTK_WIDGET (canvas)); - - /* We might be invoked before we are realized */ - if (window == NULL) - return; - - if (is_pointer_on_division (ethi, pos, NULL, &col)) { - gint last_col = ethi->eth->col_count - 1; - ETableCol *ecol = e_table_header_get_column (ethi->eth, col); - - /* Last column is not resizable */ - if (ecol->resizable && col != last_col) { - gint c = col + 1; - - /* Column is not resizable if all columns after it - * are also not resizable */ - for (; c <= last_col; c++) { - ETableCol *ecol2; - - ecol2 = e_table_header_get_column (ethi->eth, c); - if (ecol2->resizable) { - resizable = TRUE; - break; - } - } - } - } - - if (resizable) - gdk_window_set_cursor (window, ethi->resize_cursor); - else - gdk_window_set_cursor (window, NULL); -} - -static void -ethi_end_resize (ETableHeaderItem *ethi) -{ - ethi->resize_col = -1; - ethi->resize_guide = GINT_TO_POINTER (0); - - if (ethi->table) - e_table_thaw_state_change (ethi->table); - else if (ethi->tree) - e_tree_thaw_state_change (ethi->tree); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); -} - -static gboolean -ethi_maybe_start_drag (ETableHeaderItem *ethi, - GdkEventMotion *event) -{ - if (!ethi->maybe_drag) - return FALSE; - - if (ethi->eth->col_count < 2) { - ethi->maybe_drag = FALSE; - return FALSE; - } - - if (MAX (abs (ethi->click_x - event->x), - abs (ethi->click_y - event->y)) <= 3) - return FALSE; - - return TRUE; -} - -static void -ethi_start_drag (ETableHeaderItem *ethi, - GdkEvent *event) -{ - GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas); - GtkTargetList *list; - GdkDragContext *context; - ETableCol *ecol; - gint col_width; - cairo_surface_t *s; - cairo_t *cr; - - gint group_indent = 0; - GHashTable *arrows = g_hash_table_new (NULL, NULL); - - GtkTargetEntry ethi_drag_types[] = { - { (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER }, - }; - - widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas); - ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x); - - if (ethi->drag_col == -1) - return; - - if (ethi->sort_info) { - gint length = e_table_sort_info_grouping_get_count (ethi->sort_info); - gint i; - for (i = 0; i < length; i++) { - ETableSortColumn column = - e_table_sort_info_grouping_get_nth ( - ethi->sort_info, i); - group_indent++; - g_hash_table_insert ( - arrows, - GINT_TO_POINTER ((gint) column.column), - GINT_TO_POINTER ( - column.ascending ? - E_TABLE_COL_ARROW_DOWN : - E_TABLE_COL_ARROW_UP)); - } - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column = - e_table_sort_info_sorting_get_nth ( - ethi->sort_info, i); - - g_hash_table_insert ( - arrows, - GINT_TO_POINTER ((gint) column.column), - GINT_TO_POINTER ( - column.ascending ? - E_TABLE_COL_ARROW_DOWN : - E_TABLE_COL_ARROW_UP)); - } - } - - ethi_drag_types[0].target = g_strdup_printf ( - "%s-%s", ethi_drag_types[0].target, ethi->dnd_code); - list = gtk_target_list_new ( - ethi_drag_types, G_N_ELEMENTS (ethi_drag_types)); - context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event); - g_free ((gpointer) ethi_drag_types[0].target); - - ecol = e_table_header_get_column (ethi->eth, ethi->drag_col); - col_width = ecol->width; - s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, col_width, ethi->height); - cr = cairo_create (s); - - e_table_header_draw_button ( - cr, ecol, - widget, 0, 0, - col_width, ethi->height, - col_width, ethi->height, - (ETableColArrow) g_hash_table_lookup ( - arrows, GINT_TO_POINTER (ecol->col_idx))); - gtk_drag_set_icon_surface (context, s); - cairo_surface_destroy (s); - - ethi->maybe_drag = FALSE; - g_hash_table_destroy (arrows); -} - -typedef struct { - ETableHeaderItem *ethi; - gint col; -} EthiHeaderInfo; - -static void -ethi_popup_sort_ascending (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableCol *col; - gint model_col = -1; - gint length; - gint i; - gint found = FALSE; - ETableHeaderItem *ethi = info->ethi; - - col = e_table_header_get_column (ethi->eth, info->col); - if (col->sortable) - model_col = col->col_idx; - - length = e_table_sort_info_grouping_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column = e_table_sort_info_grouping_get_nth ( - ethi->sort_info, i); - - if (model_col == column.column) { - column.ascending = 1; - e_table_sort_info_grouping_set_nth ( - ethi->sort_info, i, column); - found = 1; - break; - } - } - if (!found) { - length = e_table_sort_info_sorting_get_count ( - ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column = - e_table_sort_info_sorting_get_nth ( - ethi->sort_info, i); - if (model_col == column.column || model_col == -1) { - column.ascending = 1; - e_table_sort_info_sorting_set_nth ( - ethi->sort_info, i, column); - found = 1; - if (model_col != -1) - break; - } - } - } - if (!found) { - ETableSortColumn column; - column.column = model_col; - column.ascending = 1; - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - if (length == 0) - length++; - e_table_sort_info_sorting_set_nth (ethi->sort_info, length - 1, column); - } -} - -static void -ethi_popup_sort_descending (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableCol *col; - gint model_col=-1; - gint length; - gint i; - gint found = FALSE; - ETableHeaderItem *ethi = info->ethi; - - col = e_table_header_get_column (ethi->eth, info->col); - if (col->sortable) - model_col = col->col_idx; - - length = e_table_sort_info_grouping_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column = e_table_sort_info_grouping_get_nth ( - ethi->sort_info, i); - if (model_col == column.column) { - column.ascending = 0; - e_table_sort_info_grouping_set_nth ( - ethi->sort_info, i, column); - found = 1; - break; - } - } - if (!found) { - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column = - e_table_sort_info_sorting_get_nth ( - ethi->sort_info, i); - - if (model_col == column.column || model_col == -1) { - column.ascending = 0; - e_table_sort_info_sorting_set_nth ( - ethi->sort_info, i, column); - found = 1; - if (model_col != -1) - break; - } - } - } - if (!found) { - ETableSortColumn column; - column.column = model_col; - column.ascending = 0; - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - if (length == 0) - length++; - e_table_sort_info_sorting_set_nth ( - ethi->sort_info, length - 1, column); - } -} - -static void -ethi_popup_unsort (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableHeaderItem *ethi = info->ethi; - - e_table_sort_info_grouping_truncate (ethi->sort_info, 0); - e_table_sort_info_sorting_truncate (ethi->sort_info, 0); -} - -static void -ethi_popup_group_field (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableCol *col; - gint model_col; - ETableHeaderItem *ethi = info->ethi; - ETableSortColumn column; - - col = e_table_header_get_column (ethi->eth, info->col); - model_col = col->col_idx; - - column.column = model_col; - column.ascending = 1; - e_table_sort_info_grouping_set_nth (ethi->sort_info, 0, column); - e_table_sort_info_grouping_truncate (ethi->sort_info, 1); -} - -static void -ethi_popup_group_box (GtkWidget *widget, - EthiHeaderInfo *info) -{ -} - -static void -ethi_popup_remove_column (GtkWidget *widget, - EthiHeaderInfo *info) -{ - e_table_header_remove (info->ethi->eth, info->col); -} - -static void -ethi_popup_field_chooser (GtkWidget *widget, - EthiHeaderInfo *info) -{ - GtkWidget *etfcd = info->ethi->etfcd.widget; - - if (etfcd) { - gtk_window_present (GTK_WINDOW (etfcd)); - - return; - } - - info->ethi->etfcd.widget = e_table_field_chooser_dialog_new (); - etfcd = info->ethi->etfcd.widget; - - g_object_add_weak_pointer (G_OBJECT (etfcd), &info->ethi->etfcd.pointer); - - g_object_set ( - info->ethi->etfcd.widget, - "full_header", info->ethi->full_header, - "header", info->ethi->eth, - "dnd_code", info->ethi->dnd_code, - NULL); - - gtk_widget_show (etfcd); -} - -static void -ethi_popup_alignment (GtkWidget *widget, - EthiHeaderInfo *info) -{ -} - -static void -ethi_popup_best_fit (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableHeaderItem *ethi = info->ethi; - gint width; - - g_signal_emit_by_name ( - ethi->eth, - "request_width", - info->col, &width); - /* Add 10 to stop it from "..."ing */ - e_table_header_set_size (ethi->eth, info->col, width + 10); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); - -} - -static void -ethi_popup_format_columns (GtkWidget *widget, - EthiHeaderInfo *info) -{ -} - -static void -config_destroyed (gpointer data, - GObject *where_object_was) -{ - ETableHeaderItem *ethi = data; - ethi->config = NULL; -} - -static void -apply_changes (ETableConfig *config, - ETableHeaderItem *ethi) -{ - gchar *state = e_table_state_save_to_string (config->state); - - if (ethi->table) - e_table_set_state (ethi->table, state); - if (ethi->tree) - e_tree_set_state (ethi->tree, state); - g_free (state); - - gtk_dialog_set_response_sensitive ( - GTK_DIALOG (config->dialog_toplevel), - GTK_RESPONSE_APPLY, FALSE); -} - -static void -ethi_popup_customize_view (GtkWidget *widget, - EthiHeaderInfo *info) -{ - ETableHeaderItem *ethi = info->ethi; - ETableState *state; - ETableSpecification *spec; - - if (ethi->config) - e_table_config_raise (E_TABLE_CONFIG (ethi->config)); - else { - if (ethi->table) { - state = e_table_get_state_object (ethi->table); - spec = ethi->table->spec; - } else if (ethi->tree) { - state = e_tree_get_state_object (ethi->tree); - spec = e_tree_get_spec (ethi->tree); - } else - return; - - ethi->config = e_table_config_new ( - _("Customize Current View"), - spec, state, GTK_WINDOW (gtk_widget_get_toplevel (widget))); - g_object_weak_ref ( - G_OBJECT (ethi->config), - config_destroyed, ethi); - g_signal_connect ( - ethi->config, "changed", - G_CALLBACK (apply_changes), ethi); - } -} - -static void -free_popup_info (GtkWidget *w, - EthiHeaderInfo *info) -{ - g_free (info); -} - -/* Bit 1 is always disabled. */ -/* Bit 2 is disabled if not "sortable". */ -/* Bit 4 is disabled if we don't have a pointer to our table object. */ -static EPopupMenu ethi_context_menu[] = { - E_POPUP_ITEM ( - N_("Sort _Ascending"), - G_CALLBACK (ethi_popup_sort_ascending), 2), - E_POPUP_ITEM ( - N_("Sort _Descending"), - G_CALLBACK (ethi_popup_sort_descending), 2), - E_POPUP_ITEM ( - N_("_Unsort"), G_CALLBACK (ethi_popup_unsort), 0), - E_POPUP_SEPARATOR, - E_POPUP_ITEM ( - N_("Group By This _Field"), - G_CALLBACK (ethi_popup_group_field), 16), - E_POPUP_ITEM ( - N_("Group By _Box"), - G_CALLBACK (ethi_popup_group_box), 128), - E_POPUP_SEPARATOR, - E_POPUP_ITEM ( - N_("Remove This _Column"), - G_CALLBACK (ethi_popup_remove_column), 8), - E_POPUP_ITEM ( - N_("Add a C_olumn..."), - G_CALLBACK (ethi_popup_field_chooser), 0), - E_POPUP_SEPARATOR, - E_POPUP_ITEM ( - N_("A_lignment"), - G_CALLBACK (ethi_popup_alignment), 128), - E_POPUP_ITEM ( - N_("B_est Fit"), - G_CALLBACK (ethi_popup_best_fit), 2), - E_POPUP_ITEM ( - N_("Format Column_s..."), - G_CALLBACK (ethi_popup_format_columns), 128), - E_POPUP_SEPARATOR, - E_POPUP_ITEM ( - N_("Custo_mize Current View..."), - G_CALLBACK (ethi_popup_customize_view), 4), - E_POPUP_TERMINATOR -}; - -static void -sort_by_id (GtkWidget *menu_item, - ETableHeaderItem *ethi) -{ - ETableCol *ecol; - gboolean clearfirst; - gint col; - - col = GPOINTER_TO_INT (g_object_get_data ( - G_OBJECT (menu_item), "col-number")); - ecol = e_table_header_get_column (ethi->full_header, col); - clearfirst = e_table_sort_info_sorting_get_count (ethi->sort_info) > 1; - - if (!clearfirst && ecol && - e_table_sort_info_sorting_get_count (ethi->sort_info) == 1) { - ETableSortColumn column; - - column = e_table_sort_info_sorting_get_nth (ethi->sort_info, 0); - clearfirst = ecol->sortable && ecol->col_idx != column.column; - } - - if (clearfirst) - e_table_sort_info_sorting_truncate (ethi->sort_info, 0); - - ethi_change_sort_state (ethi, ecol); -} - -static void -popup_custom (GtkWidget *menu_item, - EthiHeaderInfo *info) -{ - ethi_popup_customize_view (menu_item, info); -} - -static void -ethi_header_context_menu (ETableHeaderItem *ethi, - GdkEvent *button_event) -{ - EthiHeaderInfo *info = g_new (EthiHeaderInfo, 1); - GtkMenu *popup; - gint ncol, sort_count, sort_col; - GtkWidget *menu_item, *sub_menu; - ETableSortColumn column; - gboolean ascending = TRUE; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - guint event_button = 0; - guint32 event_time; - - d (g_print ("ethi_header_context_menu: \n")); - - gdk_event_get_button (button_event, &event_button); - gdk_event_get_coords (button_event, &event_x_win, &event_y_win); - event_time = gdk_event_get_time (button_event); - - info->ethi = ethi; - info->col = ethi_find_col_by_x (ethi, event_x_win); - - popup = e_popup_menu_create_with_domain ( - ethi_context_menu, - 1 + - ((ethi->table || ethi->tree) ? 0 : 4) + - ((e_table_header_count (ethi->eth) > 1) ? 0 : 8), - ((e_table_sort_info_get_can_group (ethi->sort_info)) ? 0 : 16) + - 128, info, GETTEXT_PACKAGE); - - menu_item = gtk_menu_item_new_with_mnemonic (_("_Sort By")); - gtk_widget_show (menu_item); - sub_menu = gtk_menu_new (); - gtk_widget_show (sub_menu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu); - gtk_menu_shell_prepend (GTK_MENU_SHELL (popup), menu_item); - - sort_count = e_table_sort_info_sorting_get_count (ethi->sort_info); - - if (sort_count > 1 || sort_count < 1) - sort_col = -1; /* Custom sorting */ - else { - column = e_table_sort_info_sorting_get_nth (ethi->sort_info, 0); - sort_col = column.column; - ascending = column.ascending; - } - - /* Custom */ - menu_item = gtk_check_menu_item_new_with_mnemonic (_("_Custom")); - gtk_widget_show (menu_item); - gtk_menu_shell_prepend (GTK_MENU_SHELL (sub_menu), menu_item); - if (sort_col == -1) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE); - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menu_item), TRUE); - g_signal_connect ( - menu_item, "activate", - G_CALLBACK (popup_custom), info); - - /* Show a seperator */ - menu_item = gtk_separator_menu_item_new (); - gtk_widget_show (menu_item); - gtk_menu_shell_prepend (GTK_MENU_SHELL (sub_menu), menu_item); - /* Headers */ - for (ncol = 0; ncol < ethi->full_header->col_count; ncol++) - { - gchar *text = NULL; - - if (!ethi->full_header->columns[ncol]->sortable || - ethi->full_header->columns[ncol]->disabled) - continue; - - if (ncol == sort_col) { - text = g_strdup_printf ( - "%s (%s)", - ethi->full_header->columns[ncol]->text, - ascending ? _("Ascending"):_("Descending")); - menu_item = gtk_check_menu_item_new_with_label (text); - g_free (text); - } else - menu_item = gtk_check_menu_item_new_with_label ( - ethi->full_header->columns[ncol]->text); - - gtk_widget_show (menu_item); - gtk_menu_shell_prepend (GTK_MENU_SHELL (sub_menu), menu_item); - - if (ncol == sort_col) - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM (menu_item), TRUE); - gtk_check_menu_item_set_draw_as_radio ( - GTK_CHECK_MENU_ITEM (menu_item), TRUE); - g_object_set_data ( - G_OBJECT (menu_item), "col-number", - GINT_TO_POINTER (ncol)); - g_signal_connect ( - menu_item, "activate", - G_CALLBACK (sort_by_id), ethi); - } - - g_object_ref_sink (popup); - g_signal_connect ( - popup, "selection-done", - G_CALLBACK (free_popup_info), info); - - gtk_menu_popup ( - GTK_MENU (popup), - NULL, NULL, NULL, NULL, - event_button, event_time); -} - -static void -ethi_button_pressed (ETableHeaderItem *ethi, - GdkEvent *button_event) -{ - g_signal_emit (ethi, ethi_signals[BUTTON_PRESSED], 0, button_event); -} - -void -ethi_change_sort_state (ETableHeaderItem *ethi, - ETableCol *col) -{ - gint model_col = -1; - gint length; - gint i; - gboolean found = FALSE; - - if (col == NULL) - return; - - if (col->sortable) - model_col = col->col_idx; - - length = e_table_sort_info_grouping_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column; - - column = e_table_sort_info_grouping_get_nth ( - ethi->sort_info, i); - - if (model_col == column.column || model_col == -1) { - gint ascending = column.ascending; - ascending = !ascending; - column.ascending = ascending; - e_table_sort_info_grouping_set_nth (ethi->sort_info, i, column); - found = TRUE; - if (model_col != -1) - break; - } - } - - if (!found) { - length = e_table_sort_info_sorting_get_count (ethi->sort_info); - for (i = 0; i < length; i++) { - ETableSortColumn column; - - column = e_table_sort_info_sorting_get_nth ( - ethi->sort_info, i); - - if (model_col == column.column || model_col == -1) { - gint ascending = column.ascending; - - if (ascending == 0 && model_col != -1) { - /* - * This means the user has clicked twice - * already, lets kill sorting of this column now. - */ - gint j; - - for (j = i + 1; j < length; j++) - e_table_sort_info_sorting_set_nth ( - ethi->sort_info, j - 1, - e_table_sort_info_sorting_get_nth ( - ethi->sort_info, j)); - - e_table_sort_info_sorting_truncate ( - ethi->sort_info, length - 1); - length--; - i--; - } else { - ascending = !ascending; - column.ascending = ascending; - e_table_sort_info_sorting_set_nth ( - ethi->sort_info, i, column); - } - found = TRUE; - if (model_col != -1) - break; - } - } - } - - if (!found && model_col != -1) { - ETableSortColumn column; - column.column = model_col; - column.ascending = 1; - e_table_sort_info_sorting_truncate (ethi->sort_info, 0); - e_table_sort_info_sorting_set_nth (ethi->sort_info, 0, column); - } -} - -/* - * Handles the events on the ETableHeaderItem, particularly it handles resizing - */ -static gint -ethi_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); - GnomeCanvas *canvas = item->canvas; - GdkWindow *window; - const gboolean resizing = ETHI_RESIZING (ethi); - gint x, y, start, col; - gint was_maybe_drag = 0; - GdkModifierType event_state = 0; - guint event_button = 0; - guint event_keyval = 0; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - guint32 event_time; - - /* Don't fetch the device here. GnomeCanvas frequently emits - * synthesized events, and calling gdk_event_get_device() on them - * will trigger a runtime warning. Fetch the device where needed. */ - gdk_event_get_button (event, &event_button); - gdk_event_get_coords (event, &event_x_win, &event_y_win); - gdk_event_get_keyval (event, &event_keyval); - gdk_event_get_state (event, &event_state); - event_time = gdk_event_get_time (event); - - switch (event->type) { - case GDK_ENTER_NOTIFY: - convert (canvas, event_x_win, event_y_win, &x, &y); - set_cursor (ethi, x); - break; - - case GDK_LEAVE_NOTIFY: - window = gtk_widget_get_window (GTK_WIDGET (canvas)); - gdk_window_set_cursor (window, NULL); - break; - - case GDK_MOTION_NOTIFY: - - convert (canvas, event_x_win, event_y_win, &x, &y); - if (resizing) { - gint new_width; - - if (ethi->resize_guide == NULL) { - GdkDevice *event_device; - - /* Quick hack until I actually bind the views */ - ethi->resize_guide = GINT_TO_POINTER (1); - - event_device = gdk_event_get_device (event); - - gnome_canvas_item_grab ( - item, - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - ethi->resize_cursor, - event_device, - event_time); - } - - new_width = x - ethi->resize_start_pos; - - e_table_header_set_size (ethi->eth, ethi->resize_col, new_width); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); - } else if (ethi_maybe_start_drag (ethi, &event->motion)) { - ethi_start_drag (ethi, event); - } else - set_cursor (ethi, x); - break; - - case GDK_BUTTON_PRESS: - if (event_button > 3) - return FALSE; - - convert (canvas, event_x_win, event_y_win, &x, &y); - - if (is_pointer_on_division (ethi, x, &start, &col) && - event_button == 1) { - ETableCol *ecol; - - /* - * Record the important bits. - * - * By setting resize_pos to a non -1 value, - * we know that we are being resized (used in the - * other event handlers). - */ - ecol = e_table_header_get_column (ethi->eth, col); - - if (!ecol->resizable) - break; - ethi->resize_col = col; - ethi->resize_start_pos = start - ecol->width; - ethi->resize_min_width = ecol->min_width; - - if (ethi->table) - e_table_freeze_state_change (ethi->table); - else if (ethi->tree) - e_tree_freeze_state_change (ethi->tree); - } else { - if (event_button == 1) { - ethi->click_x = event_x_win; - ethi->click_y = event_y_win; - ethi->maybe_drag = TRUE; - is_pointer_on_division (ethi, x, &start, &col); - ethi->selected_col = col; - if (gtk_widget_get_can_focus (GTK_WIDGET (item->canvas))) - e_canvas_item_grab_focus (item, TRUE); - } else if (event_button == 3) { - ethi_header_context_menu (ethi, event); - } else - ethi_button_pressed (ethi, event); - } - break; - - case GDK_2BUTTON_PRESS: - if (!resizing) - break; - - if (event_button != 1) - break; - else { - gint width = 0; - g_signal_emit_by_name ( - ethi->eth, - "request_width", - (gint) ethi->resize_col, &width); - /* Add 10 to stop it from "..."ing */ - e_table_header_set_size (ethi->eth, ethi->resize_col, width + 10); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); - ethi->maybe_drag = FALSE; - } - break; - - case GDK_BUTTON_RELEASE: { - gboolean needs_ungrab = FALSE; - - was_maybe_drag = ethi->maybe_drag; - - ethi->maybe_drag = FALSE; - - if (ethi->resize_col != -1) { - needs_ungrab = (ethi->resize_guide != NULL); - ethi_end_resize (ethi); - } else if (was_maybe_drag && ethi->sort_info) { - ETableCol *ecol; - - col = ethi_find_col_by_x (ethi, event_x_win); - ecol = e_table_header_get_column (ethi->eth, col); - ethi_change_sort_state (ethi, ecol); - } - - if (needs_ungrab) - gnome_canvas_item_ungrab (item, event_time); - - break; - } - case GDK_KEY_PRESS: - if ((event_keyval == GDK_KEY_F10) && (event_state & GDK_SHIFT_MASK)) { - EthiHeaderInfo *info = g_new (EthiHeaderInfo, 1); - ETableCol *ecol; - GtkMenu *popup; - - info->ethi = ethi; - info->col = ethi->selected_col; - ecol = e_table_header_get_column (ethi->eth, info->col); - - popup = e_popup_menu_create_with_domain ( - ethi_context_menu, - 1 + - (ecol->sortable ? 0 : 2) + - ((ethi->table || ethi->tree) ? 0 : 4) + - ((e_table_header_count (ethi->eth) > 1) ? 0 : 8), - ((e_table_sort_info_get_can_group ( - ethi->sort_info)) ? 0 : 16) + - 128, info, GETTEXT_PACKAGE); - g_object_ref_sink (popup); - g_signal_connect ( - popup, "selection-done", - G_CALLBACK (free_popup_info), info); - gtk_menu_popup ( - GTK_MENU (popup), - NULL, NULL, NULL, NULL, - 0, GDK_CURRENT_TIME); - } else if (event_keyval == GDK_KEY_space) { - ETableCol *ecol; - - ecol = e_table_header_get_column (ethi->eth, ethi->selected_col); - ethi_change_sort_state (ethi, ecol); - } else if ((event_keyval == GDK_KEY_Right) || - (event_keyval == GDK_KEY_KP_Right)) { - ETableCol *ecol; - - if ((ethi->selected_col < 0) || - (ethi->selected_col >= ethi->eth->col_count - 1)) - ethi->selected_col = 0; - else - ethi->selected_col++; - ecol = e_table_header_get_column (ethi->eth, ethi->selected_col); - ethi_change_sort_state (ethi, ecol); - } else if ((event_keyval == GDK_KEY_Left) || - (event_keyval == GDK_KEY_KP_Left)) { - ETableCol *ecol; - - if ((ethi->selected_col <= 0) || - (ethi->selected_col >= ethi->eth->col_count)) - ethi->selected_col = ethi->eth->col_count - 1; - else - ethi->selected_col--; - ecol = e_table_header_get_column (ethi->eth, ethi->selected_col); - ethi_change_sort_state (ethi, ecol); - } - break; - - default: - return FALSE; - } - return TRUE; -} - -static void -ethi_class_init (ETableHeaderItemClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = ethi_dispose; - object_class->set_property = ethi_set_property; - object_class->get_property = ethi_get_property; - - item_class->update = ethi_update; - item_class->realize = ethi_realize; - item_class->unrealize = ethi_unrealize; - item_class->draw = ethi_draw; - item_class->point = ethi_point; - item_class->event = ethi_event; - - g_object_class_install_property ( - object_class, - PROP_DND_CODE, - g_param_spec_string ( - "dnd_code", - "DnD code", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_FONT_DESC, - g_param_spec_boxed ( - "font-desc", - "Font Description", - NULL, - PANGO_TYPE_FONT_DESCRIPTION, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_FULL_HEADER, - g_param_spec_object ( - "full_header", - "Full Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_HEADER, - g_param_spec_object ( - "ETableHeader", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_SORT_INFO, - g_param_spec_object ( - "sort_info", - "Sort Info", - NULL, - E_TYPE_TABLE_SORT_INFO, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE, - g_param_spec_object ( - "table", - "Table", - NULL, - E_TYPE_TABLE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TREE, - g_param_spec_object ( - "tree", - "Tree", - NULL, - E_TYPE_TREE, - G_PARAM_WRITABLE)); - - ethi_signals[BUTTON_PRESSED] = g_signal_new ( - "button_pressed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableHeaderItemClass, button_pressed), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); -} - -static void -ethi_init (ETableHeaderItem *ethi) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ethi); - - ethi->resize_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - - ethi->resize_col = -1; - - item->x1 = 0; - item->y1 = 0; - item->x2 = 0; - item->y2 = 0; - - ethi->drag_col = -1; - ethi->drag_mark = -1; - - ethi->sort_info = NULL; - - ethi->sort_info_changed_id = 0; - ethi->group_info_changed_id = 0; - - ethi->group_indent_width = 0; - ethi->table = NULL; - ethi->tree = NULL; - - ethi->selected_col = 0; -} - diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h deleted file mode 100644 index baaa07cacf..0000000000 --- a/widgets/table/e-table-header-item.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza (miguel@gnu.org) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_HEADER_ITEM_H_ -#define _E_TABLE_HEADER_ITEM_H_ - -#include <table/e-table.h> -#include <table/e-tree.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <libxml/tree.h> -#include <table/e-table-header.h> -#include <table/e-table-sort-info.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_HEADER_ITEM \ - (e_table_header_item_get_type ()) -#define E_TABLE_HEADER_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_HEADER_ITEM, ETableHeaderItem)) -#define E_TABLE_HEADER_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_HEADER_ITEM, ETableHeaderItemClass)) -#define E_IS_TABLE_HEADER_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_HEADER_ITEM)) -#define E_IS_TABLE_HEADER_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_HEADER_ITEM)) -#define E_TABLE_HEADER_ITEM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_HEADER_ITEM, ETableHeaderItemClass)) - -G_BEGIN_DECLS - -typedef struct _ETableHeaderItem ETableHeaderItem; -typedef struct _ETableHeaderItemClass ETableHeaderItemClass; - -struct _ETableHeaderItem { - GnomeCanvasItem parent; - ETableHeader *eth; - - GdkCursor *change_cursor; - GdkCursor *resize_cursor; - - gshort height, width; - PangoFontDescription *font_desc; - - /* - * Used during resizing; Could be shorts - */ - gint resize_col; - gint resize_start_pos; - gint resize_min_width; - - gpointer resize_guide; - - gint group_indent_width; - - /* - * Ids - */ - gint structure_change_id, dimension_change_id; - - /* - * For dragging columns - */ - guint maybe_drag : 1; - guint dnd_ready : 1; - gint click_x, click_y; - gint drag_col, drop_col, drag_mark; - guint drag_motion_id; - guint drag_end_id; - guint drag_leave_id; - guint drag_drop_id; - guint drag_data_received_id; - guint drag_data_get_id; - guint sort_info_changed_id, group_info_changed_id; - GnomeCanvasItem *remove_item; - - gchar *dnd_code; - - /* - * For column sorting info - */ - ETableSortInfo *sort_info; - - guint scroll_direction : 4; - gint last_drop_x; - gint last_drop_y; - gint last_drop_time; - GdkDragContext *last_drop_context; - gint scroll_idle_id; - - /* For adding fields. */ - ETableHeader *full_header; - ETable *table; - ETree *tree; - gpointer config; - - union { - GtkWidget *widget; - gpointer pointer; - } etfcd; - - /* For keyboard navigation*/ - gint selected_col; -}; - -struct _ETableHeaderItemClass { - GnomeCanvasItemClass parent_class; - - /* Signals */ - void (*button_pressed) (ETableHeaderItem *ethi, - GdkEvent *button_event); -}; - -GType e_table_header_item_get_type (void) G_GNUC_CONST; -void ethi_change_sort_state (ETableHeaderItem *ethi, - ETableCol *col); - -G_END_DECLS - -#endif /* _E_TABLE_HEADER_ITEM_H_ */ diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c deleted file mode 100644 index e3d4ced22c..0000000000 --- a/widgets/table/e-table-header-utils.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> /* strlen() */ - -#include <gtk/gtk.h> - -#include "e-util/e-unicode.h" - -#include "e-table-defines.h" -#include "e-table-header-utils.h" - -static void -get_button_padding (GtkWidget *widget, - GtkBorder *padding) -{ - GtkStyleContext *context; - GtkStateFlags state_flags; - - context = gtk_widget_get_style_context (widget); - state_flags = gtk_widget_get_state_flags (widget); - - gtk_style_context_save (context); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON); - gtk_style_context_get_padding (context, state_flags, padding); - - gtk_style_context_restore (context); -} - -/** - * e_table_header_compute_height: - * @ecol: Table column description. - * @widget: The widget from which to build the PangoLayout. - * - * Computes the minimum height required for a table header button. - * - * Return value: The height of the button, in pixels. - **/ -gdouble -e_table_header_compute_height (ETableCol *ecol, - GtkWidget *widget) -{ - gint height; - PangoLayout *layout; - GtkBorder padding; - - g_return_val_if_fail (ecol != NULL, -1); - g_return_val_if_fail (E_IS_TABLE_COL (ecol), -1); - g_return_val_if_fail (GTK_IS_WIDGET (widget), -1); - - get_button_padding (widget, &padding); - - layout = gtk_widget_create_pango_layout (widget, ecol->text); - - pango_layout_get_pixel_size (layout, NULL, &height); - - if (ecol->icon_name != NULL) { - g_return_val_if_fail (ecol->pixbuf != NULL, -1); - height = MAX (height, gdk_pixbuf_get_height (ecol->pixbuf)); - } - - height = MAX (height, MIN_ARROW_SIZE); - height += padding.top + padding.bottom + 2 * HEADER_PADDING; - - g_object_unref (layout); - - return height; -} - -gdouble -e_table_header_width_extras (GtkWidget *widget) -{ - GtkBorder padding; - - get_button_padding (widget, &padding); - return padding.left + padding.right + 2 * HEADER_PADDING; -} - -/** - * e_table_header_draw_button: - * @drawable: Destination drawable. - * @ecol: Table column for the header information. - * @widget: The table widget. - * @x: Leftmost coordinate of the button. - * @y: Topmost coordinate of the button. - * @width: Width of the region to draw. - * @height: Height of the region to draw. - * @button_width: Width for the complete button. - * @button_height: Height for the complete button. - * @arrow: Arrow type to use as a sort indicator. - * - * Draws a button suitable for a table header. - **/ -void -e_table_header_draw_button (cairo_t *cr, - ETableCol *ecol, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height, - gint button_width, - gint button_height, - ETableColArrow arrow) -{ - gint inner_x, inner_y; - gint inner_width, inner_height; - gint arrow_width = 0, arrow_height = 0; - PangoContext *pango_context; - PangoLayout *layout; - GtkStyleContext *context; - GtkBorder padding; - GtkStateFlags state_flags; - - g_return_if_fail (cr != NULL); - g_return_if_fail (ecol != NULL); - g_return_if_fail (E_IS_TABLE_COL (ecol)); - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (button_width > 0 && button_height > 0); - - /* Button bevel */ - context = gtk_widget_get_style_context (widget); - state_flags = gtk_widget_get_state_flags (widget); - - gtk_style_context_save (context); - gtk_style_context_set_state (context, state_flags); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON); - - gtk_style_context_get_padding (context, state_flags, &padding); - - gtk_render_background ( - context, cr, x, y, - button_width, button_height); - gtk_render_frame ( - context, cr, x, y, - button_width, button_height); - - /* Inside area */ - - inner_width = - button_width - - (padding.left + padding.right + 2 * HEADER_PADDING); - inner_height = - button_height - - (padding.top + padding.bottom + 2 * HEADER_PADDING); - - if (inner_width < 1 || inner_height < 1) { - return; /* nothing fits */ - } - - inner_x = x + padding.left + HEADER_PADDING; - inner_y = y + padding.top + HEADER_PADDING; - - /* Arrow space */ - - switch (arrow) { - case E_TABLE_COL_ARROW_NONE: - break; - - case E_TABLE_COL_ARROW_UP: - case E_TABLE_COL_ARROW_DOWN: - arrow_width = MIN (MIN_ARROW_SIZE, inner_width); - arrow_height = MIN (MIN_ARROW_SIZE, inner_height); - - if (ecol->icon_name == NULL) - inner_width -= arrow_width + HEADER_PADDING; - break; - default: - cairo_restore (cr); - g_return_if_reached (); - } - - if (inner_width < 1) { - gtk_style_context_restore (context); - return; /* nothing else fits */ - } - - pango_context = gtk_widget_create_pango_context (widget); - layout = pango_layout_new (pango_context); - g_object_unref (pango_context); - - pango_layout_set_text (layout, ecol->text, -1); - pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); - - /* Pixbuf or label */ - if (ecol->icon_name != NULL) { - gint pwidth, pheight; - gint clip_height; - gint xpos; - - g_return_if_fail (ecol->pixbuf != NULL); - - pwidth = gdk_pixbuf_get_width (ecol->pixbuf); - pheight = gdk_pixbuf_get_height (ecol->pixbuf); - - clip_height = MIN (pheight, inner_height); - - xpos = inner_x; - - if (inner_width - pwidth > 11) { - gint ypos; - - pango_layout_get_pixel_size (layout, &width, NULL); - - if (width < inner_width - (pwidth + 1)) { - xpos = inner_x + (inner_width - width - (pwidth + 1)) / 2; - } - - ypos = inner_y; - - pango_layout_set_width ( - layout, (inner_width - (xpos - inner_x)) * - PANGO_SCALE); - - gtk_render_layout ( - context, cr, xpos + pwidth + 1, - ypos, layout); - } - - gtk_render_icon ( - context, cr, ecol->pixbuf, xpos, - inner_y + (inner_height - clip_height) / 2); - - } else { - pango_layout_set_width (layout, inner_width * PANGO_SCALE); - - gtk_render_layout (context, cr, inner_x, inner_y, layout); - } - - switch (arrow) { - case E_TABLE_COL_ARROW_NONE: - break; - - case E_TABLE_COL_ARROW_UP: - case E_TABLE_COL_ARROW_DOWN: { - if (ecol->icon_name == NULL) - inner_width += arrow_width + HEADER_PADDING; - - gtk_render_arrow ( - context, cr, - (arrow == E_TABLE_COL_ARROW_UP) ? 0 : G_PI, - inner_x + inner_width - arrow_width, - inner_y + (inner_height - arrow_height) / 2, - MAX (arrow_width, arrow_height)); - - break; - } - - default: - cairo_restore (cr); - g_return_if_reached (); - } - - g_object_unref (layout); - gtk_style_context_restore (context); -} diff --git a/widgets/table/e-table-header-utils.h b/widgets/table/e-table-header-utils.h deleted file mode 100644 index e6d2aaba1d..0000000000 --- a/widgets/table/e-table-header-utils.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TABLE_HEADER_UTILS_H -#define E_TABLE_HEADER_UTILS_H - -#include <table/e-table-col.h> - -G_BEGIN_DECLS - -gdouble e_table_header_compute_height (ETableCol *ecol, - GtkWidget *widget); -gdouble e_table_header_width_extras (GtkWidget *widget); -void e_table_header_draw_button (cairo_t *cr, - ETableCol *ecol, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height, - gint button_width, - gint button_height, - ETableColArrow arrow); - -G_END_DECLS - -#endif /* E_TABLE_HEADER_UTILS_H */ diff --git a/widgets/table/e-table-header.c b/widgets/table/e-table-header.c deleted file mode 100644 index 325390d559..0000000000 --- a/widgets/table/e-table-header.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-table-defines.h" -#include "e-table-header.h" - -enum { - PROP_0, - PROP_SORT_INFO, - PROP_WIDTH, - PROP_WIDTH_EXTRAS -}; - -enum { - STRUCTURE_CHANGE, - DIMENSION_CHANGE, - EXPANSION_CHANGE, - REQUEST_WIDTH, - LAST_SIGNAL -}; - -static void eth_set_size (ETableHeader *eth, gint idx, gint size); -static void eth_calc_widths (ETableHeader *eth); - -static guint eth_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE (ETableHeader, e_table_header, G_TYPE_OBJECT) - -struct two_ints { - gint column; - gint width; -}; - -static void -eth_set_width (ETableHeader *eth, - gint width) -{ - eth->width = width; -} - -static void -dequeue (ETableHeader *eth, - gint *column, - gint *width) -{ - GSList *head; - struct two_ints *store; - head = eth->change_queue; - eth->change_queue = eth->change_queue->next; - if (!eth->change_queue) - eth->change_tail = NULL; - store = head->data; - g_slist_free_1 (head); - if (column) - *column = store->column; - if (width) - *width = store->width; - g_free (store); -} - -static gboolean -dequeue_idle (ETableHeader *eth) -{ - gint column, width; - - dequeue (eth, &column, &width); - while (eth->change_queue && ((struct two_ints *) - eth->change_queue->data)->column == column) - dequeue (eth, &column, &width); - - if (column == -1) - eth_set_width (eth, width); - else if (column < eth->col_count) - eth_set_size (eth, column, width); - if (eth->change_queue) - return TRUE; - else { - eth_calc_widths (eth); - eth->idle = 0; - return FALSE; - } -} - -static void -enqueue (ETableHeader *eth, - gint column, - gint width) -{ - struct two_ints *store; - store = g_new (struct two_ints, 1); - store->column = column; - store->width = width; - - eth->change_tail = g_slist_last (g_slist_append (eth->change_tail, store)); - if (!eth->change_queue) - eth->change_queue = eth->change_tail; - - if (!eth->idle) { - eth->idle = g_idle_add_full ( - G_PRIORITY_LOW, (GSourceFunc) - dequeue_idle, eth, NULL); - } -} - -void -e_table_header_set_size (ETableHeader *eth, - gint idx, - gint size) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - - enqueue (eth, idx, size); -} - -static void -eth_do_remove (ETableHeader *eth, - gint idx, - gboolean do_unref) -{ - if (do_unref) - g_object_unref (eth->columns[idx]); - - memmove ( - ð->columns[idx], ð->columns[idx + 1], - sizeof (ETableCol *) * (eth->col_count - idx - 1)); - eth->col_count--; -} - -static void -eth_finalize (GObject *object) -{ - ETableHeader *eth = E_TABLE_HEADER (object); - const gint cols = eth->col_count; - gint i; - - if (eth->sort_info) { - if (eth->sort_info_group_change_id) - g_signal_handler_disconnect ( - eth->sort_info, - eth->sort_info_group_change_id); - g_object_unref (eth->sort_info); - eth->sort_info = NULL; - } - - if (eth->idle) - g_source_remove (eth->idle); - eth->idle = 0; - - if (eth->change_queue) { - g_slist_foreach (eth->change_queue, (GFunc) g_free, NULL); - g_slist_free (eth->change_queue); - eth->change_queue = NULL; - } - - /* - * Destroy columns - */ - for (i = cols - 1; i >= 0; i--) { - eth_do_remove (eth, i, TRUE); - } - g_free (eth->columns); - - eth->col_count = 0; - eth->columns = NULL; - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_table_header_parent_class)->finalize (object); -} - -static void -eth_group_info_changed (ETableSortInfo *info, - ETableHeader *eth) -{ - enqueue (eth, -1, eth->nominal_width); -} - -static void -eth_set_property (GObject *object, - guint property_id, - const GValue *val, - GParamSpec *pspec) -{ - ETableHeader *eth = E_TABLE_HEADER (object); - - switch (property_id) { - case PROP_WIDTH: - eth->nominal_width = g_value_get_double (val); - enqueue (eth, -1, eth->nominal_width); - break; - case PROP_WIDTH_EXTRAS: - eth->width_extras = g_value_get_double (val); - enqueue (eth, -1, eth->nominal_width); - break; - case PROP_SORT_INFO: - if (eth->sort_info) { - if (eth->sort_info_group_change_id) - g_signal_handler_disconnect ( - eth->sort_info, - eth->sort_info_group_change_id); - g_object_unref (eth->sort_info); - } - eth->sort_info = E_TABLE_SORT_INFO (g_value_get_object (val)); - if (eth->sort_info) { - g_object_ref (eth->sort_info); - eth->sort_info_group_change_id = g_signal_connect ( - eth->sort_info, "group_info_changed", - G_CALLBACK (eth_group_info_changed), eth); - } - enqueue (eth, -1, eth->nominal_width); - break; - default: - break; - } -} - -static void -eth_get_property (GObject *object, - guint property_id, - GValue *val, - GParamSpec *pspec) -{ - ETableHeader *eth = E_TABLE_HEADER (object); - - switch (property_id) { - case PROP_SORT_INFO: - g_value_set_object (val, eth->sort_info); - break; - case PROP_WIDTH: - g_value_set_double (val, eth->nominal_width); - break; - case PROP_WIDTH_EXTRAS: - g_value_set_double (val, eth->width_extras); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_table_header_class_init (ETableHeaderClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->finalize = eth_finalize; - object_class->set_property = eth_set_property; - object_class->get_property = eth_get_property; - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", "Width", "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH_EXTRAS, - g_param_spec_double ( - "width_extras", - "Width of Extras", - "Width of Extras", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SORT_INFO, - g_param_spec_object ( - "sort_info", - "Sort Info", - "Sort Info", - E_TYPE_TABLE_SORT_INFO, - G_PARAM_READWRITE)); - - eth_signals[STRUCTURE_CHANGE] = g_signal_new ( - "structure_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableHeaderClass, structure_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - eth_signals[DIMENSION_CHANGE] = g_signal_new ( - "dimension_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableHeaderClass, dimension_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - eth_signals[EXPANSION_CHANGE] = g_signal_new ( - "expansion_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableHeaderClass, expansion_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - eth_signals[REQUEST_WIDTH] = g_signal_new ( - "request_width", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableHeaderClass, request_width), - (GSignalAccumulator) NULL, NULL, - e_marshal_INT__INT, - G_TYPE_INT, 1, - G_TYPE_INT); - - class->structure_change = NULL; - class->dimension_change = NULL; - class->expansion_change = NULL; - class->request_width = NULL; -} - -static void -e_table_header_init (ETableHeader *eth) -{ - eth->col_count = 0; - eth->width = 0; - - eth->sort_info = NULL; - eth->sort_info_group_change_id = 0; - - eth->columns = NULL; - - eth->change_queue = NULL; - eth->change_tail = NULL; - - eth->width_extras = 0; -} - -/** - * e_table_header_new: - * - * Returns: A new @ETableHeader object. - */ -ETableHeader * -e_table_header_new (void) -{ - - return g_object_new (E_TYPE_TABLE_HEADER, NULL); -} - -static void -eth_update_offsets (ETableHeader *eth) -{ - gint i; - gint x = 0; - - for (i = 0; i < eth->col_count; i++) { - ETableCol *etc = eth->columns[i]; - - etc->x = x; - x += etc->width; - } -} - -static void -eth_do_insert (ETableHeader *eth, - gint pos, - ETableCol *val) -{ - memmove ( - ð->columns[pos + 1], ð->columns[pos], - sizeof (ETableCol *) * (eth->col_count - pos)); - eth->columns[pos] = val; - eth->col_count++; -} - -/** - * e_table_header_add_column: - * @eth: the table header to add the column to. - * @tc: the ETableCol definition - * @pos: position where the ETableCol will go. - * - * This function adds the @tc ETableCol definition into the @eth ETableHeader - * at position @pos. This is the way you add new ETableCols to the - * ETableHeader. The header will assume ownership of the @tc; you should not - * unref it after you add it. - * - * This function will emit the "structure_change" signal on the @eth object. - * The ETableCol is assumed - */ -void -e_table_header_add_column (ETableHeader *eth, - ETableCol *tc, - gint pos) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - g_return_if_fail (tc != NULL); - g_return_if_fail (E_IS_TABLE_COL (tc)); - g_return_if_fail (pos >= -1 && pos <= eth->col_count); - - if (pos == -1) - pos = eth->col_count; - eth->columns = g_realloc ( - eth->columns, sizeof (ETableCol *) * (eth->col_count + 1)); - - /* - * We are the primary owners of the column - */ - g_object_ref (tc); - - eth_do_insert (eth, pos, tc); - - enqueue (eth, -1, eth->nominal_width); - g_signal_emit (eth, eth_signals[STRUCTURE_CHANGE], 0); -} - -/** - * e_table_header_get_column: - * @eth: the ETableHeader to query - * @column: the column inside the @eth. - * - * Returns: The ETableCol at @column in the @eth object - */ -ETableCol * -e_table_header_get_column (ETableHeader *eth, - gint column) -{ - g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); - - if (column < 0) - return NULL; - - if (column >= eth->col_count) - return NULL; - - return eth->columns[column]; -} - -/** - * e_table_header_get_column_by_col_id: - * @eth: the ETableHeader to query - * @col_id: the col_id to search for. - * - * Returns: The ETableCol with col_idx = @col_idx in the @eth object - */ -ETableCol * -e_table_header_get_column_by_col_idx (ETableHeader *eth, - gint col_idx) -{ - gint i; - g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); - - for (i = 0; i < eth->col_count; i++) { - if (eth->columns[i]->col_idx == col_idx) { - return eth->columns[i]; - } - } - - return NULL; -} - -/** - * e_table_header_count: - * @eth: the ETableHeader to query - * - * Returns: the number of columns in this ETableHeader. - */ -gint -e_table_header_count (ETableHeader *eth) -{ - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - return eth->col_count; -} - -/** - * e_table_header_index: - * @eth: the ETableHeader to query - * @col: the column to fetch. - * - * ETableHeaders contain the visual list of columns that the user will - * view. The visible columns will typically map to different columns - * in the ETableModel (because the user reordered the data for - * example). - * - * Returns: the column in the model that the @col column - * in the ETableHeader points to. */ -gint -e_table_header_index (ETableHeader *eth, - gint col) -{ - g_return_val_if_fail (eth != NULL, -1); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), -1); - g_return_val_if_fail (col >= 0 && col < eth->col_count, -1); - - return eth->columns[col]->col_idx; -} - -/** - * e_table_header_get_index_at: - * @eth: the ETableHeader to query - * @x_offset: a pixel count from the beginning of the ETableHeader - * - * This will return the ETableHeader column that would contain - * the @x_offset pixel. - * - * Returns: the column that contains pixel @x_offset, or -1 - * if no column inside this ETableHeader contains that pixel. - */ -gint -e_table_header_get_index_at (ETableHeader *eth, - gint x_offset) -{ - gint i, total; - - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - total = 0; - for (i = 0; i < eth->col_count; i++) { - total += eth->columns[i]->width; - - if (x_offset < total) - return i; - } - - return -1; -} - -/** - * e_table_header_get_columns: - * @eth: The ETableHeader to query - * - * Returns: A NULL terminated array of the ETableCols - * contained in the ETableHeader @eth. Note that every - * returned ETableCol in the array has been referenced, to release - * this information you need to g_free the buffer returned - * and you need to g_object_unref every element returned - */ -ETableCol ** -e_table_header_get_columns (ETableHeader *eth) -{ - ETableCol **ret; - gint i; - - g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); - - ret = g_new (ETableCol *, eth->col_count + 1); - memcpy (ret, eth->columns, sizeof (ETableCol *) * eth->col_count); - ret[eth->col_count] = NULL; - - for (i = 0; i < eth->col_count; i++) { - g_object_ref (ret[i]); - } - - return ret; -} - -/** - * e_table_header_get_selected: - * @eth: The ETableHeader to query - * - * Returns: The number of selected columns in the @eth object. - */ -gint -e_table_header_get_selected (ETableHeader *eth) -{ - gint i; - gint selected = 0; - - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - for (i = 0; i < eth->col_count; i++) { - if (eth->columns[i]->selected) - selected++; - } - - return selected; -} - -/** - * e_table_header_total_width: - * @eth: The ETableHeader to query - * - * Returns: the number of pixels used by the @eth object - * when rendered on screen - */ -gint -e_table_header_total_width (ETableHeader *eth) -{ - gint total, i; - - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - total = 0; - for (i = 0; i < eth->col_count; i++) - total += eth->columns[i]->width; - - return total; -} - -/** - * e_table_header_min_width: - * @eth: The ETableHeader to query - * - * Returns: the minimum number of pixels required by the @eth object. - **/ -gint -e_table_header_min_width (ETableHeader *eth) -{ - gint total, i; - - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - total = 0; - for (i = 0; i < eth->col_count; i++) - total += eth->columns[i]->min_width; - - return total; -} - -/** - * e_table_header_move: - * @eth: The ETableHeader to operate on. - * @source_index: the source column to move. - * @target_index: the target location for the column - * - * This function moves the column @source_index to @target_index - * inside the @eth ETableHeader. The signals "dimension_change" - * and "structure_change" will be emmited - */ -void -e_table_header_move (ETableHeader *eth, - gint source_index, - gint target_index) -{ - ETableCol *old; - - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - g_return_if_fail (source_index >= 0); - g_return_if_fail (target_index >= 0); - g_return_if_fail (source_index < eth->col_count); - - /* Can be moved beyond the last item. */ - g_return_if_fail (target_index < eth->col_count + 1); - - if (source_index < target_index) - target_index--; - - old = eth->columns[source_index]; - eth_do_remove (eth, source_index, FALSE); - eth_do_insert (eth, target_index, old); - eth_update_offsets (eth); - - g_signal_emit (eth, eth_signals[DIMENSION_CHANGE], 0, eth->width); - g_signal_emit (eth, eth_signals[STRUCTURE_CHANGE], 0); -} - -/** - * e_table_header_remove: - * @eth: The ETableHeader to operate on. - * @idx: the index to the column to be removed. - * - * Removes the column at @idx position in the ETableHeader @eth. - * This emmits the "structure_change" signal on the @eth object. - */ -void -e_table_header_remove (ETableHeader *eth, - gint idx) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - g_return_if_fail (idx >= 0); - g_return_if_fail (idx < eth->col_count); - - eth_do_remove (eth, idx, TRUE); - enqueue (eth, -1, eth->nominal_width); - g_signal_emit (eth, eth_signals[STRUCTURE_CHANGE], 0); -} - -/* - * FIXME: deprecated? - */ -void -e_table_header_set_selection (ETableHeader *eth, - gboolean allow_selection) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); -} - -static void -eth_set_size (ETableHeader *eth, - gint idx, - gint size) -{ - gdouble expansion; - gdouble old_expansion; - gint min_width; - gint left_width; - gint total_extra; - gint expandable_count; - gint usable_width; - gint i; - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - g_return_if_fail (idx >= 0); - g_return_if_fail (idx < eth->col_count); - - /* If this column is not resizable, don't do anything. */ - if (!eth->columns[idx]->resizable) - return; - - expansion = 0; - min_width = 0; - left_width = 0; - expandable_count = -1; - - /* Calculate usable area. */ - for (i = 0; i < idx; i++) { - left_width += eth->columns[i]->width; - } - /* - 1 to account for the last pixel border. */ - usable_width = eth->width - left_width - 1; - - if (eth->sort_info) - usable_width -= e_table_sort_info_grouping_get_count ( - eth->sort_info) * GROUP_INDENT; - - /* Calculate minimum_width of stuff on the right as well as - * total usable expansion on the right. - */ - for (; i < eth->col_count; i++) { - min_width += eth->columns[i]->min_width + eth->width_extras; - if (eth->columns[i]->resizable) { - expansion += eth->columns[i]->expansion; - expandable_count++; - } - } - /* If there's no room for anything, don't change. */ - if (expansion == 0) - return; - - /* (1) If none of the columns to the right are expandable, use - * all the expansion space in this column. - */ - if (expandable_count == 0) { - eth->columns[idx]->expansion = expansion; - for (i = idx + 1; i < eth->col_count; i++) { - eth->columns[i]->expansion = 0; - } - - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); - return; - } - - total_extra = usable_width - min_width; - /* If there's no extra space, set all expansions to 0. */ - if (total_extra <= 0) { - for (i = idx; i < eth->col_count; i++) { - eth->columns[i]->expansion = 0; - } - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); - return; - } - - /* If you try to resize smaller than the minimum width, it - * uses the minimum. */ - if (size < eth->columns[idx]->min_width + eth->width_extras) - size = eth->columns[idx]->min_width + eth->width_extras; - - /* If all the extra space will be used up in this column, use - * all the expansion and set all others to 0. - */ - if (size >= total_extra + eth->columns[idx]->min_width + eth->width_extras) { - eth->columns[idx]->expansion = expansion; - for (i = idx + 1; i < eth->col_count; i++) { - eth->columns[i]->expansion = 0; - } - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); - return; - } - - /* The old_expansion used by columns to the right. */ - old_expansion = expansion; - old_expansion -= eth->columns[idx]->expansion; - /* Set the new expansion so that it will generate the desired size. */ - eth->columns[idx]->expansion = - expansion * (((gdouble)(size - (eth->columns[idx]->min_width + - eth->width_extras))) / ((gdouble) total_extra)); - /* The expansion left for the columns on the right. */ - expansion -= eth->columns[idx]->expansion; - - /* (2) If the old columns to the right didn't have any - * expansion before, expand them evenly. old_expansion > 0 by - * expansion = SUM(i=idx to col_count -1, - * columns[i]->min_width) - columns[idx]->min_width) = - * SUM(non-negatives). - */ - if (old_expansion == 0) { - for (i = idx + 1; i < eth->col_count; i++) { - if (eth->columns[idx]->resizable) { - /* expandable_count != 0 by (1) */ - eth->columns[i]->expansion = expansion / expandable_count; - } - } - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); - return; - } - - for (i = idx + 1; i < eth->col_count; i++) { - if (eth->columns[idx]->resizable) { - /* old_expansion != 0 by (2) */ - eth->columns[i]->expansion *= expansion / old_expansion; - } - } - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); -} - -/** - * e_table_header_col_diff: - * @eth: the ETableHeader to query. - * @start_col: the starting column - * @end_col: the ending column. - * - * Computes the number of pixels between the columns @start_col and - * @end_col. - * - * Returns: the number of pixels between @start_col and @end_col on the - * @eth ETableHeader object - */ -gint -e_table_header_col_diff (ETableHeader *eth, - gint start_col, - gint end_col) -{ - gint total, col; - - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - if (start_col < 0) - start_col = 0; - if (end_col > eth->col_count) - end_col = eth->col_count; - - total = 0; - for (col = start_col; col < end_col; col++) { - - total += eth->columns[col]->width; - } - - return total; -} - -static void -eth_calc_widths (ETableHeader *eth) -{ - gint i; - gint extra; - gdouble expansion; - gint last_position = 0; - gdouble next_position = 0; - gint last_resizable = -1; - gint *widths; - gboolean changed; - - widths = g_new (int, eth->col_count); - - /* - 1 to account for the last pixel border. */ - extra = eth->width - 1; - expansion = 0; - for (i = 0; i < eth->col_count; i++) { - extra -= eth->columns[i]->min_width + eth->width_extras; - if (eth->columns[i]->resizable && eth->columns[i]->expansion > 0) - last_resizable = i; - expansion += eth->columns[i]->resizable ? eth->columns[i]->expansion : 0; - widths[i] = eth->columns[i]->min_width + eth->width_extras; - } - if (eth->sort_info) - extra -= e_table_sort_info_grouping_get_count (eth->sort_info) - * GROUP_INDENT; - if (expansion != 0 && extra > 0) { - for (i = 0; i < last_resizable; i++) { - next_position += - extra * (eth->columns[i]->resizable ? - eth->columns[i]->expansion : 0) / expansion; - widths[i] += next_position - last_position; - last_position = next_position; - } - widths[i] += extra - last_position; - } - - changed = FALSE; - - for (i = 0; i < eth->col_count; i++) { - if (eth->columns[i]->width != widths[i]) { - changed = TRUE; - eth->columns[i]->width = widths[i]; - } - } - g_free (widths); - if (changed) - g_signal_emit (eth, eth_signals[DIMENSION_CHANGE], 0, eth->width); - eth_update_offsets (eth); -} - -void -e_table_header_update_horizontal (ETableHeader *eth) -{ - gint i; - gint cols; - - cols = eth->col_count; - - for (i = 0; i < cols; i++) { - gint width = 0; - - g_signal_emit_by_name ( - eth, "request_width", i, &width); - eth->columns[i]->min_width = width + 10; - eth->columns[i]->expansion = 1; - } - enqueue (eth, -1, eth->nominal_width); - g_signal_emit (eth, eth_signals[EXPANSION_CHANGE], 0); -} - -gint -e_table_header_prioritized_column (ETableHeader *eth) -{ - gint best_model_col = 0; - gint best_priority; - gint i; - gint count; - - count = e_table_header_count (eth); - if (count == 0) - return -1; - best_priority = e_table_header_get_column (eth, 0)->priority; - best_model_col = e_table_header_get_column (eth, 0)->col_idx; - for (i = 1; i < count; i++) { - gint priority = e_table_header_get_column (eth, i)->priority; - if (priority > best_priority) { - best_priority = priority; - best_model_col = e_table_header_get_column (eth, i)->col_idx; - } - } - return best_model_col; -} - -ETableCol * -e_table_header_prioritized_column_selected (ETableHeader *eth, - ETableColCheckFunc check_func, - gpointer user_data) -{ - ETableCol *best_col = NULL; - gint best_priority = G_MININT; - gint i; - gint count; - - count = e_table_header_count (eth); - if (count == 0) - return NULL; - for (i = 1; i < count; i++) { - ETableCol *col = e_table_header_get_column (eth, i); - if (col) { - if ((best_col == NULL || col->priority > best_priority) - && check_func (col, user_data)) { - best_priority = col->priority; - best_col = col; - } - } - } - return best_col; -} diff --git a/widgets/table/e-table-header.h b/widgets/table/e-table-header.h deleted file mode 100644 index 1ac3016c8f..0000000000 --- a/widgets/table/e-table-header.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_COLUMN_H_ -#define _E_TABLE_COLUMN_H_ - -#include <gdk/gdk.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-col.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_HEADER \ - (e_table_header_get_type ()) -#define E_TABLE_HEADER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_HEADER, ETableHeader)) -#define E_TABLE_HEADER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_HEADER, ETableHeaderClass)) -#define E_IS_TABLE_HEADER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_HEADER)) -#define E_IS_TABLE_HEADER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_HEADER)) -#define E_TABLE_HEADER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_HEADER, ETableHeaderClass)) - -G_BEGIN_DECLS - -typedef struct _ETableHeader ETableHeader; -typedef struct _ETableHeaderClass ETableHeaderClass; - -typedef gboolean (*ETableColCheckFunc) (ETableCol *col, gpointer user_data); - -/* - * A Column header. - */ -struct _ETableHeader { - GObject parent; - - gint col_count; - gint width; - gint nominal_width; - gint width_extras; - - ETableSortInfo *sort_info; - gint sort_info_group_change_id; - - ETableCol **columns; - - GSList *change_queue, *change_tail; - gint idle; -}; - -struct _ETableHeaderClass { - GObjectClass parent_class; - - void (*structure_change) (ETableHeader *eth); - void (*dimension_change) (ETableHeader *eth, - gint width); - void (*expansion_change) (ETableHeader *eth); - gint (*request_width) (ETableHeader *eth, - gint col); -}; - -GType e_table_header_get_type (void) G_GNUC_CONST; -ETableHeader * e_table_header_new (void); - -void e_table_header_add_column (ETableHeader *eth, - ETableCol *tc, - gint pos); -ETableCol * e_table_header_get_column (ETableHeader *eth, - gint column); -ETableCol * e_table_header_get_column_by_col_idx - (ETableHeader *eth, - gint col_idx); -gint e_table_header_count (ETableHeader *eth); -gint e_table_header_index (ETableHeader *eth, - gint col); -gint e_table_header_get_index_at (ETableHeader *eth, - gint x_offset); -ETableCol ** e_table_header_get_columns (ETableHeader *eth); -gint e_table_header_get_selected (ETableHeader *eth); - -gint e_table_header_total_width (ETableHeader *eth); -gint e_table_header_min_width (ETableHeader *eth); -void e_table_header_move (ETableHeader *eth, - gint source_index, - gint target_index); -void e_table_header_remove (ETableHeader *eth, - gint idx); -void e_table_header_set_size (ETableHeader *eth, - gint idx, - gint size); -void e_table_header_set_selection (ETableHeader *eth, - gboolean allow_selection); -gint e_table_header_col_diff (ETableHeader *eth, - gint start_col, - gint end_col); - -void e_table_header_calc_widths (ETableHeader *eth); -GList * e_table_header_get_selected_indexes - (ETableHeader *eth); -void e_table_header_update_horizontal - (ETableHeader *eth); -gint e_table_header_prioritized_column - (ETableHeader *eth); -ETableCol * e_table_header_prioritized_column_selected - (ETableHeader *eth, - ETableColCheckFunc check_func, - gpointer user_data); - -G_END_DECLS - -#endif /* _E_TABLE_HEADER_H_ */ - diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c deleted file mode 100644 index ddf7d0ac62..0000000000 --- a/widgets/table/e-table-item.c +++ /dev/null @@ -1,4041 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-table-item.c - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@gnu.org> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ -/* - * TODO: - * Add a border to the thing, so that focusing works properly. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> - -#include "gal-a11y-e-table-item-factory.h" -#include "gal-a11y-e-table-item.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas.h" -#include "misc/e-canvas-utils.h" - -#include "e-cell.h" -#include "e-table-item.h" -#include "e-table-subset.h" - -/* workaround for avoiding API breakage */ -#define eti_get_type e_table_item_get_type -G_DEFINE_TYPE (ETableItem, eti, GNOME_TYPE_CANVAS_ITEM) - -#define FOCUSED_BORDER 2 - -#define d(x) - -#if d(!)0 -#define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x)), g_print ("%s: e_table_item_leave_edit\n", __FUNCTION__)) -#else -#define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x))) -#endif - -static void eti_check_cursor_bounds (ETableItem *eti); -static void eti_cancel_drag_due_to_model_change (ETableItem *eti); - -/* FIXME: Do an analysis of which cell functions are needed before - * realize and make sure that all of them are doable by all the cells - * and that all of the others are only done after realization. */ - -enum { - CURSOR_CHANGE, - CURSOR_ACTIVATED, - DOUBLE_CLICK, - RIGHT_CLICK, - CLICK, - KEY_PRESS, - START_DRAG, - STYLE_SET, - SELECTION_MODEL_REMOVED, - SELECTION_MODEL_ADDED, - LAST_SIGNAL -}; - -static guint eti_signals[LAST_SIGNAL] = { 0, }; - -enum { - PROP_0, - PROP_TABLE_HEADER, - PROP_TABLE_MODEL, - PROP_SELECTION_MODEL, - PROP_TABLE_ALTERNATING_ROW_COLORS, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - PROP_TABLE_VERTICAL_DRAW_GRID, - PROP_TABLE_DRAW_FOCUS, - PROP_CURSOR_MODE, - PROP_LENGTH_THRESHOLD, - PROP_CURSOR_ROW, - PROP_UNIFORM_ROW_HEIGHT, - - PROP_MINIMUM_WIDTH, - PROP_WIDTH, - PROP_HEIGHT -}; - -#define DOUBLE_CLICK_TIME 250 -#define TRIPLE_CLICK_TIME 500 - -static gint eti_get_height (ETableItem *eti); -static gint eti_row_height (ETableItem *eti, gint row); -static void e_table_item_focus (ETableItem *eti, gint col, gint row, GdkModifierType state); -static void eti_cursor_change (ESelectionModel *selection, gint row, gint col, ETableItem *eti); -static void eti_cursor_activated (ESelectionModel *selection, gint row, gint col, ETableItem *eti); -static void eti_selection_change (ESelectionModel *selection, ETableItem *eti); -static void eti_selection_row_change (ESelectionModel *selection, gint row, ETableItem *eti); -static void e_table_item_redraw_row (ETableItem *eti, gint row); - -#define ETI_SINGLE_ROW_HEIGHT(eti) ((eti)->uniform_row_height_cache != -1 ? (eti)->uniform_row_height_cache : eti_row_height((eti), -1)) -#define ETI_MULTIPLE_ROW_HEIGHT(eti,row) ((eti)->height_cache && (eti)->height_cache[(row)] != -1 ? (eti)->height_cache[(row)] : eti_row_height((eti),(row))) -#define ETI_ROW_HEIGHT(eti,row) ((eti)->uniform_row_height ? ETI_SINGLE_ROW_HEIGHT ((eti)) : ETI_MULTIPLE_ROW_HEIGHT((eti),(row))) - -/* tweak_hsv is a really tweaky function. it modifies its first argument, which - * should be the color you want tweaked. delta_h, delta_s and delta_v specify - * how much you want their respective channels modified (and in what direction). - * if it can't do the specified modification, it does it in the oppositon direction */ -static void -e_hsv_tweak (GdkColor *color, - gdouble delta_h, - gdouble delta_s, - gdouble delta_v) -{ - gdouble h, s, v, r, g, b; - - r = color->red / 65535.0f; - g = color->green / 65535.0f; - b = color->blue / 65535.0f; - - gtk_rgb_to_hsv (r, g, b, &h, &s, &v); - - if (h + delta_h < 0) { - h -= delta_h; - } else { - h += delta_h; - } - - if (s + delta_s < 0) { - s -= delta_s; - } else { - s += delta_s; - } - - if (v + delta_v < 0) { - v -= delta_v; - } else { - v += delta_v; - } - - gtk_hsv_to_rgb (h, s, v, &r, &g, &b); - - color->red = r * 65535.0f; - color->green = g * 65535.0f; - color->blue = b * 65535.0f; -} - -inline static gint -model_to_view_row (ETableItem *eti, - gint row) -{ - gint i; - if (row == -1) - return -1; - if (eti->uses_source_model) { - ETableSubset *etss = E_TABLE_SUBSET (eti->table_model); - if (eti->row_guess >= 0 && eti->row_guess < etss->n_map) { - if (etss->map_table[eti->row_guess] == row) { - return eti->row_guess; - } - } - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] == row) - return i; - } - return -1; - } else - return row; -} - -inline static gint -view_to_model_row (ETableItem *eti, - gint row) -{ - if (eti->uses_source_model) { - ETableSubset *etss = E_TABLE_SUBSET (eti->table_model); - if (row >= 0 && row < etss->n_map) { - eti->row_guess = row; - return etss->map_table[row]; - } else - return -1; - } else - return row; -} - -inline static gint -model_to_view_col (ETableItem *eti, - gint col) -{ - gint i; - if (col == -1) - return -1; - for (i = 0; i < eti->cols; i++) { - ETableCol *ecol = e_table_header_get_column (eti->header, i); - if (ecol->col_idx == col) - return i; - } - return -1; -} - -inline static gint -view_to_model_col (ETableItem *eti, - gint col) -{ - ETableCol *ecol = e_table_header_get_column (eti->header, col); - return ecol ? ecol->col_idx : -1; -} - -static void -grab_cancelled (ECanvas *canvas, - GnomeCanvasItem *item, - gpointer data) -{ - ETableItem *eti = data; - - eti->grab_cancelled = TRUE; -} - -inline static void -eti_grab (ETableItem *eti, - GdkDevice *device, - guint32 time) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - d (g_print ("%s: time: %d\n", __FUNCTION__, time)); - if (eti->grabbed_count == 0) { - GdkGrabStatus grab_status; - - eti->gtk_grabbed = FALSE; - eti->grab_cancelled = FALSE; - - grab_status = e_canvas_item_grab ( - E_CANVAS (item->canvas), - item, - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON2_MOTION_MASK | - GDK_BUTTON3_MOTION_MASK | - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, - device, time, - grab_cancelled, - eti); - - if (grab_status != GDK_GRAB_SUCCESS) { - d (g_print ("%s: gtk_grab_add\n", __FUNCTION__)); - gtk_grab_add (GTK_WIDGET (item->canvas)); - eti->gtk_grabbed = TRUE; - } - } - eti->grabbed_count++; -} - -inline static void -eti_ungrab (ETableItem *eti, - guint32 time) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - d (g_print ("%s: time: %d\n", __FUNCTION__, time)); - eti->grabbed_count--; - if (eti->grabbed_count == 0) { - if (eti->grab_cancelled) { - eti->grab_cancelled = FALSE; - } else { - if (eti->gtk_grabbed) { - d (g_print ("%s: gtk_grab_remove\n", __FUNCTION__)); - gtk_grab_remove (GTK_WIDGET (item->canvas)); - eti->gtk_grabbed = FALSE; - } - gnome_canvas_item_ungrab (item, time); - eti->grabbed_col = -1; - eti->grabbed_row = -1; - } - } -} - -inline static gboolean -eti_editing (ETableItem *eti) -{ - d (g_print ("%s: %s\n", __FUNCTION__, (eti->editing_col == -1) ? "false":"true")); - - if (eti->editing_col == -1) - return FALSE; - else - return TRUE; -} - -inline static GdkColor * -eti_get_cell_background_color (ETableItem *eti, - gint row, - gint col, - gboolean selected, - gboolean *allocatedp) -{ - ECellView *ecell_view = eti->cell_views[col]; - GtkWidget *canvas; - GdkColor *background, bg; - GtkStyle *style; - gchar *color_spec = NULL; - gboolean allocated = FALSE; - - canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - style = gtk_widget_get_style (canvas); - - if (selected) { - if (gtk_widget_has_focus (canvas)) - background = &style->bg[GTK_STATE_SELECTED]; - else - background = &style->bg[GTK_STATE_ACTIVE]; - } else { - background = &style->base[GTK_STATE_NORMAL]; - } - - color_spec = e_cell_get_bg_color (ecell_view, row); - - if (color_spec != NULL) { - if (gdk_color_parse (color_spec, &bg)) { - background = gdk_color_copy (&bg); - allocated = TRUE; - } - } - - if (eti->alternating_row_colors) { - if (row % 2) { - - } else { - if (!allocated) { - background = gdk_color_copy (background); - allocated = TRUE; - } - e_hsv_tweak (background, 0.0f, 0.0f, -0.07f); - } - } - if (allocatedp) - *allocatedp = allocated; - - return background; -} - -inline static GdkColor * -eti_get_cell_foreground_color (ETableItem *eti, - gint row, - gint col, - gboolean selected, - gboolean *allocated) -{ - GtkWidget *canvas; - GdkColor *foreground; - GtkStyle *style; - - canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - style = gtk_widget_get_style (canvas); - - if (allocated) - *allocated = FALSE; - - if (selected) { - if (gtk_widget_has_focus (canvas)) - foreground = &style->fg[GTK_STATE_SELECTED]; - else - foreground = &style->fg[GTK_STATE_ACTIVE]; - } else { - foreground = &style->text[GTK_STATE_NORMAL]; - } - - return foreground; -} - -static void -eti_free_save_state (ETableItem *eti) -{ - if (eti->save_row == -1 || - !eti->cell_views_realized) - return; - - e_cell_free_state ( - eti->cell_views[eti->save_col], view_to_model_col (eti, eti->save_col), - eti->save_col, eti->save_row, eti->save_state); - eti->save_row = -1; - eti->save_col = -1; - eti->save_state = NULL; -} - -/* - * During realization, we have to invoke the per-ecell realize routine - * (On our current setup, we have one e-cell per column. - * - * We might want to optimize this to only realize the unique e-cells: - * ie, a strings-only table, uses the same e-cell for every column, and - * we might want to avoid realizing each e-cell. - */ -static void -eti_realize_cell_views (ETableItem *eti) -{ - GnomeCanvasItem *item; - gint i; - - item = GNOME_CANVAS_ITEM (eti); - - if (eti->cell_views_realized) - return; - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - for (i = 0; i < eti->n_cells; i++) - e_cell_realize (eti->cell_views[i]); - eti->cell_views_realized = 1; -} - -static void -eti_attach_cell_views (ETableItem *eti) -{ - gint i; - - g_return_if_fail (eti->header); - g_return_if_fail (eti->table_model); - - /* this is just c&p from model pre change, but it fixes things */ - eti_cancel_drag_due_to_model_change (eti); - eti_check_cursor_bounds (eti); - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - eti->motion_row = -1; - eti->motion_col = -1; - - /* - * Now realize the various ECells - */ - eti->n_cells = eti->cols; - eti->cell_views = g_new (ECellView *, eti->n_cells); - - for (i = 0; i < eti->n_cells; i++) { - ETableCol *ecol = e_table_header_get_column (eti->header, i); - - eti->cell_views[i] = e_cell_new_view (ecol->ecell, eti->table_model, eti); - } - - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -/* - * During unrealization: we invoke every e-cell (one per column in the current - * setup) to dispose all X resources allocated - */ -static void -eti_unrealize_cell_views (ETableItem *eti) -{ - gint i; - - if (eti->cell_views_realized == 0) - return; - - eti_free_save_state (eti); - - for (i = 0; i < eti->n_cells; i++) - e_cell_unrealize (eti->cell_views[i]); - eti->cell_views_realized = 0; -} - -static void -eti_detach_cell_views (ETableItem *eti) -{ - gint i; - - eti_free_save_state (eti); - - for (i = 0; i < eti->n_cells; i++) { - e_cell_kill_view (eti->cell_views[i]); - eti->cell_views[i] = NULL; - } - - g_free (eti->cell_views); - eti->cell_views = NULL; - eti->n_cells = 0; -} - -static void -eti_bounds (GnomeCanvasItem *item, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2) -{ - cairo_matrix_t i2c; - ETableItem *eti = E_TABLE_ITEM (item); - - /* Wrong BBox's are the source of redraw nightmares */ - - *x1 = 0; - *y1 = 0; - *x2 = eti->width; - *y2 = eti->height; - - gnome_canvas_item_i2c_matrix (GNOME_CANVAS_ITEM (eti), &i2c); - gnome_canvas_matrix_transform_rect (&i2c, x1, y1, x2, y2); -} - -static void -eti_reflow (GnomeCanvasItem *item, - gint flags) -{ - ETableItem *eti = E_TABLE_ITEM (item); - - if (eti->needs_compute_height) { - gint new_height = eti_get_height (eti); - - if (new_height != eti->height) { - eti->height = new_height; - e_canvas_item_request_parent_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); - } - eti->needs_compute_height = 0; - } - if (eti->needs_compute_width) { - gint new_width = e_table_header_total_width (eti->header); - if (new_width != eti->width) { - eti->width = new_width; - e_canvas_item_request_parent_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); - } - eti->needs_compute_width = 0; - } -} - -/* - * GnomeCanvasItem::update method - */ -static void -eti_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - ETableItem *eti = E_TABLE_ITEM (item); - gdouble x1, x2, y1, y2; - - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update) - (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, i2c, flags); - - x1 = item->x1; - y1 = item->y1; - x2 = item->x2; - y2 = item->y2; - - eti_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2); - if (item->x1 != x1 || - item->y1 != y1 || - item->x2 != x2 || - item->y2 != y2) { - gnome_canvas_request_redraw (item->canvas, x1, y1, x2, y2); - eti->needs_redraw = 1; - } - - if (eti->needs_redraw) { - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, - item->x2, item->y2); - eti->needs_redraw = 0; - } -} - -/* - * eti_remove_table_model: - * - * Invoked to release the table model associated with this ETableItem - */ -static void -eti_remove_table_model (ETableItem *eti) -{ - if (!eti->table_model) - return; - - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_pre_change_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_no_change_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_change_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_row_change_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_cell_change_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_rows_inserted_id); - g_signal_handler_disconnect ( - eti->table_model, - eti->table_model_rows_deleted_id); - g_object_unref (eti->table_model); - if (eti->source_model) - g_object_unref (eti->source_model); - - eti->table_model_pre_change_id = 0; - eti->table_model_no_change_id = 0; - eti->table_model_change_id = 0; - eti->table_model_row_change_id = 0; - eti->table_model_cell_change_id = 0; - eti->table_model_rows_inserted_id = 0; - eti->table_model_rows_deleted_id = 0; - eti->table_model = NULL; - eti->source_model = NULL; - eti->uses_source_model = 0; -} - -/* - * eti_remove_table_model: - * - * Invoked to release the table model associated with this ETableItem - */ -static void -eti_remove_selection_model (ETableItem *eti) -{ - if (!eti->selection) - return; - - g_signal_handler_disconnect ( - eti->selection, - eti->selection_change_id); - g_signal_handler_disconnect ( - eti->selection, - eti->selection_row_change_id); - g_signal_handler_disconnect ( - eti->selection, - eti->cursor_change_id); - g_signal_handler_disconnect ( - eti->selection, - eti->cursor_activated_id); - g_object_unref (eti->selection); - - eti->selection_change_id = 0; - eti->selection_row_change_id = 0; - eti->cursor_activated_id = 0; - eti->selection = NULL; -} - -/* - * eti_remove_header_model: - * - * Invoked to release the header model associated with this ETableItem - */ -static void -eti_remove_header_model (ETableItem *eti) -{ - if (!eti->header) - return; - - g_signal_handler_disconnect ( - eti->header, - eti->header_structure_change_id); - g_signal_handler_disconnect ( - eti->header, - eti->header_dim_change_id); - g_signal_handler_disconnect ( - eti->header, - eti->header_request_width_id); - - if (eti->cell_views) { - eti_unrealize_cell_views (eti); - eti_detach_cell_views (eti); - } - g_object_unref (eti->header); - - eti->header_structure_change_id = 0; - eti->header_dim_change_id = 0; - eti->header_request_width_id = 0; - eti->header = NULL; -} - -/* - * eti_row_height_real: - * - * Returns the height used by row @row. This does not include the one-pixel - * used as a separator between rows - */ -static gint -eti_row_height_real (ETableItem *eti, - gint row) -{ - const gint cols = e_table_header_count (eti->header); - gint col; - gint h, max_h; - - g_return_val_if_fail (cols == 0 || eti->cell_views, 0); - - max_h = 0; - - for (col = 0; col < cols; col++) { - h = e_cell_height (eti->cell_views[col], view_to_model_col (eti, col), col, row); - - if (h > max_h) - max_h = h; - } - return max_h; -} - -static void -confirm_height_cache (ETableItem *eti) -{ - gint i; - - if (eti->uniform_row_height || eti->height_cache) - return; - eti->height_cache = g_new (int, eti->rows); - for (i = 0; i < eti->rows; i++) { - eti->height_cache[i] = -1; - } -} - -static gboolean -height_cache_idle (ETableItem *eti) -{ - gint changed = 0; - gint i; - confirm_height_cache (eti); - for (i = eti->height_cache_idle_count; i < eti->rows; i++) { - if (eti->height_cache[i] == -1) { - eti_row_height (eti, i); - changed++; - if (changed >= 20) - break; - } - } - if (changed >= 20) { - eti->height_cache_idle_count = i; - return TRUE; - } - eti->height_cache_idle_id = 0; - return FALSE; -} - -static void -free_height_cache (ETableItem *eti) -{ - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (eti); - - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) { - if (eti->height_cache) - g_free (eti->height_cache); - eti->height_cache = NULL; - eti->height_cache_idle_count = 0; - eti->uniform_row_height_cache = -1; - - if (eti->uniform_row_height && eti->height_cache_idle_id != 0) { - g_source_remove (eti->height_cache_idle_id); - eti->height_cache_idle_id = 0; - } - - if ((!eti->uniform_row_height) && eti->height_cache_idle_id == 0) - eti->height_cache_idle_id = g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc) height_cache_idle, eti, NULL); - } -} - -static void -calculate_height_cache (ETableItem *eti) -{ - free_height_cache (eti); - confirm_height_cache (eti); -} - -/* - * eti_row_height: - * - * Returns the height used by row @row. This does not include the one-pixel - * used as a separator between rows - */ -static gint -eti_row_height (ETableItem *eti, - gint row) -{ - if (eti->uniform_row_height) { - eti->uniform_row_height_cache = eti_row_height_real (eti, -1); - return eti->uniform_row_height_cache; - } else { - if (!eti->height_cache) { - calculate_height_cache (eti); - } - if (eti->height_cache[row] == -1) { - eti->height_cache[row] = eti_row_height_real (eti, row); - if (row > 0 && - eti->length_threshold != -1 && - eti->rows > eti->length_threshold && - eti->height_cache[row] != eti_row_height (eti, 0)) { - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - } - } - return eti->height_cache[row]; - } -} - -/* - * eti_get_height: - * - * Returns the height of the ETableItem. - * - * The ETableItem might compute the whole height by asking every row its - * size. There is a special mode (designed to work when there are too - * many rows in the table that performing the previous step could take - * too long) set by the ETableItem->length_threshold that would determine - * when the height is computed by using the first row as the size for - * every other row in the ETableItem. - */ -static gint -eti_get_height (ETableItem *eti) -{ - const gint rows = eti->rows; - gint height_extra = eti->horizontal_draw_grid ? 1 : 0; - - if (rows == 0) - return 0; - - if (eti->uniform_row_height) { - gint row_height = ETI_ROW_HEIGHT (eti, -1); - return ((row_height + height_extra) * rows + height_extra); - } else { - gint height; - gint row; - if (eti->length_threshold != -1) { - if (rows > eti->length_threshold) { - gint row_height = ETI_ROW_HEIGHT (eti, 0); - if (eti->height_cache) { - height = 0; - for (row = 0; row < rows; row++) { - if (eti->height_cache[row] == -1) { - height += (row_height + height_extra) * (rows - row); - break; - } - else - height += eti->height_cache[row] + height_extra; - } - } else - height = (ETI_ROW_HEIGHT (eti, 0) + height_extra) * rows; - - /* - * 1 pixel at the top - */ - return height + height_extra; - } - } - - height = height_extra; - for (row = 0; row < rows; row++) - height += ETI_ROW_HEIGHT (eti, row) + height_extra; - - return height; - } -} - -static void -eti_item_region_redraw (ETableItem *eti, - gint x0, - gint y0, - gint x1, - gint y1) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - gdouble dx1, dy1, dx2, dy2; - cairo_matrix_t i2c; - - dx1 = x0; - dy1 = y0; - dx2 = x1; - dy2 = y1; - - gnome_canvas_item_i2c_matrix (item, &i2c); - gnome_canvas_matrix_transform_rect (&i2c, &dx1, &dy1, &dx2, &dy2); - - gnome_canvas_request_redraw (item->canvas, floor (dx1), floor (dy1), ceil (dx2), ceil (dy2)); -} - -/* - * Computes the distance between @start_row and @end_row in pixels - */ -gint -e_table_item_row_diff (ETableItem *eti, - gint start_row, - gint end_row) -{ - gint height_extra = eti->horizontal_draw_grid ? 1 : 0; - - if (start_row < 0) - start_row = 0; - if (end_row > eti->rows) - end_row = eti->rows; - - if (eti->uniform_row_height) { - return ((end_row - start_row) * (ETI_ROW_HEIGHT (eti, -1) + height_extra)); - } else { - gint row, total; - total = 0; - for (row = start_row; row < end_row; row++) - total += ETI_ROW_HEIGHT (eti, row) + height_extra; - - return total; - } -} - -static void -eti_get_region (ETableItem *eti, - gint start_col, - gint start_row, - gint end_col, - gint end_row, - gint *x1p, - gint *y1p, - gint *x2p, - gint *y2p) -{ - gint x1, y1, x2, y2; - - x1 = e_table_header_col_diff (eti->header, 0, start_col); - y1 = e_table_item_row_diff (eti, 0, start_row); - x2 = x1 + e_table_header_col_diff (eti->header, start_col, end_col + 1); - y2 = y1 + e_table_item_row_diff (eti, start_row, end_row + 1); - if (x1p) - *x1p = x1; - if (y1p) - *y1p = y1; - if (x2p) - *x2p = x2; - if (y2p) - *y2p = y2; -} - -/* - * eti_request_region_redraw: - * - * Request a canvas redraw on the range (start_col, start_row) to (end_col, end_row). - * This is inclusive (ie, you can use: 0,0-0,0 to redraw the first cell). - * - * The @border argument is a number of pixels around the region that should also be queued - * for redraw. This is typically used by the focus routines to queue a redraw for the - * border as well. - */ -static void -eti_request_region_redraw (ETableItem *eti, - gint start_col, - gint start_row, - gint end_col, - gint end_row, - gint border) -{ - gint x1, y1, x2, y2; - - if (eti->rows > 0) { - - eti_get_region ( - eti, - start_col, start_row, - end_col, end_row, - &x1, &y1, &x2, &y2); - - eti_item_region_redraw ( - eti, - x1 - border, - y1 - border, - x2 + 1 + border, - y2 + 1 + border); - } -} - -/* - * eti_request_region_show - * - * Request a canvas show on the range (start_col, start_row) to (end_col, end_row). - * This is inclusive (ie, you can use: 0,0-0,0 to show the first cell). - */ -static void -eti_request_region_show (ETableItem *eti, - gint start_col, - gint start_row, - gint end_col, - gint end_row, - gint delay) -{ - gint x1, y1, x2, y2; - - eti_get_region ( - eti, - start_col, start_row, - end_col, end_row, - &x1, &y1, &x2, &y2); - - if (delay) - e_canvas_item_show_area_delayed ( - GNOME_CANVAS_ITEM (eti), x1, y1, x2, y2, delay); - else - e_canvas_item_show_area ( - GNOME_CANVAS_ITEM (eti), x1, y1, x2, y2); -} - -static void -eti_show_cursor (ETableItem *eti, - gint delay) -{ - GnomeCanvasItem *item; - gint cursor_row; - - item = GNOME_CANVAS_ITEM (eti); - - if (!((item->flags & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized)) - return; - - if (eti->frozen_count > 0) { - eti->queue_show_cursor = TRUE; - return; - } - -#if 0 - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - NULL); -#else - cursor_row = e_selection_model_cursor_row (eti->selection); -#endif - - d (g_print ("%s: cursor row: %d\n", __FUNCTION__, cursor_row)); - - if (cursor_row != -1) { - cursor_row = model_to_view_row (eti, cursor_row); - eti_request_region_show ( - eti, - 0, cursor_row, eti->cols - 1, cursor_row, - delay); - } -} - -static void -eti_check_cursor_bounds (ETableItem *eti) -{ - GnomeCanvasItem *item; - gint x1, y1, x2, y2; - gint cursor_row; - - item = GNOME_CANVAS_ITEM (eti); - - if (!((item->flags & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized)) - return; - - if (eti->frozen_count > 0) { - return; - } - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - NULL); - - if (cursor_row == -1) { - eti->cursor_x1 = -1; - eti->cursor_y1 = -1; - eti->cursor_x2 = -1; - eti->cursor_y2 = -1; - eti->cursor_on_screen = TRUE; - return; - } - - d (g_print ("%s: model cursor row: %d\n", __FUNCTION__, cursor_row)); - - cursor_row = model_to_view_row (eti, cursor_row); - - d (g_print ("%s: cursor row: %d\n", __FUNCTION__, cursor_row)); - - eti_get_region ( - eti, - 0, cursor_row, eti->cols - 1, cursor_row, - &x1, &y1, &x2, &y2); - eti->cursor_x1 = x1; - eti->cursor_y1 = y1; - eti->cursor_x2 = x2; - eti->cursor_y2 = y2; - eti->cursor_on_screen = e_canvas_item_area_shown (GNOME_CANVAS_ITEM (eti), x1, y1, x2, y2); - - d (g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE")); -} - -static void -eti_maybe_show_cursor (ETableItem *eti, - gint delay) -{ - d (g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE")); - if (eti->cursor_on_screen) - eti_show_cursor (eti, delay); - eti_check_cursor_bounds (eti); -} - -static gboolean -eti_idle_show_cursor_cb (gpointer data) -{ - ETableItem *eti = data; - - if (eti->selection) { - eti_show_cursor (eti, 0); - eti_check_cursor_bounds (eti); - } - - eti->cursor_idle_id = 0; - g_object_unref (eti); - return FALSE; -} - -static void -eti_idle_maybe_show_cursor (ETableItem *eti) -{ - d (g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE")); - if (eti->cursor_on_screen) { - g_object_ref (eti); - if (!eti->cursor_idle_id) - eti->cursor_idle_id = g_idle_add (eti_idle_show_cursor_cb, eti); - } -} - -static void -eti_cancel_drag_due_to_model_change (ETableItem *eti) -{ - if (eti->maybe_in_drag) { - eti->maybe_in_drag = FALSE; - if (!eti->maybe_did_something) - e_selection_model_do_something (E_SELECTION_MODEL (eti->selection), eti->drag_row, eti->drag_col, eti->drag_state); - } - if (eti->in_drag) { - eti->in_drag = FALSE; - } -} - -static void -eti_freeze (ETableItem *eti) -{ - eti->frozen_count++; - d (g_print ("%s: %d\n", __FUNCTION__, eti->frozen_count)); -} - -static void -eti_unfreeze (ETableItem *eti) -{ - if (eti->frozen_count <= 0) - return; - - eti->frozen_count--; - d (g_print ("%s: %d\n", __FUNCTION__, eti->frozen_count)); - if (eti->frozen_count == 0 && eti->queue_show_cursor) { - eti_show_cursor (eti, 0); - eti_check_cursor_bounds (eti); - eti->queue_show_cursor = FALSE; - } -} - -/* - * Callback routine: invoked before the ETableModel suffers a change - */ -static void -eti_table_model_pre_change (ETableModel *table_model, - ETableItem *eti) -{ - eti_cancel_drag_due_to_model_change (eti); - eti_check_cursor_bounds (eti); - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - eti->motion_row = -1; - eti->motion_col = -1; - eti_freeze (eti); -} - -/* - * Callback routine: invoked when the ETableModel has not suffered a change - */ -static void -eti_table_model_no_change (ETableModel *table_model, - ETableItem *eti) -{ - eti_unfreeze (eti); -} - -/* - * Callback routine: invoked when the ETableModel has suffered a change - */ - -static void -eti_table_model_changed (ETableModel *table_model, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) { - eti_unfreeze (eti); - return; - } - - eti->rows = e_table_model_row_count (eti->table_model); - - free_height_cache (eti); - - eti_unfreeze (eti); - - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); - - eti_idle_maybe_show_cursor (eti); -} - -static void -eti_table_model_row_changed (ETableModel *table_model, - gint row, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) { - eti_unfreeze (eti); - return; - } - - if ((!eti->uniform_row_height) && eti->height_cache && eti->height_cache[row] != -1 && eti_row_height_real (eti, row) != eti->height_cache[row]) { - eti_table_model_changed (table_model, eti); - return; - } - - eti_unfreeze (eti); - - e_table_item_redraw_row (eti, row); -} - -static void -eti_table_model_cell_changed (ETableModel *table_model, - gint col, - gint row, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) { - eti_unfreeze (eti); - return; - } - - if ((!eti->uniform_row_height) && eti->height_cache && eti->height_cache[row] != -1 && eti_row_height_real (eti, row) != eti->height_cache[row]) { - eti_table_model_changed (table_model, eti); - return; - } - - eti_unfreeze (eti); - - e_table_item_redraw_row (eti, row); -} - -static void -eti_table_model_rows_inserted (ETableModel *table_model, - gint row, - gint count, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) { - eti_unfreeze (eti); - return; - } - eti->rows = e_table_model_row_count (eti->table_model); - - if (eti->height_cache) { - gint i; - eti->height_cache = g_renew (int, eti->height_cache, eti->rows); - memmove (eti->height_cache + row + count, eti->height_cache + row, (eti->rows - count - row) * sizeof (gint)); - for (i = row; i < row + count; i++) - eti->height_cache[i] = -1; - } - - eti_unfreeze (eti); - - eti_idle_maybe_show_cursor (eti); - - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -static void -eti_table_model_rows_deleted (ETableModel *table_model, - gint row, - gint count, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) { - eti_unfreeze (eti); - return; - } - - eti->rows = e_table_model_row_count (eti->table_model); - - if (eti->height_cache && (eti->rows > row)) { - memmove (eti->height_cache + row, eti->height_cache + row + count, (eti->rows - row) * sizeof (gint)); - } - - eti_unfreeze (eti); - - eti_idle_maybe_show_cursor (eti); - - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -/** - * e_table_item_redraw_range - * @eti: %ETableItem which will be redrawn - * @start_col: The first col to redraw. - * @start_row: The first row to redraw. - * @end_col: The last col to redraw. - * @end_row: The last row to redraw. - * - * This routine redraws the given %ETableItem in the range given. The - * range is inclusive at both ends. - */ -void -e_table_item_redraw_range (ETableItem *eti, - gint start_col, - gint start_row, - gint end_col, - gint end_row) -{ - gint border; - gint cursor_col, cursor_row; - - g_return_if_fail (eti != NULL); - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - "cursor_row", &cursor_row, - NULL); - - if ((start_col == cursor_col) || - (end_col == cursor_col) || - (view_to_model_row (eti, start_row) == cursor_row) || - (view_to_model_row (eti, end_row) == cursor_row)) - border = 2; - else - border = 0; - - eti_request_region_redraw (eti, start_col, start_row, end_col, end_row, border); -} - -static void -e_table_item_redraw_row (ETableItem *eti, - gint row) -{ - if (row != -1) - e_table_item_redraw_range (eti, 0, row, eti->cols - 1, row); -} - -static void -eti_add_table_model (ETableItem *eti, - ETableModel *table_model) -{ - g_return_if_fail (eti->table_model == NULL); - - eti->table_model = table_model; - g_object_ref (eti->table_model); - - eti->table_model_pre_change_id = g_signal_connect ( - table_model, "model_pre_change", - G_CALLBACK (eti_table_model_pre_change), eti); - - eti->table_model_no_change_id = g_signal_connect ( - table_model, "model_no_change", - G_CALLBACK (eti_table_model_no_change), eti); - - eti->table_model_change_id = g_signal_connect ( - table_model, "model_changed", - G_CALLBACK (eti_table_model_changed), eti); - - eti->table_model_row_change_id = g_signal_connect ( - table_model, "model_row_changed", - G_CALLBACK (eti_table_model_row_changed), eti); - - eti->table_model_cell_change_id = g_signal_connect ( - table_model, "model_cell_changed", - G_CALLBACK (eti_table_model_cell_changed), eti); - - eti->table_model_rows_inserted_id = g_signal_connect ( - table_model, "model_rows_inserted", - G_CALLBACK (eti_table_model_rows_inserted), eti); - - eti->table_model_rows_deleted_id = g_signal_connect ( - table_model, "model_rows_deleted", - G_CALLBACK (eti_table_model_rows_deleted), eti); - - if (eti->header) { - eti_detach_cell_views (eti); - eti_attach_cell_views (eti); - } - - if (E_IS_TABLE_SUBSET (table_model)) { - eti->uses_source_model = 1; - eti->source_model = E_TABLE_SUBSET (table_model)->source; - if (eti->source_model) - g_object_ref (eti->source_model); - } - - eti_freeze (eti); - - eti_table_model_changed (table_model, eti); -} - -static void -eti_add_selection_model (ETableItem *eti, - ESelectionModel *selection) -{ - g_return_if_fail (eti->selection == NULL); - - eti->selection = selection; - g_object_ref (eti->selection); - - eti->selection_change_id = g_signal_connect ( - selection, "selection_changed", - G_CALLBACK (eti_selection_change), eti); - - eti->selection_row_change_id = g_signal_connect ( - selection, "selection_row_changed", - G_CALLBACK (eti_selection_row_change), eti); - - eti->cursor_change_id = g_signal_connect ( - selection, "cursor_changed", - G_CALLBACK (eti_cursor_change), eti); - - eti->cursor_activated_id = g_signal_connect ( - selection, "cursor_activated", - G_CALLBACK (eti_cursor_activated), eti); - - eti_selection_change (selection, eti); - g_signal_emit_by_name (eti, "selection_model_added", eti->selection); -} - -static void -eti_header_dim_changed (ETableHeader *eth, - gint col, - ETableItem *eti) -{ - eti->needs_compute_width = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -static void -eti_header_structure_changed (ETableHeader *eth, - ETableItem *eti) -{ - eti->cols = e_table_header_count (eti->header); - - /* - * There should be at least one column - * BUT: then you can't remove all columns from a header and add new ones. - */ - - if (eti->cell_views) { - eti_unrealize_cell_views (eti); - eti_detach_cell_views (eti); - eti_attach_cell_views (eti); - eti_realize_cell_views (eti); - } else { - if (eti->table_model) { - eti_attach_cell_views (eti); - eti_realize_cell_views (eti); - } - } - eti->needs_compute_width = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -static gint -eti_request_column_width (ETableHeader *eth, - gint col, - ETableItem *eti) -{ - gint width = 0; - - if (eti->cell_views && eti->cell_views_realized) { - width = e_cell_max_width (eti->cell_views[col], view_to_model_col (eti, col), col); - } - - return width; -} - -static void -eti_add_header_model (ETableItem *eti, - ETableHeader *header) -{ - g_return_if_fail (eti->header == NULL); - - eti->header = header; - g_object_ref (header); - - eti_header_structure_changed (header, eti); - - eti->header_dim_change_id = g_signal_connect ( - header, "dimension_change", - G_CALLBACK (eti_header_dim_changed), eti); - - eti->header_structure_change_id = g_signal_connect ( - header, "structure_change", - G_CALLBACK (eti_header_structure_changed), eti); - - eti->header_request_width_id = g_signal_connect ( - header, "request_width", - G_CALLBACK (eti_request_column_width), eti); -} - -/* - * GObject::dispose method - */ -static void -eti_dispose (GObject *object) -{ - ETableItem *eti = E_TABLE_ITEM (object); - - eti_remove_header_model (eti); - eti_remove_table_model (eti); - eti_remove_selection_model (eti); - - if (eti->height_cache_idle_id) { - g_source_remove (eti->height_cache_idle_id); - eti->height_cache_idle_id = 0; - } - eti->height_cache_idle_count = 0; - - if (eti->cursor_idle_id) { - g_source_remove (eti->cursor_idle_id); - eti->cursor_idle_id = 0; - } - - if (eti->height_cache) - g_free (eti->height_cache); - eti->height_cache = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (eti_parent_class)->dispose (object); -} - -static void -eti_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object); - ETableItem *eti = E_TABLE_ITEM (object); - gint cursor_col; - - switch (property_id) { - case PROP_TABLE_HEADER: - eti_remove_header_model (eti); - eti_add_header_model (eti, E_TABLE_HEADER (g_value_get_object (value))); - break; - - case PROP_TABLE_MODEL: - eti_remove_table_model (eti); - eti_add_table_model (eti, E_TABLE_MODEL (g_value_get_object (value))); - break; - - case PROP_SELECTION_MODEL: - g_signal_emit_by_name ( - eti, "selection_model_removed", eti->selection); - eti_remove_selection_model (eti); - if (g_value_get_object (value)) - eti_add_selection_model (eti, E_SELECTION_MODEL (g_value_get_object (value))); - break; - - case PROP_LENGTH_THRESHOLD: - eti->length_threshold = g_value_get_int (value); - break; - - case PROP_TABLE_ALTERNATING_ROW_COLORS: - eti->alternating_row_colors = g_value_get_boolean (value); - break; - - case PROP_TABLE_HORIZONTAL_DRAW_GRID: - eti->horizontal_draw_grid = g_value_get_boolean (value); - break; - - case PROP_TABLE_VERTICAL_DRAW_GRID: - eti->vertical_draw_grid = g_value_get_boolean (value); - break; - - case PROP_TABLE_DRAW_FOCUS: - eti->draw_focus = g_value_get_boolean (value); - break; - - case PROP_CURSOR_MODE: - eti->cursor_mode = g_value_get_int (value); - break; - - case PROP_MINIMUM_WIDTH: - case PROP_WIDTH: - if ((eti->minimum_width == eti->width && g_value_get_double (value) > eti->width) || - g_value_get_double (value) < eti->width) { - eti->needs_compute_width = 1; - e_canvas_item_request_reflow (item); - } - eti->minimum_width = g_value_get_double (value); - break; - case PROP_CURSOR_ROW: - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - NULL); - - e_table_item_focus (eti, cursor_col != -1 ? cursor_col : 0, view_to_model_row (eti, g_value_get_int (value)), 0); - break; - case PROP_UNIFORM_ROW_HEIGHT: - if (eti->uniform_row_height != g_value_get_boolean (value)) { - eti->uniform_row_height = g_value_get_boolean (value); - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) { - free_height_cache (eti); - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (item); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (item); - } - } - break; - } - eti->needs_redraw = 1; - gnome_canvas_item_request_update (item); -} - -static void -eti_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableItem *eti; - gint row; - - eti = E_TABLE_ITEM (object); - - switch (property_id) { - case PROP_WIDTH: - g_value_set_double (value, eti->width); - break; - case PROP_HEIGHT: - g_value_set_double (value, eti->height); - break; - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, eti->minimum_width); - break; - case PROP_CURSOR_ROW: - g_object_get ( - eti->selection, - "cursor_row", &row, - NULL); - g_value_set_int (value, model_to_view_row (eti, row)); - break; - case PROP_UNIFORM_ROW_HEIGHT: - g_value_set_boolean (value, eti->uniform_row_height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -eti_init (ETableItem *eti) -{ - eti->motion_row = -1; - eti->motion_col = -1; - eti->editing_col = -1; - eti->editing_row = -1; - eti->height = 0; - eti->width = 0; - eti->minimum_width = 0; - - eti->save_col = -1; - eti->save_row = -1; - eti->save_state = NULL; - - eti->click_count = 0; - - eti->height_cache = NULL; - eti->height_cache_idle_id = 0; - eti->height_cache_idle_count = 0; - - eti->length_threshold = -1; - eti->uniform_row_height = FALSE; - - eti->uses_source_model = 0; - eti->source_model = NULL; - - eti->row_guess = -1; - eti->cursor_mode = E_CURSOR_SIMPLE; - - eti->selection_change_id = 0; - eti->selection_row_change_id = 0; - eti->cursor_change_id = 0; - eti->cursor_activated_id = 0; - eti->selection = NULL; - - eti->old_cursor_row = -1; - - eti->needs_redraw = 0; - eti->needs_compute_height = 0; - - eti->in_key_press = 0; - - eti->maybe_did_something = TRUE; - - eti->grabbed_count = 0; - eti->gtk_grabbed = 0; - - eti->in_drag = 0; - eti->maybe_in_drag = 0; - eti->grabbed = 0; - - eti->grabbed_col = -1; - eti->grabbed_row = -1; - - eti->cursor_on_screen = FALSE; - eti->cursor_x1 = -1; - eti->cursor_y1 = -1; - eti->cursor_x2 = -1; - eti->cursor_y2 = -1; - - eti->rows = -1; - eti->cols = -1; - - eti->frozen_count = 0; - eti->queue_show_cursor = FALSE; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow); -} - -#define gray50_width 2 -#define gray50_height 2 -static const gchar gray50_bits[] = { - 0x02, 0x01, }; - -static gboolean -eti_tree_unfreeze (GtkWidget *widget, - GdkEvent *event, - ETableItem *eti) -{ - - if (widget) - g_object_set_data (G_OBJECT (widget), "freeze-cursor", NULL); - - return FALSE; -} - -static void -eti_realize (GnomeCanvasItem *item) -{ - ETableItem *eti = E_TABLE_ITEM (item); - - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->realize) - (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->realize)(item); - - eti->rows = e_table_model_row_count (eti->table_model); - - g_signal_connect ( - item->canvas, "scroll_event", - G_CALLBACK (eti_tree_unfreeze), eti); - - if (eti->cell_views == NULL) - eti_attach_cell_views (eti); - - eti_realize_cell_views (eti); - - free_height_cache (eti); - - if (item->canvas->focused_item == NULL && eti->selection) { - gint row; - - row = e_selection_model_cursor_row (E_SELECTION_MODEL (eti->selection)); - row = model_to_view_row (eti, row); - if (row != -1) { - e_canvas_item_grab_focus (item, FALSE); - eti_show_cursor (eti, 0); - eti_check_cursor_bounds (eti); - } - } - - eti->needs_compute_height = 1; - eti->needs_compute_width = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -static void -eti_unrealize (GnomeCanvasItem *item) -{ - ETableItem *eti = E_TABLE_ITEM (item); - - if (eti->grabbed_count > 0) { - d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (eti, -1); - } - - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - - if (eti->height_cache_idle_id) { - g_source_remove (eti->height_cache_idle_id); - eti->height_cache_idle_id = 0; - } - - if (eti->height_cache) - g_free (eti->height_cache); - eti->height_cache = NULL; - eti->height_cache_idle_count = 0; - - eti_unrealize_cell_views (eti); - - eti->height = 0; - - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item); -} - -static void -eti_draw_grid_line (ETableItem *eti, - cairo_t *cr, - GtkStyle *style, - gint x1, - gint y1, - gint x2, - gint y2) -{ - cairo_save (cr); - - cairo_set_line_width (cr, 1.0); - gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]); - - cairo_move_to (cr, x1 + 0.5, y1 + 0.5); - cairo_line_to (cr, x2 + 0.5, y2 + 0.5); - cairo_stroke (cr); - - cairo_restore (cr); -} - -static void -eti_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - ETableItem *eti = E_TABLE_ITEM (item); - const gint rows = eti->rows; - const gint cols = eti->cols; - gint row, col; - gint first_col, last_col, x_offset; - gint first_row, last_row, y_offset, yd; - gint x1, x2; - gint f_x1, f_x2, f_y1, f_y2; - gboolean f_found; - cairo_matrix_t i2c; - gdouble eti_base_x, eti_base_y, lower_right_y, lower_right_x; - GtkWidget *canvas = GTK_WIDGET (item->canvas); - GtkStyle *style = gtk_widget_get_style (canvas); - gint height_extra = eti->horizontal_draw_grid ? 1 : 0; - - /* - * Find out our real position after grouping - */ - gnome_canvas_item_i2c_matrix (item, &i2c); - eti_base_x = 0; - eti_base_y = 0; - cairo_matrix_transform_point (&i2c, &eti_base_x, &eti_base_y); - - lower_right_x = eti->width; - lower_right_y = eti->height; - cairo_matrix_transform_point (&i2c, &lower_right_x, &lower_right_y); - - /* - * First column to draw, last column to draw - */ - first_col = -1; - x_offset = 0; - x1 = floor (eti_base_x); - for (col = 0; col < cols; col++, x1 = x2) { - ETableCol *ecol = e_table_header_get_column (eti->header, col); - - x2 = x1 + ecol->width; - - if (x1 > (x + width)) - break; - if (x2 < x) - continue; - if (first_col == -1) { - x_offset = x1 - x; - first_col = col; - } - } - last_col = col; - - /* - * Nothing to paint - */ - if (first_col == -1) - return; - - /* - * Compute row span. - */ - if (eti->uniform_row_height) { - first_row = (y - floor (eti_base_y) - height_extra) / (ETI_ROW_HEIGHT (eti, -1) + height_extra); - last_row = (y + height - floor (eti_base_y) ) / (ETI_ROW_HEIGHT (eti, -1) + height_extra) + 1; - if (first_row > last_row) - return; - y_offset = floor (eti_base_y) - y + height_extra + first_row * (ETI_ROW_HEIGHT (eti, -1) + height_extra); - if (first_row < 0) - first_row = 0; - if (last_row > eti->rows) - last_row = eti->rows; - } else { - gint y1, y2; - - y_offset = 0; - first_row = -1; - - y1 = y2 = floor (eti_base_y) + height_extra; - for (row = 0; row < rows; row++, y1 = y2) { - - y2 += ETI_ROW_HEIGHT (eti, row) + height_extra; - - if (y1 > y + height) - break; - - if (y2 < y) - continue; - - if (first_row == -1) { - y_offset = y1 - y; - first_row = row; - } - } - last_row = row; - - if (first_row == -1) - return; - } - - if (first_row == -1) - return; - - /* - * Draw cells - */ - yd = y_offset; - f_x1 = f_x2 = f_y1 = f_y2 = -1; - f_found = FALSE; - - if (eti->horizontal_draw_grid && first_row == 0) - eti_draw_grid_line (eti, cr, style, eti_base_x - x, yd, eti_base_x + eti->width - x, yd); - - yd += height_extra; - - for (row = first_row; row < last_row; row++) { - gint xd; - gboolean selected; - gint cursor_col, cursor_row; - - height = ETI_ROW_HEIGHT (eti, row); - - xd = x_offset; - - selected = e_selection_model_is_row_selected (E_SELECTION_MODEL (eti->selection), view_to_model_row (eti,row)); - - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - "cursor_row", &cursor_row, - NULL); - - for (col = first_col; col < last_col; col++) { - ETableCol *ecol = e_table_header_get_column (eti->header, col); - ECellView *ecell_view = eti->cell_views[col]; - gboolean col_selected = selected; - gboolean cursor = FALSE; - ECellFlags flags; - gboolean free_background; - GdkColor *background; - gint x1, x2, y1, y2; - cairo_pattern_t *pat; - - switch (eti->cursor_mode) { - case E_CURSOR_SIMPLE: - case E_CURSOR_SPREADSHEET: - if (cursor_col == ecol->col_idx && cursor_row == view_to_model_row (eti, row)) { - col_selected = !col_selected; - cursor = TRUE; - } - break; - case E_CURSOR_LINE: - /* Nothing */ - break; - } - - x1 = xd; - y1 = yd + 1; - x2 = x1 + ecol->width; - y2 = yd + height; - - background = eti_get_cell_background_color (eti, row, col, col_selected, &free_background); - - cairo_save (cr); - pat = cairo_pattern_create_linear (0, y1, 0, y2); - cairo_pattern_add_color_stop_rgba ( - pat, 0.0, background->red / 65535.0 , - background->green / 65535.0, - background->blue / 65535.0, selected ? 0.8: 1.0); - if (selected) - cairo_pattern_add_color_stop_rgba ( - pat, 0.5, background->red / 65535.0 , - background->green / 65535.0, - background->blue / 65535.0, 0.9); - - cairo_pattern_add_color_stop_rgba ( - pat, 1, background->red / 65535.0 , - background->green / 65535.0, - background->blue / 65535.0, selected ? 0.8 : 1.0); - cairo_rectangle (cr, x1, y1, ecol->width, height - 1); - cairo_set_source (cr, pat); - cairo_fill_preserve (cr); - cairo_pattern_destroy (pat); - cairo_set_line_width (cr, 0); - cairo_stroke (cr); - cairo_restore (cr); - - cairo_save (cr); - cairo_set_line_width (cr, 1.0); - cairo_set_source_rgba ( - cr, background->red / 65535.0 , - background->green / 65535.0, - background->blue / 65535.0, 1); - cairo_move_to (cr, x1, y1); - cairo_line_to (cr, x2, y1); - cairo_stroke (cr); - - cairo_set_line_width (cr, 1.0); - cairo_set_source_rgba ( - cr, background->red / 65535.0 , - background->green / 65535.0, - background->blue / 65535.0, 1); - cairo_move_to (cr, x1, y2); - cairo_line_to (cr, x2, y2); - cairo_stroke (cr); - cairo_restore (cr); - - if (free_background) - gdk_color_free (background); - - flags = col_selected ? E_CELL_SELECTED : 0; - flags |= gtk_widget_has_focus (canvas) ? E_CELL_FOCUSED : 0; - flags |= cursor ? E_CELL_CURSOR : 0; - - switch (ecol->justification) { - case GTK_JUSTIFY_LEFT: - flags |= E_CELL_JUSTIFY_LEFT; - break; - case GTK_JUSTIFY_RIGHT: - flags |= E_CELL_JUSTIFY_RIGHT; - break; - case GTK_JUSTIFY_CENTER: - flags |= E_CELL_JUSTIFY_CENTER; - break; - case GTK_JUSTIFY_FILL: - flags |= E_CELL_JUSTIFY_FILL; - break; - } - - e_cell_draw ( - ecell_view, cr, ecol->col_idx, col, row, flags, - xd, yd, xd + ecol->width, yd + height); - - if (!f_found && !selected) { - switch (eti->cursor_mode) { - case E_CURSOR_LINE: - if (view_to_model_row (eti, row) == cursor_row) { - f_x1 = floor (eti_base_x) - x; - f_x2 = floor (lower_right_x) - x; - f_y1 = yd + 1; - f_y2 = yd + height; - f_found = TRUE; - } - break; - case E_CURSOR_SIMPLE: - case E_CURSOR_SPREADSHEET: - if (view_to_model_col (eti, col) == cursor_col && view_to_model_row (eti, row) == cursor_row) { - f_x1 = xd; - f_x2 = xd + ecol->width; - f_y1 = yd; - f_y2 = yd + height; - f_found = TRUE; - } - break; - } - } - - xd += ecol->width; - } - yd += height; - - if (eti->horizontal_draw_grid) { - eti_draw_grid_line (eti, cr, style, eti_base_x - x, yd, eti_base_x + eti->width - x, yd); - yd++; - } - } - - if (eti->vertical_draw_grid) { - gint xd = x_offset; - - for (col = first_col; col <= last_col; col++) { - ETableCol *ecol = e_table_header_get_column (eti->header, col); - - eti_draw_grid_line (eti, cr, style, xd, y_offset, xd, yd - 1); - - /* - * This looks wierd, but it is to draw the last line - */ - if (ecol) - xd += ecol->width; - } - } - - /* - * Draw focus - */ - if (eti->draw_focus && f_found) { - static const double dash[] = { 1.0, 1.0 }; - cairo_set_line_width (cr, 1.0); - cairo_rectangle ( - cr, - f_x1 + 0.5, f_x2 + 0.5, - f_x2 - f_x1 - 1, f_y2 - f_y1); - - gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]); - cairo_stroke_preserve (cr); - - cairo_set_dash (cr, dash, G_N_ELEMENTS (dash), 0.0); - gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]); - cairo_stroke (cr); - } -} - -static GnomeCanvasItem * -eti_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - return item; -} - -static gboolean -find_cell (ETableItem *eti, - gdouble x, - gdouble y, - gint *view_col_res, - gint *view_row_res, - gdouble *x1_res, - gdouble *y1_res) -{ - const gint cols = eti->cols; - const gint rows = eti->rows; - gdouble x1, y1, x2, y2; - gint col, row; - - gint height_extra = eti->horizontal_draw_grid ? 1 : 0; - - /* FIXME: this routine is inneficient, fix later */ - - if (eti->grabbed_col >= 0 && eti->grabbed_row >= 0) { - *view_col_res = eti->grabbed_col; - *view_row_res = eti->grabbed_row; - *x1_res = x - e_table_header_col_diff (eti->header, 0, eti->grabbed_col); - *y1_res = y - e_table_item_row_diff (eti, 0, eti->grabbed_row); - return TRUE; - } - - if (cols == 0 || rows == 0) - return FALSE; - - x1 = 0; - for (col = 0; col < cols - 1; col++, x1 = x2) { - ETableCol *ecol = e_table_header_get_column (eti->header, col); - - if (x < x1) - return FALSE; - - x2 = x1 + ecol->width; - - if (x <= x2) - break; - } - - if (eti->uniform_row_height) { - if (y < height_extra) - return FALSE; - row = (y - height_extra) / (ETI_ROW_HEIGHT (eti, -1) + height_extra); - y1 = row * (ETI_ROW_HEIGHT (eti, -1) + height_extra) + height_extra; - if (row >= eti->rows) - return FALSE; - } else { - y1 = y2 = height_extra; - if (y < height_extra) - return FALSE; - for (row = 0; row < rows; row++, y1 = y2) { - y2 += ETI_ROW_HEIGHT (eti, row) + height_extra; - - if (y <= y2) - break; - } - - if (row == rows) - return FALSE; - } - *view_col_res = col; - if (x1_res) - *x1_res = x - x1; - *view_row_res = row; - if (y1_res) - *y1_res = y - y1; - return TRUE; -} - -static void -eti_cursor_move (ETableItem *eti, - gint row, - gint column) -{ - e_table_item_leave_edit_(eti); - e_table_item_focus (eti, view_to_model_col (eti, column), view_to_model_row (eti, row), 0); -} - -static void -eti_cursor_move_left (ETableItem *eti) -{ - gint cursor_col, cursor_row; - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - "cursor_row", &cursor_row, - NULL); - - eti_cursor_move (eti, model_to_view_row (eti, cursor_row), model_to_view_col (eti, cursor_col) - 1); -} - -static void -eti_cursor_move_right (ETableItem *eti) -{ - gint cursor_col, cursor_row; - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - "cursor_row", &cursor_row, - NULL); - - eti_cursor_move (eti, model_to_view_row (eti, cursor_row), model_to_view_col (eti, cursor_col) + 1); -} - -static gint -eti_e_cell_event (ETableItem *item, - ECellView *ecell_view, - GdkEvent *event, - gint model_col, - gint view_col, - gint row, - ECellFlags flags) -{ - ECellActions actions = 0; - gint ret_val; - - ret_val = e_cell_event ( - ecell_view, event, model_col, view_col, row, flags, &actions); - - if (actions & E_CELL_GRAB) { - GdkDevice *event_device; - guint32 event_time; - - d (g_print ("%s: eti_grab\n", __FUNCTION__)); - - event_device = gdk_event_get_device (event); - event_time = gdk_event_get_time (event); - eti_grab (item, event_device, event_time); - - item->grabbed_col = view_col; - item->grabbed_row = row; - } - - if (actions & E_CELL_UNGRAB) { - guint32 event_time; - - d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - - event_time = gdk_event_get_time (event); - eti_ungrab (item, event_time); - - item->grabbed_col = -1; - item->grabbed_row = -1; - } - - return ret_val; -} - -/* FIXME: cursor */ -static gint -eti_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - ETableItem *eti = E_TABLE_ITEM (item); - ECellView *ecell_view; - GdkModifierType event_state = 0; - GdkEvent *event_copy; - guint event_button = 0; - guint event_keyval = 0; - gdouble event_x_item = 0; - gdouble event_y_item = 0; - gdouble event_x_win = 0; - gdouble event_y_win = 0; - guint32 event_time; - gboolean return_val = TRUE; -#if d(!)0 - gboolean leave = FALSE; -#endif - - if (!eti->header) - return FALSE; - - /* Don't fetch the device here. GnomeCanvas frequently emits - * synthesized events, and calling gdk_event_get_device() on them - * will trigger a runtime warning. Fetch the device where needed. */ - gdk_event_get_button (event, &event_button); - gdk_event_get_coords (event, &event_x_win, &event_y_win); - gdk_event_get_keyval (event, &event_keyval); - gdk_event_get_state (event, &event_state); - event_time = gdk_event_get_time (event); - - switch (event->type) { - case GDK_BUTTON_PRESS: { - gdouble x1, y1; - gint col, row; - gint cursor_row, cursor_col; - gint new_cursor_row, new_cursor_col; - ECellFlags flags = 0; - - d (g_print ("%s: GDK_BUTTON_PRESS received, button %d\n", __FUNCTION__, event_button)); - - switch (event_button) { - case 1: /* Fall through. */ - case 2: - e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (eti), TRUE); - - event_x_item = event_x_win; - event_y_item = event_y_win; - - gnome_canvas_item_w2i ( - item, &event_x_item, &event_y_item); - - if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) { - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - return TRUE; - } - - ecell_view = eti->cell_views[col]; - - /* Clone the event and alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->button.x = x1; - event_copy->button.y = y1; - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - if (cursor_col == view_to_model_col (eti, col) && cursor_row == view_to_model_row (eti, row)) { - flags = E_CELL_CURSOR; - } else { - flags = 0; - } - - return_val = eti_e_cell_event ( - eti, ecell_view, event_copy, - view_to_model_col (eti, col), - col, row, flags); - if (return_val) { - gdk_event_free (event_copy); - return TRUE; - } - - g_signal_emit ( - eti, eti_signals[CLICK], 0, - row, view_to_model_col (eti, col), - event_copy, &return_val); - - gdk_event_free (event_copy); - - if (return_val) { - eti->click_count = 0; - return TRUE; - } - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - eti->maybe_did_something = - e_selection_model_maybe_do_something ( - E_SELECTION_MODEL (eti->selection), - view_to_model_row (eti, row), - view_to_model_col (eti, col), - event_state); - g_object_get ( - eti->selection, - "cursor_row", &new_cursor_row, - "cursor_col", &new_cursor_col, - NULL); - - if (cursor_row != new_cursor_row || cursor_col != new_cursor_col) { - eti->click_count = 1; - } else { - eti->click_count++; - eti->row_guess = row; - - if ((!eti_editing (eti)) && e_table_model_is_cell_editable (eti->table_model, cursor_col, row)) { - e_table_item_enter_edit (eti, col, row); - } - - /* - * Adjust the event positions - */ - - if (eti_editing (eti)) { - return_val = eti_e_cell_event ( - eti, ecell_view, event, - view_to_model_col (eti, col), - col, row, - E_CELL_EDITING | - E_CELL_CURSOR); - if (return_val) - return TRUE; - } - } - - if (event_button == 1) { - GdkDevice *event_device; - - return_val = TRUE; - - event_device = gdk_event_get_device (event); - - eti->maybe_in_drag = TRUE; - eti->drag_row = new_cursor_row; - eti->drag_col = new_cursor_col; - eti->drag_x = event_x_item; - eti->drag_y = event_y_item; - eti->drag_state = event_state; - eti->grabbed = TRUE; - d (g_print ("%s: eti_grab\n", __FUNCTION__)); - eti_grab (eti, event_device, event_time); - } - - break; - case 3: - e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (eti), TRUE); - - event_x_item = event_x_win; - event_y_item = event_y_win; - - gnome_canvas_item_w2i ( - item, &event_x_item, &event_y_item); - - if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) - return TRUE; - - e_selection_model_right_click_down ( - E_SELECTION_MODEL (eti->selection), - view_to_model_row (eti, row), - view_to_model_col (eti, col), 0); - - /* Clone the event and alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->button.x = event_x_item; - event_copy->button.y = event_y_item; - - g_signal_emit ( - eti, eti_signals[RIGHT_CLICK], 0, - row, view_to_model_col (eti, col), - event, &return_val); - - gdk_event_free (event_copy); - - if (!return_val) - e_selection_model_right_click_up (E_SELECTION_MODEL (eti->selection)); - break; - case 4: - case 5: - return FALSE; - - } - break; - } - - case GDK_BUTTON_RELEASE: { - gdouble x1, y1; - gint col, row; - gint cursor_row, cursor_col; - - d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d\n", __FUNCTION__, event_button)); - - if (eti->grabbed_count > 0) { - d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (eti, event_time); - } - - if (event_button == 1) { - if (eti->maybe_in_drag) { - eti->maybe_in_drag = FALSE; - if (!eti->maybe_did_something) - e_selection_model_do_something (E_SELECTION_MODEL (eti->selection), eti->drag_row, eti->drag_col, eti->drag_state); - } - if (eti->in_drag) { - eti->in_drag = FALSE; - } - } - - switch (event_button) { - case 1: /* Fall through. */ - case 2: - - event_x_item = event_x_win; - event_y_item = event_y_win; - - gnome_canvas_item_w2i ( - item, &event_x_item, &event_y_item); -#if d(!)0 - { - gboolean cell_found = find_cell ( - eti, event_x_item, event_y_item, - &col, &row, &x1, &y1); - g_print ( - "%s: find_cell(%f, %f) = %s(%d, %d, %f, %f)\n", - __FUNCTION__, event_x_item, event_y_item, - cell_found?"true":"false", col, row, x1, y1); - } -#endif - - if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) - return TRUE; - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - if (eti_editing (eti) && cursor_row == view_to_model_row (eti, row) && cursor_col == view_to_model_col (eti, col)) { - - d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d, line: %d\n", __FUNCTION__, event_button, __LINE__)) -; - - ecell_view = eti->cell_views[col]; - - /* Clone the event and alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->button.x = x1; - event_copy->button.y = y1; - - return_val = eti_e_cell_event ( - eti, ecell_view, event_copy, - view_to_model_col (eti, col), - col, row, - E_CELL_EDITING | - E_CELL_CURSOR); - - gdk_event_free (event_copy); - } - break; - case 3: - e_selection_model_right_click_up (E_SELECTION_MODEL (eti->selection)); - return_val = TRUE; - break; - case 4: - case 5: - return FALSE; - - } - break; - } - - case GDK_2BUTTON_PRESS: { - gint model_col, model_row; -#if 0 - gdouble x1, y1; -#endif - - d (g_print ("%s: GDK_2BUTTON_PRESS received, button %d\n", __FUNCTION__, event_button)); - - /* - * click_count is so that if you click on two - * different rows we don't send a double click signal. - */ - - if (eti->click_count >= 2) { - - event_x_item = event_x_win; - event_y_item = event_y_win; - - gnome_canvas_item_w2i ( - item, &event_x_item, &event_y_item); - - g_object_get ( - eti->selection, - "cursor_row", &model_row, - "cursor_col", &model_col, - NULL); - - /* Clone the event and alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->button.x = event_x_item - - e_table_header_col_diff ( - eti->header, 0, - model_to_view_col (eti, model_col)); - event_copy->button.y = event_y_item - - e_table_item_row_diff ( - eti, 0, - model_to_view_row (eti, model_row)); - - if (event_button == 1) { - if (eti->maybe_in_drag) { - eti->maybe_in_drag = FALSE; - if (!eti->maybe_did_something) - e_selection_model_do_something (E_SELECTION_MODEL (eti->selection), eti->drag_row, eti->drag_col, eti->drag_state); - } - if (eti->in_drag) { - eti->in_drag = FALSE; - } - if (eti_editing (eti)) - e_table_item_leave_edit_ (eti); - - } - - if (eti->grabbed_count > 0) { - d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (eti, event_time); - } - - if (model_row != -1 && model_col != -1) { - g_signal_emit ( - eti, eti_signals[DOUBLE_CLICK], 0, - model_row, model_col, event_copy); - } - - gdk_event_free (event_copy); - } - break; - } - case GDK_MOTION_NOTIFY: { - gint col, row, flags; - gdouble x1, y1; - gint cursor_col, cursor_row; - - event_x_item = event_x_win; - event_y_item = event_y_win; - - gnome_canvas_item_w2i (item, &event_x_item, &event_y_item); - - if (eti->maybe_in_drag) { - if (abs (event_x_item - eti->drag_x) >= 3 || - abs (event_y_item - eti->drag_y) >= 3) { - gboolean drag_handled; - - eti->maybe_in_drag = 0; - - /* Clone the event and - * alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->motion.x = event_x_item; - event_copy->motion.y = event_y_item; - - g_signal_emit ( - eti, eti_signals[START_DRAG], 0, - eti->drag_row, eti->drag_col, - event_copy, &drag_handled); - - gdk_event_free (event_copy); - - if (drag_handled) - eti->in_drag = 1; - else - eti->in_drag = 0; - } - } - - if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) - return TRUE; - - if (eti->motion_row != -1 && eti->motion_col != -1 && - (row != eti->motion_row || col != eti->motion_col)) { - GdkEvent *cross = gdk_event_new (GDK_LEAVE_NOTIFY); - cross->crossing.time = event_time; - return_val = eti_e_cell_event ( - eti, eti->cell_views[eti->motion_col], - cross, - view_to_model_col (eti, eti->motion_col), - eti->motion_col, eti->motion_row, 0); - } - - eti->motion_row = row; - eti->motion_col = col; - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - flags = 0; - if (cursor_row == view_to_model_row (eti, row) && cursor_col == view_to_model_col (eti, col)) { - flags = E_CELL_EDITING | E_CELL_CURSOR; - } - - ecell_view = eti->cell_views[col]; - - /* Clone the event and alter its position. */ - event_copy = gdk_event_copy (event); - event_copy->motion.x = x1; - event_copy->motion.y = y1; - - return_val = eti_e_cell_event ( - eti, ecell_view, event_copy, - view_to_model_col (eti, col), col, row, flags); - - gdk_event_free (event_copy); - - break; - } - - case GDK_KEY_PRESS: { - gint cursor_row, cursor_col; - gint handled = TRUE; - - d (g_print ("%s: GDK_KEY_PRESS received, keyval: %d\n", __FUNCTION__, (gint) e->key.keyval)); - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - if (cursor_row == -1 && cursor_col == -1) - return FALSE; - - eti->in_key_press = TRUE; - - switch (event_keyval) { - case GDK_KEY_Left: - case GDK_KEY_KP_Left: - if (eti_editing (eti)) { - handled = FALSE; - break; - } - - g_signal_emit ( - eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), - cursor_col, event, &return_val); - if ((!return_val) && - (atk_get_root () || eti->cursor_mode != E_CURSOR_LINE) && - cursor_col != view_to_model_col (eti, 0)) - eti_cursor_move_left (eti); - return_val = 1; - break; - - case GDK_KEY_Right: - case GDK_KEY_KP_Right: - if (eti_editing (eti)) { - handled = FALSE; - break; - } - - g_signal_emit ( - eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), - cursor_col, event, &return_val); - if ((!return_val) && - (atk_get_root () || eti->cursor_mode != E_CURSOR_LINE) && - cursor_col != view_to_model_col (eti, eti->cols - 1)) - eti_cursor_move_right (eti); - return_val = 1; - break; - - case GDK_KEY_Up: - case GDK_KEY_KP_Up: - case GDK_KEY_Down: - case GDK_KEY_KP_Down: - if ((event_state & GDK_MOD1_MASK) - && ((event_keyval == GDK_KEY_Down) || (event_keyval == GDK_KEY_KP_Down))) { - gint view_col = model_to_view_col (eti, cursor_col); - - if ((view_col >= 0) && (view_col < eti->cols)) - if (eti_e_cell_event (eti, eti->cell_views[view_col], event, cursor_col, view_col, model_to_view_row (eti, cursor_row), E_CELL_CURSOR)) - return TRUE; - } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - break; - case GDK_KEY_Home: - case GDK_KEY_KP_Home: - if (eti_editing (eti)) { - handled = FALSE; - break; - } - - if (eti->cursor_mode != E_CURSOR_LINE) { - eti_cursor_move (eti, model_to_view_row (eti, cursor_row), 0); - return_val = TRUE; - } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - break; - case GDK_KEY_End: - case GDK_KEY_KP_End: - if (eti_editing (eti)) { - handled = FALSE; - break; - } - - if (eti->cursor_mode != E_CURSOR_LINE) { - eti_cursor_move (eti, model_to_view_row (eti, cursor_row), eti->cols - 1); - return_val = TRUE; - } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - break; - case GDK_KEY_Tab: - case GDK_KEY_KP_Tab: - case GDK_KEY_ISO_Left_Tab: - if ((event_state & GDK_CONTROL_MASK) != 0) { - return_val = FALSE; - break; - } - if (eti->cursor_mode == E_CURSOR_SPREADSHEET) { - if ((event_state & GDK_SHIFT_MASK) != 0) { - /* shift tab */ - if (cursor_col != view_to_model_col (eti, 0)) - eti_cursor_move_left (eti); - else if (cursor_row != view_to_model_row (eti, 0)) - eti_cursor_move (eti, model_to_view_row (eti, cursor_row) - 1, eti->cols - 1); - else - return_val = FALSE; - } else { - if (cursor_col != view_to_model_col (eti, eti->cols - 1)) - eti_cursor_move_right (eti); - else if (cursor_row != view_to_model_row (eti, eti->rows - 1)) - eti_cursor_move (eti, model_to_view_row (eti, cursor_row) + 1, 0); - else - return_val = FALSE; - } - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - if (cursor_col >= 0 && cursor_row >= 0 && return_val && - (!eti_editing (eti)) && e_table_model_is_cell_editable (eti->table_model, cursor_col, model_to_view_row (eti, cursor_row))) { - e_table_item_enter_edit (eti, model_to_view_col (eti, cursor_col), model_to_view_row (eti, cursor_row)); - } - break; - } else { - /* Let tab send you to the next widget. */ - return_val = FALSE; - break; - } - - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_ISO_Enter: - case GDK_KEY_3270_Enter: - if (eti_editing (eti)) { - ecell_view = eti->cell_views[eti->editing_col]; - return_val = eti_e_cell_event ( - eti, ecell_view, event, - view_to_model_col (eti, eti->editing_col), - eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR | E_CELL_PREEDIT); - if (!return_val) - break; - } - g_signal_emit ( - eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), - cursor_col, event, &return_val); - if (!return_val) - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - break; - - default: - handled = FALSE; - break; - } - - if (!handled) { - switch (event_keyval) { - case GDK_KEY_Scroll_Lock: - case GDK_KEY_Sys_Req: - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - case GDK_KEY_Caps_Lock: - case GDK_KEY_Shift_Lock: - case GDK_KEY_Meta_L: - case GDK_KEY_Meta_R: - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - case GDK_KEY_Super_L: - case GDK_KEY_Super_R: - case GDK_KEY_Hyper_L: - case GDK_KEY_Hyper_R: - case GDK_KEY_ISO_Lock: - break; - - default: - if (!eti_editing (eti)) { - gint col, row; - row = model_to_view_row (eti, cursor_row); - col = model_to_view_col (eti, cursor_col); - if (col != -1 && row != -1 && e_table_model_is_cell_editable (eti->table_model, cursor_col, row)) { - e_table_item_enter_edit (eti, col, row); - } - } - if (!eti_editing (eti)) { - g_signal_emit ( - eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), - cursor_col, event, &return_val); - if (!return_val) - e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - } else { - ecell_view = eti->cell_views[eti->editing_col]; - return_val = eti_e_cell_event ( - eti, ecell_view, event, - view_to_model_col (eti, eti->editing_col), - eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR); - if (!return_val) - e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); - } - break; - } - } - eti->in_key_press = FALSE; - break; - } - - case GDK_KEY_RELEASE: { - gint cursor_row, cursor_col; - - d (g_print ("%s: GDK_KEY_RELEASE received, keyval: %d\n", __FUNCTION__, (gint) event_keyval)); - - g_object_get ( - eti->selection, - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, - NULL); - - if (cursor_col == -1) - return FALSE; - - if (eti_editing (eti)) { - ecell_view = eti->cell_views[eti->editing_col]; - return_val = eti_e_cell_event ( - eti, ecell_view, event, - view_to_model_col (eti, eti->editing_col), - eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR); - } - break; - } - - case GDK_LEAVE_NOTIFY: - d (leave = TRUE); - case GDK_ENTER_NOTIFY: - d (g_print ("%s: %s received\n", __FUNCTION__, leave ? "GDK_LEAVE_NOTIFY" : "GDK_ENTER_NOTIFY")); - if (eti->motion_row != -1 && eti->motion_col != -1) - return_val = eti_e_cell_event ( - eti, eti->cell_views[eti->motion_col], - event, - view_to_model_col (eti, eti->motion_col), - eti->motion_col, eti->motion_row, 0); - eti->motion_row = -1; - eti->motion_col = -1; - - break; - - case GDK_FOCUS_CHANGE: - d (g_print ("%s: GDK_FOCUS_CHANGE received, %s\n", __FUNCTION__, e->focus_change.in ? "in": "out")); - if (event->focus_change.in) { - if (eti->save_row != -1 && - eti->save_col != -1 && - !eti_editing (eti) && - e_table_model_is_cell_editable (eti->table_model, view_to_model_col (eti, eti->save_col), eti->save_row)) { - e_table_item_enter_edit (eti, eti->save_col, eti->save_row); - e_cell_load_state ( - eti->cell_views[eti->editing_col], view_to_model_col (eti, eti->save_col), - eti->save_col, eti->save_row, eti->edit_ctx, eti->save_state); - eti_free_save_state (eti); - } - } else { - if (eti_editing (eti)) { - eti_free_save_state (eti); - - eti->save_row = eti->editing_row; - eti->save_col = eti->editing_col; - eti->save_state = e_cell_save_state ( - eti->cell_views[eti->editing_col], view_to_model_col (eti, eti->editing_col), - eti->editing_col, eti->editing_row, eti->edit_ctx); - e_table_item_leave_edit_(eti); - } - } - - default: - return_val = FALSE; - } - /* d(g_print("%s: returning: %s\n", __FUNCTION__, return_val?"true":"false"));*/ - - return return_val; -} - -static void -eti_style_set (ETableItem *eti, - GtkStyle *previous_style) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - if (eti->cell_views_realized) { - gint i; - gint n_cells = eti->n_cells; - - for (i = 0; i < n_cells; i++) { - e_cell_style_set (eti->cell_views[i], previous_style); - } - } - - eti->needs_compute_height = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); - - free_height_cache (eti); - - eti_idle_maybe_show_cursor (eti); -} - -static void -eti_class_init (ETableItemClass *class) -{ - GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = eti_dispose; - object_class->set_property = eti_set_property; - object_class->get_property = eti_get_property; - - item_class->update = eti_update; - item_class->realize = eti_realize; - item_class->unrealize = eti_unrealize; - item_class->draw = eti_draw; - item_class->point = eti_point; - item_class->event = eti_event; - - class->cursor_change = NULL; - class->cursor_activated = NULL; - class->double_click = NULL; - class->right_click = NULL; - class->click = NULL; - class->key_press = NULL; - class->start_drag = NULL; - class->style_set = eti_style_set; - class->selection_model_removed = NULL; - class->selection_model_added = NULL; - - g_object_class_install_property ( - object_class, - PROP_TABLE_HEADER, - g_param_spec_object ( - "ETableHeader", - "Table header", - "Table header", - E_TYPE_TABLE_HEADER, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_MODEL, - g_param_spec_object ( - "ETableModel", - "Table model", - "Table model", - E_TYPE_TABLE_MODEL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTION_MODEL, - g_param_spec_object ( - "selection_model", - "Selection model", - "Selection model", - E_TYPE_SELECTION_MODEL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_ALTERNATING_ROW_COLORS, - g_param_spec_boolean ( - "alternating_row_colors", - "Alternating Row Colors", - "Alternating Row Colors", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_HORIZONTAL_DRAW_GRID, - g_param_spec_boolean ( - "horizontal_draw_grid", - "Horizontal Draw Grid", - "Horizontal Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_VERTICAL_DRAW_GRID, - g_param_spec_boolean ( - "vertical_draw_grid", - "Vertical Draw Grid", - "Vertical Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_TABLE_DRAW_FOCUS, - g_param_spec_boolean ( - "drawfocus", - "Draw focus", - "Draw focus", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_MODE, - g_param_spec_int ( - "cursor_mode", - "Cursor mode", - "Cursor mode", - E_CURSOR_LINE, - E_CURSOR_SPREADSHEET, - E_CURSOR_LINE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_LENGTH_THRESHOLD, - g_param_spec_int ( - "length_threshold", - "Length Threshold", - "Length Threshold", - -1, G_MAXINT, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_WIDTH, - g_param_spec_double ( - "minimum_width", - "Minimum width", - "Minimum Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_ROW, - g_param_spec_int ( - "cursor_row", - "Cursor row", - "Cursor row", - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UNIFORM_ROW_HEIGHT, - g_param_spec_boolean ( - "uniform_row_height", - "Uniform row height", - "Uniform row height", - FALSE, - G_PARAM_READWRITE)); - - eti_signals[CURSOR_CHANGE] = g_signal_new ( - "cursor_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, cursor_change), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - eti_signals[CURSOR_ACTIVATED] = g_signal_new ( - "cursor_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, cursor_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - eti_signals[DOUBLE_CLICK] = g_signal_new ( - "double_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, double_click), - NULL, NULL, - e_marshal_NONE__INT_INT_BOXED, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - eti_signals[START_DRAG] = g_signal_new ( - "start_drag", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, start_drag), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - eti_signals[RIGHT_CLICK] = g_signal_new ( - "right_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, right_click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - eti_signals[CLICK] = g_signal_new ( - "click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - eti_signals[KEY_PRESS] = g_signal_new ( - "key_press", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, key_press), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - eti_signals[STYLE_SET] = g_signal_new ( - "style_set", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableItemClass, style_set), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_STYLE); - - eti_signals[SELECTION_MODEL_REMOVED] = g_signal_new ( - "selection_model_removed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ETableItemClass, selection_model_removed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - eti_signals[SELECTION_MODEL_ADDED] = g_signal_new ( - "selection_model_added", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ETableItemClass, selection_model_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - /* A11y Init */ - gal_a11y_e_table_item_init (); -} - -/** - * e_table_item_set_cursor: - * @eti: %ETableItem which will have the cursor set. - * @col: Column to select. -1 means the last column. - * @row: Row to select. -1 means the last row. - * - * This routine sets the cursor of the %ETableItem canvas item. - */ -void -e_table_item_set_cursor (ETableItem *eti, - gint col, - gint row) -{ - e_table_item_focus (eti, col, view_to_model_row (eti, row), 0); -} - -static void -e_table_item_focus (ETableItem *eti, - gint col, - gint row, - GdkModifierType state) -{ - g_return_if_fail (eti != NULL); - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - - if (row == -1) { - row = view_to_model_row (eti, eti->rows - 1); - } - - if (col == -1) { - col = eti->cols - 1; - } - - if (row != -1) { - e_selection_model_do_something ( - E_SELECTION_MODEL (eti->selection), - row, col, state); - } -} - -/** - * e_table_item_get_focused_column: - * @eti: %ETableItem which will have the cursor retrieved. - * - * This routine gets the cursor of the %ETableItem canvas item. - * - * Returns: The current cursor column. - */ -gint -e_table_item_get_focused_column (ETableItem *eti) -{ - gint cursor_col; - - g_return_val_if_fail (eti != NULL, -1); - g_return_val_if_fail (E_IS_TABLE_ITEM (eti), -1); - - g_object_get ( - eti->selection, - "cursor_col", &cursor_col, - NULL); - - return cursor_col; -} - -static void -eti_cursor_change (ESelectionModel *selection, - gint row, - gint col, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - gint view_row; - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - view_row = model_to_view_row (eti, row); - - if (eti->old_cursor_row != -1 && view_row != eti->old_cursor_row) - e_table_item_redraw_row (eti, eti->old_cursor_row); - - if (view_row == -1) { - e_table_item_leave_edit_(eti); - eti->old_cursor_row = -1; - return; - } - - if (!e_table_model_has_change_pending (eti->table_model)) { - if (!eti->in_key_press) { - eti_maybe_show_cursor (eti, DOUBLE_CLICK_TIME + 10); - } else { - eti_maybe_show_cursor (eti, 0); - } - } - - e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (eti), FALSE); - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - - g_signal_emit (eti, eti_signals[CURSOR_CHANGE], 0, view_row); - - e_table_item_redraw_row (eti, view_row); - - eti->old_cursor_row = view_row; -} - -static void -eti_cursor_activated (ESelectionModel *selection, - gint row, - gint col, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - gint view_row; - gint view_col; - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - view_row = model_to_view_row (eti, row); - view_col = model_to_view_col (eti, col); - - if (view_row != -1 && view_col != -1) { - if (!e_table_model_has_change_pending (eti->table_model)) { - if (!eti->in_key_press) { - eti_show_cursor (eti, DOUBLE_CLICK_TIME + 10); - } else { - eti_show_cursor (eti, 0); - } - eti_check_cursor_bounds (eti); - } - } - - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - - if (view_row != -1) - g_signal_emit ( - eti, eti_signals[CURSOR_ACTIVATED], 0, view_row); -} - -static void -eti_selection_change (ESelectionModel *selection, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - eti->needs_redraw = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); -} - -static void -eti_selection_row_change (ESelectionModel *selection, - gint row, - ETableItem *eti) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - if (!eti->needs_redraw) { - e_table_item_redraw_row (eti, model_to_view_row (eti, row)); - } -} - -/** - * e_table_item_enter_edit - * @eti: %ETableItem which will start being edited - * @col: The view col to edit. - * @row: The view row to edit. - * - * This routine starts the given %ETableItem editing at the given view - * column and row. - */ -void -e_table_item_enter_edit (ETableItem *eti, - gint col, - gint row) -{ - g_return_if_fail (eti != NULL); - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - - d (g_print ("%s: %d, %d, eti_editing() = %s\n", __FUNCTION__, col, row, eti_editing (eti)?"true":"false")); - - if (eti_editing (eti)) - e_table_item_leave_edit_(eti); - - eti->editing_col = col; - eti->editing_row = row; - - eti->edit_ctx = e_cell_enter_edit (eti->cell_views[col], view_to_model_col (eti, col), col, row); -} - -/** - * e_table_item_leave_edit_ - * @eti: %ETableItem which will stop being edited - * - * This routine stops the given %ETableItem from editing. - */ -void -e_table_item_leave_edit (ETableItem *eti) -{ - gint col, row; - gpointer edit_ctx; - - g_return_if_fail (eti != NULL); - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - - d (g_print ("%s: eti_editing() = %s\n", __FUNCTION__, eti_editing (eti)?"true":"false")); - - if (!eti_editing (eti)) - return; - - col = eti->editing_col; - row = eti->editing_row; - edit_ctx = eti->edit_ctx; - - eti->editing_col = -1; - eti->editing_row = -1; - eti->edit_ctx = NULL; - - e_cell_leave_edit ( - eti->cell_views[col], - view_to_model_col (eti, col), - col, row, edit_ctx); -} - -/** - * e_table_item_compute_location - * @eti: %ETableItem to look in. - * @x: A pointer to the x location to find in the %ETableItem. - * @y: A pointer to the y location to find in the %ETableItem. - * @row: A pointer to the location to store the found row in. - * @col: A pointer to the location to store the found col in. - * - * This routine locates the pixel location (*x, *y) in the - * %ETableItem. If that location is in the %ETableItem, *row and *col - * are set to the view row and column where it was found. If that - * location is not in the %ETableItem, the height of the %ETableItem - * is removed from the value y points to. - */ -void -e_table_item_compute_location (ETableItem *eti, - gint *x, - gint *y, - gint *row, - gint *col) -{ - /* Save the grabbed row but make sure that we don't get flawed - * results because the cursor is grabbed. */ - gint grabbed_row = eti->grabbed_row; - eti->grabbed_row = -1; - - if (!find_cell (eti, *x, *y, col, row, NULL, NULL)) { - *y -= eti->height; - } - - eti->grabbed_row = grabbed_row; -} - -/** - * e_table_item_compute_mouse_over: - * Similar to e_table_item_compute_location, only here recalculating - * the position inside the item too. - **/ -void -e_table_item_compute_mouse_over (ETableItem *eti, - gint x, - gint y, - gint *row, - gint *col) -{ - gdouble realx, realy; - /* Save the grabbed row but make sure that we don't get flawed - * results because the cursor is grabbed. */ - gint grabbed_row = eti->grabbed_row; - eti->grabbed_row = -1; - - realx = x; - realy = y; - - gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (eti), &realx, &realy); - - if (!find_cell (eti, (gint) realx, (gint) realy, col, row, NULL, NULL)) { - *row = -1; - *col = -1; - } - - eti->grabbed_row = grabbed_row; -} - -void -e_table_item_get_cell_geometry (ETableItem *eti, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height) -{ - if (eti->rows > *row) { - if (x) - *x = e_table_header_col_diff (eti->header, 0, *col); - if (y) - *y = e_table_item_row_diff (eti, 0, *row); - if (width) - *width = e_table_header_col_diff (eti->header, *col, *col + 1); - if (height) - *height = ETI_ROW_HEIGHT (eti, *row); - *row = -1; - *col = -1; - } else { - *row -= eti->rows; - } -} - -typedef struct { - ETableItem *item; - gint rows_printed; -} ETableItemPrintContext; - -static gdouble * -e_table_item_calculate_print_widths (ETableHeader *eth, - gdouble width) -{ - gint i; - gdouble extra; - gdouble expansion; - gint last_resizable = -1; - gdouble scale = 1.0L; - gdouble *widths = g_new (gdouble, e_table_header_count (eth)); - /* - 1 to account for the last pixel border. */ - extra = width - 1; - expansion = 0; - for (i = 0; i < eth->col_count; i++) { - extra -= eth->columns[i]->min_width * scale; - if (eth->columns[i]->resizable && eth->columns[i]->expansion > 0) - last_resizable = i; - expansion += eth->columns[i]->resizable ? eth->columns[i]->expansion : 0; - widths[i] = eth->columns[i]->min_width * scale; - } - for (i = 0; i <= last_resizable; i++) { - widths[i] += extra * (eth->columns[i]->resizable ? eth->columns[i]->expansion : 0) / expansion; - } - - return widths; -} - -static gdouble -eti_printed_row_height (ETableItem *eti, - gdouble *widths, - GtkPrintContext *context, - gint row) -{ - gint col; - gint cols = eti->cols; - gdouble height = 0; - for (col = 0; col < cols; col++) { - ECellView *ecell_view = eti->cell_views[col]; - gdouble this_height = e_cell_print_height ( - ecell_view, context, view_to_model_col (eti, col), col, row, - widths[col] - 1); - if (this_height > height) - height = this_height; - } - return height; -} - -#define CHECK(x) if((x) == -1) return -1; - -static gint -gp_draw_rect (GtkPrintContext *context, - gdouble x, - gdouble y, - gdouble width, - gdouble height) -{ - cairo_t *cr; - cr = gtk_print_context_get_cairo_context (context); - cairo_save (cr); - cairo_rectangle (cr, x, y, width, height); - cairo_set_line_width (cr, 0.5); - cairo_stroke (cr); - cairo_restore (cr); - return 0; -} - -static void -e_table_item_print_page (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble height, - gboolean quantize, - ETableItemPrintContext *itemcontext) -{ - ETableItem *eti = itemcontext->item; - const gint rows = eti->rows; - const gint cols = eti->cols; - gdouble max_height; - gint rows_printed = itemcontext->rows_printed; - gint row, col, next_page = 0; - gdouble yd = height; - cairo_t *cr; - gdouble *widths; - - cr = gtk_print_context_get_cairo_context (context); - max_height = gtk_print_context_get_height (context); - widths = e_table_item_calculate_print_widths (itemcontext->item->header, width); - - /* - * Draw cells - */ - - if (eti->horizontal_draw_grid) { - gp_draw_rect (context, 0, yd, width, 1); - } - yd++; - - for (row = rows_printed; row < rows; row++) { - gdouble xd = 1, row_height; - row_height = eti_printed_row_height (eti, widths, context, row); - - if (quantize) { - if (yd + row_height + 1 > max_height && row != rows_printed) { - next_page = 1; - break; - } - } else { - if (yd > max_height) { - next_page = 1; - break; - } - } - - for (col = 0; col < cols; col++) { - ECellView *ecell_view = eti->cell_views[col]; - - cairo_save (cr); - cairo_translate (cr, xd, yd); - cairo_rectangle (cr, 0, 0, widths[col] - 1, row_height); - cairo_clip (cr); - - e_cell_print ( - ecell_view, context, - view_to_model_col (eti, col), - col, - row, - widths[col] - 1, - row_height + 2); - - cairo_restore (cr); - - xd += widths[col]; - } - - yd += row_height; - if (eti->horizontal_draw_grid) { - gp_draw_rect (context, 0, yd, width, 1); - } - yd++; - } - - itemcontext->rows_printed = row; - if (eti->vertical_draw_grid) { - gdouble xd = 0; - for (col = 0; col < cols; col++) { - gp_draw_rect (context, xd, height, 1, yd - height); - xd += widths[col]; - } - gp_draw_rect (context, xd, height, 1, yd - height); - } - - if (next_page) - cairo_show_page (cr); - - g_free (widths); -} - -static gboolean -e_table_item_data_left (EPrintable *ep, - ETableItemPrintContext *itemcontext) -{ - ETableItem *item = itemcontext->item; - gint rows_printed = itemcontext->rows_printed; - - g_signal_stop_emission_by_name (ep, "data_left"); - return rows_printed < item->rows; -} - -static void -e_table_item_reset (EPrintable *ep, - ETableItemPrintContext *itemcontext) -{ - itemcontext->rows_printed = 0; -} - -static gdouble -e_table_item_height (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantize, - ETableItemPrintContext *itemcontext) -{ - ETableItem *item = itemcontext->item; - const gint rows = item->rows; - gint rows_printed = itemcontext->rows_printed; - gdouble *widths; - gint row; - gdouble yd = 0; - - widths = e_table_item_calculate_print_widths (itemcontext->item->header, width); - - /* - * Draw cells - */ - yd++; - - for (row = rows_printed; row < rows; row++) { - gdouble row_height; - - row_height = eti_printed_row_height (item, widths, context, row); - if (quantize) { - if (max_height != -1 && yd + row_height + 1 > max_height && row != rows_printed) { - break; - } - } else { - if (max_height != -1 && yd > max_height) { - break; - } - } - - yd += row_height; - - yd++; - } - - g_free (widths); - - if (max_height != -1 && (!quantize) && yd > max_height) - yd = max_height; - - g_signal_stop_emission_by_name (ep, "height"); - return yd; -} - -static gboolean -e_table_item_will_fit (EPrintable *ep, - GtkPrintContext *context, - gdouble width, - gdouble max_height, - gboolean quantize, - ETableItemPrintContext *itemcontext) -{ - ETableItem *item = itemcontext->item; - const gint rows = item->rows; - gint rows_printed = itemcontext->rows_printed; - gdouble *widths; - gint row; - gdouble yd = 0; - gboolean ret_val = TRUE; - - widths = e_table_item_calculate_print_widths (itemcontext->item->header, width); - - /* - * Draw cells - */ - yd++; - - for (row = rows_printed; row < rows; row++) { - gdouble row_height; - - row_height = eti_printed_row_height (item, widths, context, row); - if (quantize) { - if (max_height != -1 && yd + row_height + 1 > max_height && row != rows_printed) { - ret_val = FALSE; - break; - } - } else { - if (max_height != -1 && yd > max_height) { - ret_val = FALSE; - break; - } - } - - yd += row_height; - - yd++; - } - - g_free (widths); - - g_signal_stop_emission_by_name (ep, "will_fit"); - return ret_val; -} - -static void -e_table_item_printable_destroy (gpointer data, - GObject *where_object_was) -{ - ETableItemPrintContext *itemcontext = data; - - g_object_unref (itemcontext->item); - g_free (itemcontext); -} - -/** - * e_table_item_get_printable - * @eti: %ETableItem which will be printed - * - * This routine creates and returns an %EPrintable that can be used to - * print the given %ETableItem. - * - * Returns: The %EPrintable. - */ -EPrintable * -e_table_item_get_printable (ETableItem *item) -{ - EPrintable *printable = e_printable_new (); - ETableItemPrintContext *itemcontext; - - itemcontext = g_new (ETableItemPrintContext, 1); - itemcontext->item = item; - g_object_ref (item); - itemcontext->rows_printed = 0; - - g_signal_connect ( - printable, "print_page", - G_CALLBACK (e_table_item_print_page), itemcontext); - g_signal_connect ( - printable, "data_left", - G_CALLBACK (e_table_item_data_left), itemcontext); - g_signal_connect ( - printable, "reset", - G_CALLBACK (e_table_item_reset), itemcontext); - g_signal_connect ( - printable, "height", - G_CALLBACK (e_table_item_height), itemcontext); - g_signal_connect ( - printable, "will_fit", - G_CALLBACK (e_table_item_will_fit), itemcontext); - - g_object_weak_ref ( - G_OBJECT (printable), - e_table_item_printable_destroy, itemcontext); - - return printable; -} diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h deleted file mode 100644 index 26a181dd64..0000000000 --- a/widgets/table/e-table-item.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@gnu.org> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_ITEM_H_ -#define _E_TABLE_ITEM_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <table/e-table-model.h> -#include <table/e-table-header.h> -#include <table/e-table-defines.h> -#include <misc/e-selection-model.h> -#include <misc/e-printable.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_ITEM \ - (e_table_item_get_type ()) -#define E_TABLE_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_ITEM, ETableItem)) -#define E_TABLE_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_ITEM, ETableItemClass)) -#define E_IS_TABLE_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_ITEM)) -#define E_IS_TABLE_ITEM_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_ITEM)) -#define E_TABLE_ITEM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_ITEM, ETableItemClass)) - -G_BEGIN_DECLS - -typedef struct _ETableItem ETableItem; -typedef struct _ETableItemClass ETableItemClass; - -struct _ETableItem { - GnomeCanvasItem parent; - ETableModel *table_model; - ETableHeader *header; - - ETableModel *source_model; - ESelectionModel *selection; - - gint minimum_width, width, height; - - gint cols, rows; - - gint click_count; - - /* - * Ids for the signals we connect to - */ - gint header_dim_change_id; - gint header_structure_change_id; - gint header_request_width_id; - gint table_model_pre_change_id; - gint table_model_no_change_id; - gint table_model_change_id; - gint table_model_row_change_id; - gint table_model_cell_change_id; - gint table_model_rows_inserted_id; - gint table_model_rows_deleted_id; - - gint selection_change_id; - gint selection_row_change_id; - gint cursor_change_id; - gint cursor_activated_id; - - guint cursor_idle_id; - - /* View row, -1 means unknown */ - gint old_cursor_row; - - guint alternating_row_colors : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint uniform_row_height : 1; - guint cell_views_realized : 1; - - guint needs_redraw : 1; - guint needs_compute_height : 1; - guint needs_compute_width : 1; - - guint uses_source_model : 1; - - guint in_key_press : 1; - - guint maybe_in_drag : 1; - guint in_drag : 1; - guint grabbed : 1; - - guint maybe_did_something : 1; - - guint cursor_on_screen : 1; - guint gtk_grabbed : 1; - - guint queue_show_cursor : 1; - guint grab_cancelled : 1; - - gint frozen_count; - - gint cursor_x1; - gint cursor_y1; - gint cursor_x2; - gint cursor_y2; - - gint drag_col; - gint drag_row; - gint drag_x; - gint drag_y; - guint drag_state; - - /* - * Realized views, per column - */ - ECellView **cell_views; - gint n_cells; - - gint *height_cache; - gint uniform_row_height_cache; - gint height_cache_idle_id; - gint height_cache_idle_count; - - /* - * Lengh Threshold: above this, we stop computing correctly - * the size - */ - gint length_threshold; - - gint row_guess; - ECursorMode cursor_mode; - - gint motion_col, motion_row; - - /* - * During editing - */ - gint editing_col, editing_row; - void *edit_ctx; - - gint save_col, save_row; - void *save_state; - - gint grabbed_col, grabbed_row; - gint grabbed_count; -}; - -struct _ETableItemClass { - GnomeCanvasItemClass parent_class; - - void (*cursor_change) (ETableItem *eti, - gint row); - void (*cursor_activated) (ETableItem *eti, - gint row); - void (*double_click) (ETableItem *eti, - gint row, - gint col, - GdkEvent *event); - gboolean (*right_click) (ETableItem *eti, - gint row, - gint col, - GdkEvent *event); - gboolean (*click) (ETableItem *eti, - gint row, - gint col, - GdkEvent *event); - gboolean (*key_press) (ETableItem *eti, - gint row, - gint col, - GdkEvent *event); - gboolean (*start_drag) (ETableItem *eti, - gint row, - gint col, - GdkEvent *event); - void (*style_set) (ETableItem *eti, - GtkStyle *previous_style); - void (*selection_model_removed) - (ETableItem *eti, - ESelectionModel *selection); - void (*selection_model_added) - (ETableItem *eti, - ESelectionModel *selection); -}; - -GType e_table_item_get_type (void) G_GNUC_CONST; - -/* - * Focus - */ -void e_table_item_set_cursor (ETableItem *eti, - gint col, - gint row); - -gint e_table_item_get_focused_column (ETableItem *eti); - -void e_table_item_leave_edit (ETableItem *eti); -void e_table_item_enter_edit (ETableItem *eti, - gint col, - gint row); - -void e_table_item_redraw_range (ETableItem *eti, - gint start_col, - gint start_row, - gint end_col, - gint end_row); - -EPrintable * e_table_item_get_printable (ETableItem *eti); -void e_table_item_compute_location (ETableItem *eti, - gint *x, - gint *y, - gint *row, - gint *col); -void e_table_item_compute_mouse_over (ETableItem *eti, - gint x, - gint y, - gint *row, - gint *col); -void e_table_item_get_cell_geometry (ETableItem *eti, - gint *row, - gint *col, - gint *x, - gint *y, - gint *width, - gint *height); - -gint e_table_item_row_diff (ETableItem *eti, - gint start_row, - gint end_row); - -G_END_DECLS - -#endif /* _E_TABLE_ITEM_H_ */ diff --git a/widgets/table/e-table-memory-callbacks.c b/widgets/table/e-table-memory-callbacks.c deleted file mode 100644 index 279d0a505e..0000000000 --- a/widgets/table/e-table-memory-callbacks.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-util.h" - -#include "e-table-memory-callbacks.h" - -G_DEFINE_TYPE (ETableMemoryCallbacks, e_table_memory_callbacks, E_TYPE_TABLE_MEMORY) - -static gint -etmc_column_count (ETableModel *etm) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->col_count) - return etmc->col_count (etm, etmc->data); - else - return 0; -} - -static gpointer -etmc_value_at (ETableModel *etm, - gint col, - gint row) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->value_at) - return etmc->value_at (etm, col, row, etmc->data); - else - return NULL; -} - -static void -etmc_set_value_at (ETableModel *etm, - gint col, - gint row, - gconstpointer val) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->set_value_at) - etmc->set_value_at (etm, col, row, val, etmc->data); -} - -static gboolean -etmc_is_cell_editable (ETableModel *etm, - gint col, - gint row) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->is_cell_editable) - return etmc->is_cell_editable (etm, col, row, etmc->data); - else - return FALSE; -} - -/* The default for etmc_duplicate_value is to return the raw value. */ -static gpointer -etmc_duplicate_value (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->duplicate_value) - return etmc->duplicate_value (etm, col, value, etmc->data); - else - return (gpointer) value; -} - -static void -etmc_free_value (ETableModel *etm, - gint col, - gpointer value) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->free_value) - etmc->free_value (etm, col, value, etmc->data); -} - -static gpointer -etmc_initialize_value (ETableModel *etm, - gint col) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->initialize_value) - return etmc->initialize_value (etm, col, etmc->data); - else - return NULL; -} - -static gboolean -etmc_value_is_empty (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->value_is_empty) - return etmc->value_is_empty (etm, col, value, etmc->data); - else - return FALSE; -} - -static gchar * -etmc_value_to_string (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->value_to_string) - return etmc->value_to_string (etm, col, value, etmc->data); - else - return g_strdup (""); -} - -static void -etmc_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ - ETableMemoryCallbacks *etmc = E_TABLE_MEMORY_CALLBACKS (etm); - - if (etmc->append_row) - etmc->append_row (etm, source, row, etmc->data); -} - -static void -e_table_memory_callbacks_class_init (ETableMemoryCallbacksClass *class) -{ - ETableModelClass *model_class = E_TABLE_MODEL_CLASS (class); - - model_class->column_count = etmc_column_count; - model_class->value_at = etmc_value_at; - model_class->set_value_at = etmc_set_value_at; - model_class->is_cell_editable = etmc_is_cell_editable; - model_class->duplicate_value = etmc_duplicate_value; - model_class->free_value = etmc_free_value; - model_class->initialize_value = etmc_initialize_value; - model_class->value_is_empty = etmc_value_is_empty; - model_class->value_to_string = etmc_value_to_string; - model_class->append_row = etmc_append_row; - -} - -static void -e_table_memory_callbacks_init (ETableMemoryCallbacks *etmc) -{ - /* nothing to do */ -} - -/** - * e_table_memory_callbacks_new: - * @col_count: - * @value_at: - * @set_value_at: - * @is_cell_editable: - * @duplicate_value: - * @free_value: - * @initialize_value: - * @value_is_empty: - * @value_to_string: - * @data: closure pointer. - * - * This initializes a new ETableMemoryCallbacksModel object. - * ETableMemoryCallbacksModel is an implementaiton of the abstract class - * ETableModel. The ETableMemoryCallbacksModel is designed to allow people - * to easily create ETableModels without having to create a new GType - * derived from ETableModel every time they need one. - * - * Instead, ETableMemoryCallbacksModel uses a setup based in callback - * functions, every callback function signature mimics the signature of - * each ETableModel method and passes the extra @data pointer to each one - * of the method to provide them with any context they might want to use. - * - * Returns: An ETableMemoryCallbacksModel object (which is also an ETableModel - * object). - */ -ETableModel * -e_table_memory_callbacks_new (ETableMemoryCallbacksColumnCountFn col_count, - ETableMemoryCallbacksValueAtFn value_at, - ETableMemoryCallbacksSetValueAtFn set_value_at, - ETableMemoryCallbacksIsCellEditableFn is_cell_editable, - ETableMemoryCallbacksDuplicateValueFn duplicate_value, - ETableMemoryCallbacksFreeValueFn free_value, - ETableMemoryCallbacksInitializeValueFn initialize_value, - ETableMemoryCallbacksValueIsEmptyFn value_is_empty, - ETableMemoryCallbacksValueToStringFn value_to_string, - gpointer data) -{ - ETableMemoryCallbacks *et; - - et = g_object_new (E_TYPE_TABLE_MEMORY_CALLBACKS, NULL); - - et->col_count = col_count; - et->value_at = value_at; - et->set_value_at = set_value_at; - et->is_cell_editable = is_cell_editable; - et->duplicate_value = duplicate_value; - et->free_value = free_value; - et->initialize_value = initialize_value; - et->value_is_empty = value_is_empty; - et->value_to_string = value_to_string; - et->data = data; - - return (ETableModel *) et; - } diff --git a/widgets/table/e-table-memory-callbacks.h b/widgets/table/e-table-memory-callbacks.h deleted file mode 100644 index 8feb6e9884..0000000000 --- a/widgets/table/e-table-memory-callbacks.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_MEMORY_CALLBACKS_H_ -#define _E_TABLE_MEMORY_CALLBACKS_H_ - -#include <table/e-table-memory.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_MEMORY_CALLBACKS \ - (e_table_memory_callbacks_get_type ()) -#define E_TABLE_MEMORY_CALLBACKS(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_MEMORY_CALLBACKS, ETableMemoryCallbacks)) -#define E_TABLE_MEMORY_CALLBACKS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_MEMORY_CALLBACKS, ETableMemoryCallbacksClass)) -#define E_IS_TABLE_MEMORY_CALLBACKS(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_MEMORY_CALLBACKS)) -#define E_IS_TABLE_MEMORY_CALLBACKS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_MEMORY_CALLBACKS)) -#define E_TABLE_MEMORY_CALLBACKS_GET_CLASS(cls) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((cls), E_TYPE_TABLE_MEMORY_CALLBACKS, ETableMemoryCallbacksClass)) - -G_BEGIN_DECLS - -typedef struct _ETableMemoryCallbacks ETableMemoryCallbacks; -typedef struct _ETableMemoryCallbacksClass ETableMemoryCallbacksClass; - -typedef gint (*ETableMemoryCallbacksColumnCountFn) - (ETableModel *etm, - gpointer data); -typedef void (*ETableMemoryCallbacksAppendRowFn) - (ETableModel *etm, - ETableModel *model, - gint row, - gpointer data); - -typedef gpointer (*ETableMemoryCallbacksValueAtFn) - (ETableModel *etm, - gint col, - gint row, - gpointer data); -typedef void (*ETableMemoryCallbacksSetValueAtFn) - (ETableModel *etm, - gint col, - gint row, - gconstpointer val, - gpointer data); -typedef gboolean (*ETableMemoryCallbacksIsCellEditableFn) - (ETableModel *etm, - gint col, - gint row, - gpointer data); - -typedef gpointer (*ETableMemoryCallbacksDuplicateValueFn) - (ETableModel *etm, - gint col, - gconstpointer val, - gpointer data); -typedef void (*ETableMemoryCallbacksFreeValueFn) - (ETableModel *etm, - gint col, - gpointer val, - gpointer data); -typedef gpointer (*ETableMemoryCallbacksInitializeValueFn) - (ETableModel *etm, - gint col, - gpointer data); -typedef gboolean (*ETableMemoryCallbacksValueIsEmptyFn) - (ETableModel *etm, - gint col, - gconstpointer val, - gpointer data); -typedef gchar * (*ETableMemoryCallbacksValueToStringFn) - (ETableModel *etm, - gint col, - gconstpointer val, - gpointer data); - -struct _ETableMemoryCallbacks { - ETableMemory parent; - - ETableMemoryCallbacksColumnCountFn col_count; - ETableMemoryCallbacksAppendRowFn append_row; - - ETableMemoryCallbacksValueAtFn value_at; - ETableMemoryCallbacksSetValueAtFn set_value_at; - ETableMemoryCallbacksIsCellEditableFn is_cell_editable; - - ETableMemoryCallbacksDuplicateValueFn duplicate_value; - ETableMemoryCallbacksFreeValueFn free_value; - ETableMemoryCallbacksInitializeValueFn initialize_value; - ETableMemoryCallbacksValueIsEmptyFn value_is_empty; - ETableMemoryCallbacksValueToStringFn value_to_string; - gpointer data; -}; - -struct _ETableMemoryCallbacksClass { - ETableMemoryClass parent_class; -}; - -GType e_table_memory_callbacks_get_type - (void) G_GNUC_CONST; -ETableModel * e_table_memory_callbacks_new - (ETableMemoryCallbacksColumnCountFn col_count, - - ETableMemoryCallbacksValueAtFn value_at, - ETableMemoryCallbacksSetValueAtFn set_value_at, - ETableMemoryCallbacksIsCellEditableFn is_cell_editable, - - ETableMemoryCallbacksDuplicateValueFn duplicate_value, - ETableMemoryCallbacksFreeValueFn free_value, - ETableMemoryCallbacksInitializeValueFn initialize_value, - ETableMemoryCallbacksValueIsEmptyFn value_is_empty, - ETableMemoryCallbacksValueToStringFn value_to_string, - gpointer data); - -G_END_DECLS - -#endif /* _E_TABLE_MEMORY_CALLBACKS_H_ */ - diff --git a/widgets/table/e-table-memory-store.c b/widgets/table/e-table-memory-store.c deleted file mode 100644 index 950b58e31e..0000000000 --- a/widgets/table/e-table-memory-store.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-memory-store.h" - -#define E_TABLE_MEMORY_STORE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TABLE_MEMORY_STORE, ETableMemoryStorePrivate)) - -#define STORE_LOCATOR(etms, col, row) (*((etms)->priv->store + (row) * (etms)->priv->col_count + (col))) - -struct _ETableMemoryStorePrivate { - gint col_count; - ETableMemoryStoreColumnInfo *columns; - gpointer *store; -}; - -G_DEFINE_TYPE (ETableMemoryStore, e_table_memory_store, E_TYPE_TABLE_MEMORY) - -static gpointer -duplicate_value (ETableMemoryStore *etms, - gint col, - gconstpointer val) -{ - switch (etms->priv->columns[col].type) { - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING: - return g_strdup (val); - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF: - if (val) - g_object_ref ((gpointer) val); - return (gpointer) val; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT: - if (val) - g_object_ref ((gpointer) val); - return (gpointer) val; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM: - if (etms->priv->columns[col].custom.duplicate_value) - return etms->priv->columns[col].custom.duplicate_value (E_TABLE_MODEL (etms), col, val, NULL); - break; - default: - break; - } - return (gpointer) val; -} - -static void -free_value (ETableMemoryStore *etms, - gint col, - gpointer value) -{ - switch (etms->priv->columns[col].type) { - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING: - g_free (value); - break; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF: - if (value) - g_object_unref (value); - break; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT: - if (value) - g_object_unref (value); - break; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM: - if (etms->priv->columns[col].custom.free_value) - etms->priv->columns[col].custom.free_value (E_TABLE_MODEL (etms), col, value, NULL); - break; - default: - break; - } -} - -static gint -etms_column_count (ETableModel *etm) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - return etms->priv->col_count; -} - -static gpointer -etms_value_at (ETableModel *etm, - gint col, - gint row) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - return STORE_LOCATOR (etms, col, row); -} - -static void -etms_set_value_at (ETableModel *etm, - gint col, - gint row, - gconstpointer val) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - e_table_model_pre_change (etm); - - STORE_LOCATOR (etms, col, row) = duplicate_value (etms, col, val); - - e_table_model_cell_changed (etm, col, row); -} - -static gboolean -etms_is_cell_editable (ETableModel *etm, - gint col, - gint row) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - return etms->priv->columns[col].editable; -} - -/* The default for etms_duplicate_value is to return the raw value. */ -static gpointer -etms_duplicate_value (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - return duplicate_value (etms, col, value); -} - -static void -etms_free_value (ETableModel *etm, - gint col, - gpointer value) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - free_value (etms, col, value); -} - -static gpointer -etms_initialize_value (ETableModel *etm, - gint col) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - switch (etms->priv->columns[col].type) { - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING: - return g_strdup (""); - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF: - return NULL; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM: - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT: - if (etms->priv->columns[col].custom.initialize_value) - return etms->priv->columns[col].custom.initialize_value (E_TABLE_MODEL (etms), col, NULL); - break; - default: - break; - } - return NULL; -} - -static gboolean -etms_value_is_empty (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - switch (etms->priv->columns[col].type) { - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING: - return !(value && *(gchar *) value); - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF: - return value == NULL; - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM: - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT: - if (etms->priv->columns[col].custom.value_is_empty) - return etms->priv->columns[col].custom.value_is_empty (E_TABLE_MODEL (etms), col, value, NULL); - break; - default: - break; - } - return value == NULL; -} - -static gchar * -etms_value_to_string (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - - switch (etms->priv->columns[col].type) { - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING: - return g_strdup (value); - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF: - return g_strdup (""); - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM: - case E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT: - if (etms->priv->columns[col].custom.value_is_empty) - return etms->priv->columns[col].custom.value_to_string (E_TABLE_MODEL (etms), col, value, NULL); - break; - default: - break; - } - return g_strdup_printf ("%d", GPOINTER_TO_INT (value)); -} - -static void -etms_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ - ETableMemoryStore *etms = E_TABLE_MEMORY_STORE (etm); - gpointer *new_data; - gint i; - gint row_count; - - new_data = g_new (gpointer , etms->priv->col_count); - - for (i = 0; i < etms->priv->col_count; i++) { - new_data[i] = e_table_model_value_at (source, i, row); - } - - row_count = e_table_model_row_count (E_TABLE_MODEL (etms)); - - e_table_memory_store_insert_array (etms, row_count, new_data, NULL); -} - -static void -etms_finalize (GObject *object) -{ - ETableMemoryStorePrivate *priv; - - priv = E_TABLE_MEMORY_STORE_GET_PRIVATE (object); - - e_table_memory_store_clear (E_TABLE_MEMORY_STORE (object)); - - g_free (priv->columns); - g_free (priv->store); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_table_memory_store_parent_class)->finalize (object); -} - -static void -e_table_memory_store_init (ETableMemoryStore *etms) -{ - etms->priv = E_TABLE_MEMORY_STORE_GET_PRIVATE (etms); -} - -static void -e_table_memory_store_class_init (ETableMemoryStoreClass *class) -{ - GObjectClass *object_class; - ETableModelClass *model_class; - - g_type_class_add_private (class, sizeof (ETableMemoryStorePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = etms_finalize; - - model_class = E_TABLE_MODEL_CLASS (class); - model_class->column_count = etms_column_count; - model_class->value_at = etms_value_at; - model_class->set_value_at = etms_set_value_at; - model_class->is_cell_editable = etms_is_cell_editable; - model_class->duplicate_value = etms_duplicate_value; - model_class->free_value = etms_free_value; - model_class->initialize_value = etms_initialize_value; - model_class->value_is_empty = etms_value_is_empty; - model_class->value_to_string = etms_value_to_string; - model_class->append_row = etms_append_row; -} - -/** - * e_table_memory_store_new: - * @col_count: - * @value_at: - * @set_value_at: - * @is_cell_editable: - * @duplicate_value: - * @free_value: - * @initialize_value: - * @value_is_empty: - * @value_to_string: - * @data: closure pointer. - * - * This initializes a new ETableMemoryStoreModel object. ETableMemoryStoreModel is - * an implementaiton of the abstract class ETableModel. The ETableMemoryStoreModel - * is designed to allow people to easily create ETableModels without having - * to create a new GType derived from ETableModel every time they need one. - * - * Instead, ETableMemoryStoreModel uses a setup based in callback functions, every - * callback function signature mimics the signature of each ETableModel method - * and passes the extra @data pointer to each one of the method to provide them - * with any context they might want to use. - * - * Returns: An ETableMemoryStoreModel object (which is also an ETableModel - * object). - */ -ETableModel * -e_table_memory_store_new (ETableMemoryStoreColumnInfo *columns) -{ - ETableMemoryStore *et = g_object_new (E_TYPE_TABLE_MEMORY_STORE, NULL); - - if (e_table_memory_store_construct (et, columns)) { - return (ETableModel *) et; - } else { - g_object_unref (et); - return NULL; - } -} - -ETableModel * -e_table_memory_store_construct (ETableMemoryStore *etms, - ETableMemoryStoreColumnInfo *columns) -{ - gint i; - for (i = 0; columns[i].type != E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR; i++) - /* Intentionally blank */; - etms->priv->col_count = i; - - etms->priv->columns = g_new (ETableMemoryStoreColumnInfo, etms->priv->col_count + 1); - - memcpy (etms->priv->columns, columns, (etms->priv->col_count + 1) * sizeof (ETableMemoryStoreColumnInfo)); - - return E_TABLE_MODEL (etms); -} - -void -e_table_memory_store_adopt_value_at (ETableMemoryStore *etms, - gint col, - gint row, - gpointer value) -{ - e_table_model_pre_change (E_TABLE_MODEL (etms)); - - STORE_LOCATOR (etms, col, row) = value; - - e_table_model_cell_changed (E_TABLE_MODEL (etms), col, row); -} - -/* The size of these arrays is the number of columns. */ -void -e_table_memory_store_insert_array (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data) -{ - gint row_count; - gint i; - - row_count = e_table_model_row_count (E_TABLE_MODEL (etms)) + 1; - if (row == -1) - row = row_count - 1; - etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (gpointer)); - memmove ( - etms->priv->store + etms->priv->col_count * (row + 1), - etms->priv->store + etms->priv->col_count * row, - etms->priv->col_count * (row_count - row - 1) * sizeof (gpointer)); - - for (i = 0; i < etms->priv->col_count; i++) { - STORE_LOCATOR (etms, i, row) = duplicate_value (etms, i, store[i]); - } - - e_table_memory_insert (E_TABLE_MEMORY (etms), row, data); -} - -void -e_table_memory_store_insert (ETableMemoryStore *etms, - gint row, - gpointer data, - ...) -{ - gpointer *store; - va_list args; - gint i; - - store = g_new (gpointer , etms->priv->col_count + 1); - - va_start (args, data); - for (i = 0; i < etms->priv->col_count; i++) { - store[i] = va_arg (args, gpointer); - } - va_end (args); - - e_table_memory_store_insert_array (etms, row, store, data); - - g_free (store); -} - -void -e_table_memory_store_insert_adopt_array (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data) -{ - gint row_count; - gint i; - - row_count = e_table_model_row_count (E_TABLE_MODEL (etms)) + 1; - if (row == -1) - row = row_count - 1; - etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (gpointer)); - memmove ( - etms->priv->store + etms->priv->col_count * (row + 1), - etms->priv->store + etms->priv->col_count * row, - etms->priv->col_count * (row_count - row - 1) * sizeof (gpointer)); - - for (i = 0; i < etms->priv->col_count; i++) { - STORE_LOCATOR (etms, i, row) = store[i]; - } - - e_table_memory_insert (E_TABLE_MEMORY (etms), row, data); -} - -void -e_table_memory_store_insert_adopt (ETableMemoryStore *etms, - gint row, - gpointer data, - ...) -{ - gpointer *store; - va_list args; - gint i; - - store = g_new (gpointer , etms->priv->col_count + 1); - - va_start (args, data); - for (i = 0; i < etms->priv->col_count; i++) { - store[i] = va_arg (args, gpointer); - } - va_end (args); - - e_table_memory_store_insert_adopt_array (etms, row, store, data); - - g_free (store); -} - -/** - * e_table_memory_store_change_array: - * @etms: the ETabelMemoryStore. - * @row: the row we're changing. - * @store: an array of new values to fill the row - * @data: the new closure to associate with this row. - * - * frees existing values associated with a row and replaces them with - * duplicates of the values in store. - * - */ -void -e_table_memory_store_change_array (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data) -{ - gint i; - - g_return_if_fail (row >= 0 && row < e_table_model_row_count (E_TABLE_MODEL (etms))); - - e_table_model_pre_change (E_TABLE_MODEL (etms)); - - for (i = 0; i < etms->priv->col_count; i++) { - free_value (etms, i, STORE_LOCATOR (etms, i, row)); - STORE_LOCATOR (etms, i, row) = duplicate_value (etms, i, store[i]); - } - - e_table_memory_set_data (E_TABLE_MEMORY (etms), row, data); - e_table_model_row_changed (E_TABLE_MODEL (etms), row); -} - -/** - * e_table_memory_store_change: - * @etms: the ETabelMemoryStore. - * @row: the row we're changing. - * @data: the new closure to associate with this row. - * - * a varargs version of e_table_memory_store_change_array. you must - * pass in etms->col_count args. - */ -void -e_table_memory_store_change (ETableMemoryStore *etms, - gint row, - gpointer data, - ...) -{ - gpointer *store; - va_list args; - gint i; - - g_return_if_fail (row >= 0 && row < e_table_model_row_count (E_TABLE_MODEL (etms))); - - store = g_new0 (gpointer , etms->priv->col_count + 1); - - va_start (args, data); - for (i = 0; i < etms->priv->col_count; i++) { - store[i] = va_arg (args, gpointer); - } - va_end (args); - - e_table_memory_store_change_array (etms, row, store, data); - - g_free (store); -} - -/** - * e_table_memory_store_change_adopt_array: - * @etms: the ETableMemoryStore - * @row: the row we're changing. - * @store: an array of new values to fill the row - * @data: the new closure to associate with this row. - * - * frees existing values for the row and stores the values from store - * into it. This function differs from - * e_table_memory_storage_change_adopt_array in that it does not - * duplicate the data. - */ -void -e_table_memory_store_change_adopt_array (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data) -{ - gint i; - - g_return_if_fail (row >= 0 && row < e_table_model_row_count (E_TABLE_MODEL (etms))); - - for (i = 0; i < etms->priv->col_count; i++) { - free_value (etms, i, STORE_LOCATOR (etms, i, row)); - STORE_LOCATOR (etms, i, row) = store[i]; - } - - e_table_memory_set_data (E_TABLE_MEMORY (etms), row, data); - e_table_model_row_changed (E_TABLE_MODEL (etms), row); -} - -/** - * e_table_memory_store_change_adopt - * @etms: the ETabelMemoryStore. - * @row: the row we're changing. - * @data: the new closure to associate with this row. - * - * a varargs version of e_table_memory_store_change_adopt_array. you - * must pass in etms->col_count args. - */ -void -e_table_memory_store_change_adopt (ETableMemoryStore *etms, - gint row, - gpointer data, - ...) -{ - gpointer *store; - va_list args; - gint i; - - g_return_if_fail (row >= 0 && row < e_table_model_row_count (E_TABLE_MODEL (etms))); - - store = g_new0 (gpointer , etms->priv->col_count + 1); - - va_start (args, data); - for (i = 0; i < etms->priv->col_count; i++) { - store[i] = va_arg (args, gpointer); - } - va_end (args); - - e_table_memory_store_change_adopt_array (etms, row, store, data); - - g_free (store); -} - -void -e_table_memory_store_remove (ETableMemoryStore *etms, - gint row) -{ - ETableModel *model; - gint column_count, row_count; - gint i; - - model = E_TABLE_MODEL (etms); - column_count = e_table_model_column_count (model); - - for (i = 0; i < column_count; i++) - e_table_model_free_value (model, i, e_table_model_value_at (model, i, row)); - - row_count = e_table_model_row_count (E_TABLE_MODEL (etms)) - 1; - memmove ( - etms->priv->store + etms->priv->col_count * row, - etms->priv->store + etms->priv->col_count * (row + 1), - etms->priv->col_count * (row_count - row) * sizeof (gpointer)); - etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (gpointer)); - - e_table_memory_remove (E_TABLE_MEMORY (etms), row); -} - -void -e_table_memory_store_clear (ETableMemoryStore *etms) -{ - ETableModel *model; - gint row_count, column_count; - gint i, j; - - model = E_TABLE_MODEL (etms); - row_count = e_table_model_row_count (model); - column_count = e_table_model_column_count (model); - - for (i = 0; i < row_count; i++) { - for (j = 0; j < column_count; j++) { - e_table_model_free_value (model, j, e_table_model_value_at (model, j, i)); - } - } - - e_table_memory_clear (E_TABLE_MEMORY (etms)); - - g_free (etms->priv->store); - etms->priv->store = NULL; -} diff --git a/widgets/table/e-table-memory-store.h b/widgets/table/e-table-memory-store.h deleted file mode 100644 index 9d3d638e18..0000000000 --- a/widgets/table/e-table-memory-store.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_MEMORY_STORE_H_ -#define _E_TABLE_MEMORY_STORE_H_ - -#include <table/e-table-memory.h> -#include <table/e-table-memory-callbacks.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_MEMORY_STORE \ - (e_table_memory_store_get_type ()) -#define E_TABLE_MEMORY_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_MEMORY_STORE, ETableMemoryStore)) -#define E_TABLE_MEMORY_STORE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_MEMORY_STORE, ETableMemoryStoreClass)) -#define E_IS_TABLE_MEMORY_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_MEMORY_STORE)) -#define E_IS_TABLE_MEMORY_STORE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_MEMORY_STORE)) -#define E_TABLE_MEMORY_STORE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_MEMORY_STORE, ETableMemoryStoreClass)) - -G_BEGIN_DECLS - -typedef enum { - E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR, - E_TABLE_MEMORY_STORE_COLUMN_TYPE_INTEGER, - E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING, - E_TABLE_MEMORY_STORE_COLUMN_TYPE_PIXBUF, - E_TABLE_MEMORY_STORE_COLUMN_TYPE_OBJECT, - E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM -} ETableMemoryStoreColumnType; - -typedef struct { - ETableMemoryCallbacksDuplicateValueFn duplicate_value; - ETableMemoryCallbacksFreeValueFn free_value; - ETableMemoryCallbacksInitializeValueFn initialize_value; - ETableMemoryCallbacksValueIsEmptyFn value_is_empty; - ETableMemoryCallbacksValueToStringFn value_to_string; -} ETableMemoryStoreCustomColumn; - -typedef struct { - ETableMemoryStoreColumnType type; - ETableMemoryStoreCustomColumn custom; - guint editable : 1; -} ETableMemoryStoreColumnInfo; - -#define E_TABLE_MEMORY_STORE_TERMINATOR \ - { E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR, { NULL }, FALSE } -#define E_TABLE_MEMORY_STORE_INTEGER \ - { E_TABLE_MEMORY_STORE_COLUMN_TYPE_INTEGER, { NULL }, FALSE } -#define E_TABLE_MEMORY_STORE_STRING \ - { E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING, { NULL }, FALSE } - -typedef struct _ETableMemoryStore ETableMemoryStore; -typedef struct _ETableMemoryStoreClass ETableMemoryStoreClass; -typedef struct _ETableMemoryStorePrivate ETableMemoryStorePrivate; - -struct _ETableMemoryStore { - ETableMemory parent; - ETableMemoryStorePrivate *priv; -}; - -struct _ETableMemoryStoreClass { - ETableMemoryClass parent_class; -}; - -GType e_table_memory_store_get_type (void) G_GNUC_CONST; -ETableModel * e_table_memory_store_new (ETableMemoryStoreColumnInfo *columns); -ETableModel * e_table_memory_store_construct (ETableMemoryStore *store, - ETableMemoryStoreColumnInfo *columns); - -/* Adopt a value instead of copying it. */ -void e_table_memory_store_adopt_value_at - (ETableMemoryStore *etms, - gint col, - gint row, - gpointer value); - -/* The size of these arrays is the number of columns. */ -void e_table_memory_store_insert_array - (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data); -void e_table_memory_store_insert (ETableMemoryStore *etms, - gint row, - gpointer data, - ...); -void e_table_memory_store_insert_adopt - (ETableMemoryStore *etms, - gint row, - gpointer data, - ...); -void e_table_memory_store_insert_adopt_array - (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data); -void e_table_memory_store_change_array - (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data); -void e_table_memory_store_change (ETableMemoryStore *etms, - gint row, - gpointer data, - ...); -void e_table_memory_store_change_adopt - (ETableMemoryStore *etms, - gint row, - gpointer data, - ...); -void e_table_memory_store_change_adopt_array - (ETableMemoryStore *etms, - gint row, - gpointer *store, - gpointer data); -void e_table_memory_store_remove (ETableMemoryStore *etms, - gint row); -void e_table_memory_store_clear (ETableMemoryStore *etms); - -G_END_DECLS - -#endif /* _E_TABLE_MEMORY_STORE_H_ */ diff --git a/widgets/table/e-table-memory.c b/widgets/table/e-table-memory.c deleted file mode 100644 index 58c1f8415a..0000000000 --- a/widgets/table/e-table-memory.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> - -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-memory.h" - -#define E_TABLE_MEMORY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TABLE_MEMORY, ETableMemoryPrivate)) - -G_DEFINE_TYPE (ETableMemory, e_table_memory, E_TYPE_TABLE_MODEL) - -struct _ETableMemoryPrivate { - gpointer *data; - gint num_rows; - gint frozen; -}; - -static void -etmm_finalize (GObject *object) -{ - ETableMemoryPrivate *priv; - - priv = E_TABLE_MEMORY_GET_PRIVATE (object); - - g_free (priv->data); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_table_memory_parent_class)->finalize (object); -} - -static gint -etmm_row_count (ETableModel *etm) -{ - ETableMemory *etmm = E_TABLE_MEMORY (etm); - - return etmm->priv->num_rows; -} - -static void -e_table_memory_class_init (ETableMemoryClass *class) -{ - GObjectClass *object_class; - ETableModelClass *table_model_class; - - g_type_class_add_private (class, sizeof (ETableMemoryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = etmm_finalize; - - table_model_class = E_TABLE_MODEL_CLASS (class); - table_model_class->row_count = etmm_row_count; -} - -static void -e_table_memory_init (ETableMemory *etmm) -{ - etmm->priv = E_TABLE_MEMORY_GET_PRIVATE (etmm); -} - -/** - * e_table_memory_new - * - * XXX docs here. - * - * return values: a newly constructed ETableMemory. - */ -ETableMemory * -e_table_memory_new (void) -{ - return g_object_new (E_TYPE_TABLE_MEMORY, NULL); -} - -/** - * e_table_memory_get_data: - * @etmm: - * @row: - * - * - * - * Return value: - **/ -gpointer -e_table_memory_get_data (ETableMemory *etmm, - gint row) -{ - g_return_val_if_fail (row >= 0, NULL); - g_return_val_if_fail (row < etmm->priv->num_rows, NULL); - - return etmm->priv->data[row]; -} - -/** - * e_table_memory_set_data: - * @etmm: - * @row: - * @data: - * - * - **/ -void -e_table_memory_set_data (ETableMemory *etmm, - gint row, - gpointer data) -{ - g_return_if_fail (row >= 0); - g_return_if_fail (row < etmm->priv->num_rows); - - etmm->priv->data[row] = data; -} - -/** - * e_table_memory_insert: - * @table_model: - * @parent_path: - * @position: - * @data: - * - * - * - * Return value: - **/ -void -e_table_memory_insert (ETableMemory *etmm, - gint row, - gpointer data) -{ - g_return_if_fail (row >= -1); - g_return_if_fail (row <= etmm->priv->num_rows); - - if (!etmm->priv->frozen) - e_table_model_pre_change (E_TABLE_MODEL (etmm)); - - if (row == -1) - row = etmm->priv->num_rows; - etmm->priv->data = g_renew (gpointer, etmm->priv->data, etmm->priv->num_rows + 1); - memmove ( - etmm->priv->data + row + 1, - etmm->priv->data + row, - (etmm->priv->num_rows - row) * sizeof (gpointer)); - etmm->priv->data[row] = data; - etmm->priv->num_rows++; - if (!etmm->priv->frozen) - e_table_model_row_inserted (E_TABLE_MODEL (etmm), row); -} - -/** - * e_table_memory_remove: - * @etable: - * @path: - * - * - * - * Return value: - **/ -gpointer -e_table_memory_remove (ETableMemory *etmm, - gint row) -{ - gpointer ret; - - g_return_val_if_fail (row >= 0, NULL); - g_return_val_if_fail (row < etmm->priv->num_rows, NULL); - - if (!etmm->priv->frozen) - e_table_model_pre_change (E_TABLE_MODEL (etmm)); - ret = etmm->priv->data[row]; - memmove ( - etmm->priv->data + row, - etmm->priv->data + row + 1, - (etmm->priv->num_rows - row - 1) * sizeof (gpointer)); - etmm->priv->num_rows--; - if (!etmm->priv->frozen) - e_table_model_row_deleted (E_TABLE_MODEL (etmm), row); - return ret; -} - -/** - * e_table_memory_clear: - * @etable: - * @path: - * - * - * - * Return value: - **/ -void -e_table_memory_clear (ETableMemory *etmm) -{ - if (!etmm->priv->frozen) - e_table_model_pre_change (E_TABLE_MODEL (etmm)); - g_free (etmm->priv->data); - etmm->priv->data = NULL; - etmm->priv->num_rows = 0; - if (!etmm->priv->frozen) - e_table_model_changed (E_TABLE_MODEL (etmm)); -} - -/** - * e_table_memory_freeze: - * @etmm: the ETableModel to freeze. - * - * This function prepares an ETableModel for a period of much change. - * All signals regarding changes to the table are deferred until we - * thaw the table. - * - **/ -void -e_table_memory_freeze (ETableMemory *etmm) -{ - ETableMemoryPrivate *priv = etmm->priv; - - if (priv->frozen == 0) - e_table_model_pre_change (E_TABLE_MODEL (etmm)); - - priv->frozen++; -} - -/** - * e_table_memory_thaw: - * @etmm: the ETableMemory to thaw. - * - * This function thaws an ETableMemory. All the defered signals can add - * up to a lot, we don't know - so we just emit a model_changed - * signal. - * - **/ -void -e_table_memory_thaw (ETableMemory *etmm) -{ - ETableMemoryPrivate *priv = etmm->priv; - - if (priv->frozen > 0) - priv->frozen--; - if (priv->frozen == 0) { - e_table_model_changed (E_TABLE_MODEL (etmm)); - } -} diff --git a/widgets/table/e-table-memory.h b/widgets/table/e-table-memory.h deleted file mode 100644 index 853f378c9e..0000000000 --- a/widgets/table/e-table-memory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_MEMORY_H_ -#define _E_TABLE_MEMORY_H_ - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <table/e-table-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_MEMORY \ - (e_table_memory_get_type ()) -#define E_TABLE_MEMORY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_MEMORY, ETableMemory)) -#define E_TABLE_MEMORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_MEMORY, ETableMemoryClass)) -#define E_IS_TABLE_MEMORY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_MEMORY)) -#define E_IS_TABLE_MEMORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_MEMORY)) -#define E_TABLE_MEMORY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_MEMORY, ETableMemoryClass)) - -G_BEGIN_DECLS - -typedef struct _ETableMemory ETableMemory; -typedef struct _ETableMemoryClass ETableMemoryClass; -typedef struct _ETableMemoryPrivate ETableMemoryPrivate; - -struct _ETableMemory { - ETableModel parent; - ETableMemoryPrivate *priv; -}; - -struct _ETableMemoryClass { - ETableModelClass parent_class; -}; - -GType e_table_memory_get_type (void) G_GNUC_CONST; -ETableMemory * e_table_memory_new (void); -void e_table_memory_construct (ETableMemory *etable); - -/* row operations */ -void e_table_memory_insert (ETableMemory *etable, - gint row, - gpointer data); -gpointer e_table_memory_remove (ETableMemory *etable, - gint row); -void e_table_memory_clear (ETableMemory *etable); - -/* Freeze and thaw */ -void e_table_memory_freeze (ETableMemory *etable); -void e_table_memory_thaw (ETableMemory *etable); -gpointer e_table_memory_get_data (ETableMemory *etm, - gint row); -void e_table_memory_set_data (ETableMemory *etm, - gint row, - gpointer data); - -G_END_DECLS - -#endif /* _E_TABLE_MEMORY_H */ diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c deleted file mode 100644 index 99479f94ee..0000000000 --- a/widgets/table/e-table-model.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-util.h" - -#include "e-table-model.h" - -#define ETM_FROZEN(e) \ - (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (e), "frozen")) != 0) - -#define d(x) - -d (static gint depth = 0;) - -G_DEFINE_TYPE (ETableModel, e_table_model, G_TYPE_OBJECT) - -enum { - MODEL_NO_CHANGE, - MODEL_CHANGED, - MODEL_PRE_CHANGE, - MODEL_ROW_CHANGED, - MODEL_CELL_CHANGED, - MODEL_ROWS_INSERTED, - MODEL_ROWS_DELETED, - ROW_SELECTION, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -/** - * e_table_model_column_count: - * @e_table_model: The e-table-model to operate on - * - * Returns: the number of columns in the table model. - */ -gint -e_table_model_column_count (ETableModel *e_table_model) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - g_return_val_if_fail (class->column_count != NULL, 0); - - return class->column_count (e_table_model); -} - -/** - * e_table_model_row_count: - * @e_table_model: the e-table-model to operate on - * - * Returns: the number of rows in the Table model. - */ -gint -e_table_model_row_count (ETableModel *e_table_model) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - g_return_val_if_fail (class->row_count != NULL, 0); - - return class->row_count (e_table_model); -} - -/** - * e_table_model_append_row: - * @e_table_model: the table model to append the a row to. - * @source: - * @row: - * - */ -void -e_table_model_append_row (ETableModel *e_table_model, - ETableModel *source, - gint row) -{ - ETableModelClass *class; - - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->append_row != NULL) - class->append_row (e_table_model, source, row); -} - -/** - * e_table_value_at: - * @e_table_model: the e-table-model to operate on - * @col: column in the model to pull data from. - * @row: row in the model to pull data from. - * - * Return value: This function returns the value that is stored - * by the @e_table_model in column @col and row @row. The data - * returned can be a pointer or any data value that can be stored - * inside a pointer. - * - * The data returned is typically used by an ECell renderer. - * - * The data returned must be valid until the model sends a signal that - * affect that piece of data. model_changed affects all data. - * row_changed affects the data in that row. cell_changed affects the - * data in that cell. rows_deleted affects all data in those rows. - * rows_inserted and no_change don't affect any data in this way. - **/ -gpointer -e_table_model_value_at (ETableModel *e_table_model, - gint col, - gint row) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - g_return_val_if_fail (class->value_at != NULL, NULL); - - return class->value_at (e_table_model, col, row); -} - -/** - * e_table_model_set_value_at: - * @e_table_model: the table model to operate on. - * @col: the column where the data will be stored in the model. - * @row: the row where the data will be stored in the model. - * @value: the data to be stored. - * - * This function instructs the model to store the value in @data in the - * the @e_table_model at column @col and row @row. The @data typically - * comes from one of the ECell rendering objects. - * - * There should be an agreement between the Table Model and the user - * of this function about the data being stored. Typically it will - * be a pointer to a set of data, or a datum that fits inside a gpointer . - */ -void -e_table_model_set_value_at (ETableModel *e_table_model, - gint col, - gint row, - gconstpointer value) -{ - ETableModelClass *class; - - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - g_return_if_fail (class->set_value_at != NULL); - - class->set_value_at (e_table_model, col, row, value); -} - -/** - * e_table_model_is_cell_editable: - * @e_table_model: the table model to query. - * @col: column to query. - * @row: row to query. - * - * Returns: %TRUE if the cell in @e_table_model at @col,@row can be - * edited, %FALSE otherwise - */ -gboolean -e_table_model_is_cell_editable (ETableModel *e_table_model, - gint col, - gint row) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - g_return_val_if_fail (class->is_cell_editable != NULL, FALSE); - - return class->is_cell_editable (e_table_model, col, row); -} - -gpointer -e_table_model_duplicate_value (ETableModel *e_table_model, - gint col, - gconstpointer value) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->duplicate_value == NULL) - return NULL; - - return class->duplicate_value (e_table_model, col, value); -} - -void -e_table_model_free_value (ETableModel *e_table_model, - gint col, - gpointer value) -{ - ETableModelClass *class; - - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->free_value != NULL) - class->free_value (e_table_model, col, value); -} - -gboolean -e_table_model_has_save_id (ETableModel *e_table_model) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->has_save_id == NULL) - return FALSE; - - return class->has_save_id (e_table_model); -} - -gchar * -e_table_model_get_save_id (ETableModel *e_table_model, - gint row) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->get_save_id == NULL) - return NULL; - - return class->get_save_id (e_table_model, row); -} - -gboolean -e_table_model_has_change_pending (ETableModel *e_table_model) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->has_change_pending == NULL) - return FALSE; - - return class->has_change_pending (e_table_model); -} - -gpointer -e_table_model_initialize_value (ETableModel *e_table_model, - gint col) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->initialize_value == NULL) - return NULL; - - return class->initialize_value (e_table_model, col); -} - -gboolean -e_table_model_value_is_empty (ETableModel *e_table_model, - gint col, - gconstpointer value) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->value_is_empty == NULL) - return FALSE; - - return class->value_is_empty (e_table_model, col, value); -} - -gchar * -e_table_model_value_to_string (ETableModel *e_table_model, - gint col, - gconstpointer value) -{ - ETableModelClass *class; - - g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL); - - class = E_TABLE_MODEL_GET_CLASS (e_table_model); - - if (class->value_to_string == NULL) - return g_strdup (""); - - return class->value_to_string (e_table_model, col, value); -} - -static void -e_table_model_class_init (ETableModelClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - signals[MODEL_NO_CHANGE] = g_signal_new ( - "model_no_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_no_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[MODEL_CHANGED] = g_signal_new ( - "model_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[MODEL_PRE_CHANGE] = g_signal_new ( - "model_pre_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_pre_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[MODEL_ROW_CHANGED] = g_signal_new ( - "model_row_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_row_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - signals[MODEL_CELL_CHANGED] = g_signal_new ( - "model_cell_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_cell_changed), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - signals[MODEL_ROWS_INSERTED] = g_signal_new ( - "model_rows_inserted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_rows_inserted), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - signals[MODEL_ROWS_DELETED] = g_signal_new ( - "model_rows_deleted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableModelClass, model_rows_deleted), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - class->column_count = NULL; - class->row_count = NULL; - class->append_row = NULL; - - class->value_at = NULL; - class->set_value_at = NULL; - class->is_cell_editable = NULL; - - class->has_save_id = NULL; - class->get_save_id = NULL; - - class->has_change_pending = NULL; - - class->duplicate_value = NULL; - class->free_value = NULL; - class->initialize_value = NULL; - class->value_is_empty = NULL; - class->value_to_string = NULL; - - class->model_no_change = NULL; - class->model_changed = NULL; - class->model_row_changed = NULL; - class->model_cell_changed = NULL; - class->model_rows_inserted = NULL; - class->model_rows_deleted = NULL; -} - -static void -e_table_model_init (ETableModel *e_table_model) -{ - /* nothing to do */ -} - -#if d(!)0 -static void -print_tabs (void) -{ - gint i; - for (i = 0; i < depth; i++) - g_print ("\t"); -} -#endif - -void -e_table_model_pre_change (ETableModel *e_table_model) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit (e_table_model, signals[MODEL_PRE_CHANGE], 0); - d (depth--); -} - -/** - * e_table_model_no_change: - * @e_table_model: the table model to notify of the lack of a change - * - * Use this function to notify any views of this table model that - * the contents of the table model have changed. This will emit - * the signal "model_no_change" on the @e_table_model object. - * - * It is preferable to use the e_table_model_row_changed() and - * the e_table_model_cell_changed() to notify of smaller changes - * than to invalidate the entire model, as the views might have - * ways of caching the information they render from the model. - */ -void -e_table_model_no_change (ETableModel *e_table_model) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit (e_table_model, signals[MODEL_NO_CHANGE], 0); - d (depth--); -} - -/** - * e_table_model_changed: - * @e_table_model: the table model to notify of the change - * - * Use this function to notify any views of this table model that - * the contents of the table model have changed. This will emit - * the signal "model_changed" on the @e_table_model object. - * - * It is preferable to use the e_table_model_row_changed() and - * the e_table_model_cell_changed() to notify of smaller changes - * than to invalidate the entire model, as the views might have - * ways of caching the information they render from the model. - */ -void -e_table_model_changed (ETableModel *e_table_model) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit (e_table_model, signals[MODEL_CHANGED], 0); - d (depth--); -} - -/** - * e_table_model_row_changed: - * @e_table_model: the table model to notify of the change - * @row: the row that was changed in the model. - * - * Use this function to notify any views of the table model that - * the contents of row @row have changed in model. This function - * will emit the "model_row_changed" signal on the @e_table_model - * object - */ -void -e_table_model_row_changed (ETableModel *e_table_model, - gint row) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit (e_table_model, signals[MODEL_ROW_CHANGED], 0, row); - d (depth--); -} - -/** - * e_table_model_cell_changed: - * @e_table_model: the table model to notify of the change - * @col: the column. - * @row: the row - * - * Use this function to notify any views of the table model that - * contents of the cell at @col,@row has changed. This will emit - * the "model_cell_changed" signal on the @e_table_model - * object - */ -void -e_table_model_cell_changed (ETableModel *e_table_model, - gint col, - gint row) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit ( - e_table_model, signals[MODEL_CELL_CHANGED], 0, col, row); - d (depth--); -} - -/** - * e_table_model_rows_inserted: - * @e_table_model: the table model to notify of the change - * @row: the row that was inserted into the model. - * @count: The number of rows that were inserted. - * - * Use this function to notify any views of the table model that - * @count rows at row @row have been inserted into the model. This - * function will emit the "model_rows_inserted" signal on the - * @e_table_model object - */ -void -e_table_model_rows_inserted (ETableModel *e_table_model, - gint row, - gint count) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit ( - e_table_model, signals[MODEL_ROWS_INSERTED], 0, row, count); - d (depth--); -} - -/** - * e_table_model_row_inserted: - * @e_table_model: the table model to notify of the change - * @row: the row that was inserted into the model. - * - * Use this function to notify any views of the table model that the - * row @row has been inserted into the model. This function will emit - * the "model_rows_inserted" signal on the @e_table_model object - */ -void -e_table_model_row_inserted (ETableModel *e_table_model, - gint row) -{ - e_table_model_rows_inserted (e_table_model, row, 1); -} - -/** - * e_table_model_row_deleted: - * @e_table_model: the table model to notify of the change - * @row: the row that was deleted - * @count: The number of rows deleted - * - * Use this function to notify any views of the table model that - * @count rows at row @row have been deleted from the model. This - * function will emit the "model_rows_deleted" signal on the - * @e_table_model object - */ -void -e_table_model_rows_deleted (ETableModel *e_table_model, - gint row, - gint count) -{ - g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); - - if (ETM_FROZEN (e_table_model)) - return; - - d (print_tabs ()); - d (depth++); - g_signal_emit ( - e_table_model, signals[MODEL_ROWS_DELETED], 0, row, count); - d (depth--); -} - -/** - * e_table_model_row_deleted: - * @e_table_model: the table model to notify of the change - * @row: the row that was deleted - * - * Use this function to notify any views of the table model that the - * row @row has been deleted from the model. This function will emit - * the "model_rows_deleted" signal on the @e_table_model object - */ -void -e_table_model_row_deleted (ETableModel *e_table_model, - gint row) -{ - e_table_model_rows_deleted (e_table_model, row, 1); -} - -void -e_table_model_freeze (ETableModel *e_table_model) -{ - e_table_model_pre_change (e_table_model); - - /* FIXME This expression is awesome! */ - g_object_set_data ( - G_OBJECT (e_table_model), "frozen", - GINT_TO_POINTER (GPOINTER_TO_INT ( - g_object_get_data (G_OBJECT (e_table_model), "frozen")) + 1)); -} - -void -e_table_model_thaw (ETableModel *e_table_model) -{ - /* FIXME This expression is awesome! */ - g_object_set_data ( - G_OBJECT (e_table_model), "frozen", - GINT_TO_POINTER (GPOINTER_TO_INT ( - g_object_get_data (G_OBJECT (e_table_model), "frozen")) - 1)); - - e_table_model_changed (e_table_model); -} - diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h deleted file mode 100644 index 2ff4eacebd..0000000000 --- a/widgets/table/e-table-model.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_MODEL_H_ -#define _E_TABLE_MODEL_H_ - -#include <glib-object.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_MODEL \ - (e_table_model_get_type ()) -#define E_TABLE_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_MODEL, ETableModel)) -#define E_TABLE_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_MODEL, ETableModelClass)) -#define E_IS_TABLE_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_MODEL)) -#define E_IS_TABLE_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_MODEL)) -#define E_TABLE_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_MODEL, ETableModelClass)) - -G_BEGIN_DECLS - -typedef struct _ETableModel ETableModel; -typedef struct _ETableModelClass ETableModelClass; - -struct _ETableModel { - GObject parent; -}; - -struct _ETableModelClass { - GObjectClass parent_class; - - /* - * Virtual methods - */ - gint (*column_count) (ETableModel *etm); - gint (*row_count) (ETableModel *etm); - void (*append_row) (ETableModel *etm, - ETableModel *source, - gint row); - - gpointer (*value_at) (ETableModel *etm, - gint col, - gint row); - void (*set_value_at) (ETableModel *etm, - gint col, - gint row, - gconstpointer value); - gboolean (*is_cell_editable) (ETableModel *etm, - gint col, - gint row); - - gboolean (*has_save_id) (ETableModel *etm); - gchar * (*get_save_id) (ETableModel *etm, - gint row); - - gboolean (*has_change_pending) (ETableModel *etm); - - /* Allocate a copy of the given value. */ - gpointer (*duplicate_value) (ETableModel *etm, - gint col, - gconstpointer value); - /* Free an allocated value. */ - void (*free_value) (ETableModel *etm, - gint col, - gpointer value); - /* Return an allocated empty value. */ - gpointer (*initialize_value) (ETableModel *etm, - gint col); - /* Return TRUE if value is equivalent to an empty cell. */ - gboolean (*value_is_empty) (ETableModel *etm, - gint col, - gconstpointer value); - /* Return an allocated string. */ - gchar * (*value_to_string) (ETableModel *etm, - gint col, - gconstpointer value); - - /* - * Signals - */ - - /* - * These all come after the change has been made. - * No changes, cancel pre_change: no_change - * Major structural changes: model_changed - * Changes only in a row: row_changed - * Only changes in a cell: cell_changed - * A row inserted: row_inserted - * A row deleted: row_deleted - */ - void (*model_pre_change) (ETableModel *etm); - - void (*model_no_change) (ETableModel *etm); - void (*model_changed) (ETableModel *etm); - void (*model_row_changed) (ETableModel *etm, - gint row); - void (*model_cell_changed) (ETableModel *etm, - gint col, - gint row); - void (*model_rows_inserted) (ETableModel *etm, - gint row, - gint count); - void (*model_rows_deleted) (ETableModel *etm, - gint row, - gint count); -}; - -GType e_table_model_get_type (void) G_GNUC_CONST; - -/**/ -gint e_table_model_column_count (ETableModel *e_table_model); -const gchar * e_table_model_column_name (ETableModel *e_table_model, - gint col); -gint e_table_model_row_count (ETableModel *e_table_model); -void e_table_model_append_row (ETableModel *e_table_model, - ETableModel *source, - gint row); - -/**/ -gpointer e_table_model_value_at (ETableModel *e_table_model, - gint col, - gint row); -void e_table_model_set_value_at (ETableModel *e_table_model, - gint col, - gint row, - gconstpointer value); -gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, - gint col, - gint row); - -/**/ -gboolean e_table_model_has_save_id (ETableModel *etm); -gchar * e_table_model_get_save_id (ETableModel *etm, - gint row); - -/**/ -gboolean e_table_model_has_change_pending - (ETableModel *etm); - -/**/ -gpointer e_table_model_duplicate_value (ETableModel *e_table_model, - gint col, - gconstpointer value); -void e_table_model_free_value (ETableModel *e_table_model, - gint col, - gpointer value); -gpointer e_table_model_initialize_value (ETableModel *e_table_model, - gint col); -gboolean e_table_model_value_is_empty (ETableModel *e_table_model, - gint col, - gconstpointer value); -gchar * e_table_model_value_to_string (ETableModel *e_table_model, - gint col, - gconstpointer value); - -/* - * Routines for emitting signals on the e_table - */ -void e_table_model_pre_change (ETableModel *e_table_model); -void e_table_model_no_change (ETableModel *e_table_model); -void e_table_model_changed (ETableModel *e_table_model); -void e_table_model_row_changed (ETableModel *e_table_model, - gint row); -void e_table_model_cell_changed (ETableModel *e_table_model, - gint col, - gint row); -void e_table_model_rows_inserted (ETableModel *e_table_model, - gint row, - gint count); -void e_table_model_rows_deleted (ETableModel *e_table_model, - gint row, - gint count); - -/**/ -void e_table_model_row_inserted (ETableModel *e_table_model, - gint row); -void e_table_model_row_deleted (ETableModel *e_table_model, - gint row); - -void e_table_model_freeze (ETableModel *e_table_model); -void e_table_model_thaw (ETableModel *e_table_model); - -G_END_DECLS - -#endif /* _E_TABLE_MODEL_H_ */ diff --git a/widgets/table/e-table-one.c b/widgets/table/e-table-one.c deleted file mode 100644 index 503b6a47a7..0000000000 --- a/widgets/table/e-table-one.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-util.h" - -#include "e-table-one.h" - -G_DEFINE_TYPE (ETableOne, e_table_one, E_TYPE_TABLE_MODEL) - -static gint -one_column_count (ETableModel *etm) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_column_count (one->source); - else - return 0; -} - -static gint -one_row_count (ETableModel *etm) -{ - return 1; -} - -static gpointer -one_value_at (ETableModel *etm, - gint col, - gint row) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->data) - return one->data[col]; - else - return NULL; -} - -static void -one_set_value_at (ETableModel *etm, - gint col, - gint row, - gconstpointer val) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->data && one->source) { - e_table_model_free_value (one->source, col, one->data[col]); - one->data[col] = e_table_model_duplicate_value (one->source, col, val); - } -} - -static gboolean -one_is_cell_editable (ETableModel *etm, - gint col, - gint row) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_is_cell_editable (one->source, col, -1); - else - return FALSE; -} - -/* The default for one_duplicate_value is to return the raw value. */ -static gpointer -one_duplicate_value (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_duplicate_value (one->source, col, value); - else - return (gpointer) value; -} - -static void -one_free_value (ETableModel *etm, - gint col, - gpointer value) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - e_table_model_free_value (one->source, col, value); -} - -static gpointer -one_initialize_value (ETableModel *etm, - gint col) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_initialize_value (one->source, col); - else - return NULL; -} - -static gboolean -one_value_is_empty (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_value_is_empty (one->source, col, value); - else - return FALSE; -} - -static gchar * -one_value_to_string (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableOne *one = E_TABLE_ONE (etm); - - if (one->source) - return e_table_model_value_to_string (one->source, col, value); - else - return g_strdup (""); -} - -static void -one_finalize (GObject *object) -{ - G_OBJECT_CLASS (e_table_one_parent_class)->finalize (object); -} - -static void -one_dispose (GObject *object) -{ - ETableOne *one = E_TABLE_ONE (object); - - if (one->data) { - gint i; - gint col_count; - - if (one->source) { - col_count = e_table_model_column_count (one->source); - - for (i = 0; i < col_count; i++) - e_table_model_free_value (one->source, i, one->data[i]); - } - - g_free (one->data); - } - one->data = NULL; - - if (one->source) - g_object_unref (one->source); - one->source = NULL; - - G_OBJECT_CLASS (e_table_one_parent_class)->dispose (object); -} - -static void -e_table_one_class_init (ETableOneClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ETableModelClass *model_class = E_TABLE_MODEL_CLASS (class); - - model_class->column_count = one_column_count; - model_class->row_count = one_row_count; - model_class->value_at = one_value_at; - model_class->set_value_at = one_set_value_at; - model_class->is_cell_editable = one_is_cell_editable; - model_class->duplicate_value = one_duplicate_value; - model_class->free_value = one_free_value; - model_class->initialize_value = one_initialize_value; - model_class->value_is_empty = one_value_is_empty; - model_class->value_to_string = one_value_to_string; - - object_class->dispose = one_dispose; - object_class->finalize = one_finalize; -} - -static void -e_table_one_init (ETableOne *one) -{ - one->source = NULL; - one->data = NULL; -} - -ETableModel * -e_table_one_new (ETableModel *source) -{ - ETableOne *eto; - gint col_count; - gint i; - - eto = g_object_new (E_TYPE_TABLE_ONE, NULL); - eto->source = source; - - col_count = e_table_model_column_count (source); - eto->data = g_new (gpointer , col_count); - for (i = 0; i < col_count; i++) { - eto->data[i] = e_table_model_initialize_value (source, i); - } - - if (source) - g_object_ref (source); - - return (ETableModel *) eto; -} - -void -e_table_one_commit (ETableOne *one) -{ - if (one->source) { - gint empty = TRUE; - gint col; - gint cols = e_table_model_column_count (one->source); - for (col = 0; col < cols; col++) { - if (!e_table_model_value_is_empty (one->source, col, one->data[col])) { - empty = FALSE; - break; - } - } - if (!empty) { - e_table_model_append_row (one->source, E_TABLE_MODEL (one), 0); - } - } -} diff --git a/widgets/table/e-table-one.h b/widgets/table/e-table-one.h deleted file mode 100644 index a0d5c7bf88..0000000000 --- a/widgets/table/e-table-one.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_ONE_H_ -#define _E_TABLE_ONE_H_ - -#include <table/e-table-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_ONE \ - (e_table_one_get_type ()) -#define E_TABLE_ONE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_ONE, ETableOne)) -#define E_TABLE_ONE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_ONE, ETableOneClass)) -#define E_IS_TABLE_ONE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_ONE)) -#define E_IS_TABLE_ONE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_ONE)) -#define E_TABLE_ONE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_ONE, ETableOneClass)) - -G_BEGIN_DECLS - -typedef struct _ETableOne ETableOne; -typedef struct _ETableOneClass ETableOneClass; - -struct _ETableOne { - ETableModel parent; - - ETableModel *source; - gpointer *data; -}; - -struct _ETableOneClass { - ETableModelClass parent_class; -}; - -GType e_table_one_get_type (void) G_GNUC_CONST; - -ETableModel * e_table_one_new (ETableModel *source); -void e_table_one_commit (ETableOne *one); - -G_END_DECLS - -#endif /* _E_TABLE_ONE_H_ */ - diff --git a/widgets/table/e-table-search.c b/widgets/table/e-table-search.c deleted file mode 100644 index e084bc9602..0000000000 --- a/widgets/table/e-table-search.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-search.h" - -#define d(x) - -struct _ETableSearchPrivate { - guint timeout_id; - - gchar *search_string; - gunichar last_character; -}; - -G_DEFINE_TYPE (ETableSearch, e_table_search, G_TYPE_OBJECT) - -enum { - SEARCH_SEARCH, - SEARCH_ACCEPT, - LAST_SIGNAL -}; - -#define E_TABLE_SEARCH_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TABLE_SEARCH, ETableSearchPrivate)) - -d (static gint depth = 0) - -static guint e_table_search_signals[LAST_SIGNAL] = { 0, }; - -static gboolean -e_table_search_search (ETableSearch *e_table_search, - gchar *string, - ETableSearchFlags flags) -{ - gboolean ret_val; - g_return_val_if_fail (E_IS_TABLE_SEARCH (e_table_search), FALSE); - - g_signal_emit ( - e_table_search, - e_table_search_signals[SEARCH_SEARCH], 0, - string, flags, &ret_val); - - return ret_val; -} - -static void -e_table_search_accept (ETableSearch *e_table_search) -{ - g_return_if_fail (E_IS_TABLE_SEARCH (e_table_search)); - - g_signal_emit ( - e_table_search, - e_table_search_signals[SEARCH_ACCEPT], 0); -} - -static gboolean -ets_accept (gpointer data) -{ - ETableSearch *ets = data; - e_table_search_accept (ets); - g_free (ets->priv->search_string); - - ets->priv->timeout_id = 0; - ets->priv->search_string = g_strdup (""); - ets->priv->last_character = 0; - - return FALSE; -} - -static void -drop_timeout (ETableSearch *ets) -{ - if (ets->priv->timeout_id) { - g_source_remove (ets->priv->timeout_id); - } - ets->priv->timeout_id = 0; -} - -static void -add_timeout (ETableSearch *ets) -{ - drop_timeout (ets); - ets->priv->timeout_id = g_timeout_add_seconds (1, ets_accept, ets); -} - -static void -e_table_search_finalize (GObject *object) -{ - ETableSearchPrivate *priv; - - priv = E_TABLE_SEARCH_GET_PRIVATE (object); - - drop_timeout (E_TABLE_SEARCH (object)); - - g_free (priv->search_string); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_table_search_parent_class)->finalize (object); -} - -static void -e_table_search_class_init (ETableSearchClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ETableSearchPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = e_table_search_finalize; - - e_table_search_signals[SEARCH_SEARCH] = g_signal_new ( - "search", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableSearchClass, search), - (GSignalAccumulator) NULL, NULL, - e_marshal_BOOLEAN__STRING_INT, - G_TYPE_BOOLEAN, 2, - G_TYPE_STRING, - G_TYPE_INT); - - e_table_search_signals[SEARCH_ACCEPT] = g_signal_new ( - "accept", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableSearchClass, accept), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - class->search = NULL; - class->accept = NULL; -} - -static void -e_table_search_init (ETableSearch *ets) -{ - ets->priv = E_TABLE_SEARCH_GET_PRIVATE (ets); - - ets->priv->search_string = g_strdup (""); -} - -ETableSearch * -e_table_search_new (void) -{ - return g_object_new (E_TYPE_TABLE_SEARCH, NULL); -} - -/** - * e_table_search_column_count: - * @e_table_search: The e-table-search to operate on - * - * Returns: the number of columns in the table search. - */ -void -e_table_search_input_character (ETableSearch *ets, - gunichar character) -{ - gchar character_utf8[7]; - gchar *temp_string; - - g_return_if_fail (ets != NULL); - g_return_if_fail (E_IS_TABLE_SEARCH (ets)); - - character_utf8[g_unichar_to_utf8 (character, character_utf8)] = 0; - - temp_string = g_strdup_printf ("%s%s", ets->priv->search_string, character_utf8); - if (e_table_search_search ( - ets, temp_string, - ets->priv->last_character != 0 ? - E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST : 0)) { - g_free (ets->priv->search_string); - ets->priv->search_string = temp_string; - add_timeout (ets); - ets->priv->last_character = character; - return; - } else { - g_free (temp_string); - } - - if (character == ets->priv->last_character) { - if (ets->priv->search_string && - e_table_search_search (ets, ets->priv->search_string, 0)) { - add_timeout (ets); - } - } -} - -gboolean -e_table_search_backspace (ETableSearch *ets) -{ - gchar *end; - - g_return_val_if_fail (ets != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_SEARCH (ets), FALSE); - - if (!ets->priv->search_string || - !*ets->priv->search_string) - return FALSE; - - end = ets->priv->search_string + strlen (ets->priv->search_string); - end = g_utf8_prev_char (end); - *end = 0; - ets->priv->last_character = 0; - add_timeout (ets); - return TRUE; -} diff --git a/widgets/table/e-table-search.h b/widgets/table/e-table-search.h deleted file mode 100644 index ecd56a5d72..0000000000 --- a/widgets/table/e-table-search.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SEARCH_H_ -#define _E_TABLE_SEARCH_H_ - -#include <glib-object.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SEARCH \ - (e_table_search_get_type ()) -#define E_TABLE_SEARCH(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SEARCH, ETableSearch)) -#define E_TABLE_SEARCH_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SEARCH, ETableSearchClass)) -#define E_IS_TABLE_SEARCH(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SEARCH)) -#define E_IS_TABLE_SEARCH_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SEARCH)) -#define E_TABLE_SEARCH_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SEARCH, ETableSearchClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSearch ETableSearch; -typedef struct _ETableSearchClass ETableSearchClass; -typedef struct _ETableSearchPrivate ETableSearchPrivate; - -typedef enum { - E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST = 1 << 0 -} ETableSearchFlags; - -struct _ETableSearch { - GObject parent; - ETableSearchPrivate *priv; -}; - -struct _ETableSearchClass { - GObjectClass parent_class; - - /* Signals */ - gboolean (*search) (ETableSearch *ets, - gchar *string /* utf8 */, - ETableSearchFlags flags); - void (*accept) (ETableSearch *ets); -}; - -GType e_table_search_get_type (void) G_GNUC_CONST; -ETableSearch * e_table_search_new (void); -void e_table_search_input_character (ETableSearch *e_table_search, - gunichar character); -gboolean e_table_search_backspace (ETableSearch *e_table_search); -void e_table_search_cancel (ETableSearch *e_table_search); - -G_END_DECLS - -#endif /* _E_TABLE_SEARCH_H_ */ diff --git a/widgets/table/e-table-selection-model.c b/widgets/table/e-table-selection-model.c deleted file mode 100644 index 2ee44a7ffe..0000000000 --- a/widgets/table/e-table-selection-model.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gdk/gdkkeysyms.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-table-selection-model.h" - -G_DEFINE_TYPE (ETableSelectionModel, e_table_selection_model, E_SELECTION_MODEL_ARRAY_TYPE) - -static gint etsm_get_row_count (ESelectionModelArray *esm); - -enum { - PROP_0, - PROP_MODEL, - PROP_HEADER -}; - -static void -save_to_hash (gint model_row, - gpointer closure) -{ - ETableSelectionModel *etsm = closure; - const gchar *key = e_table_model_get_save_id (etsm->model, model_row); - - g_hash_table_insert (etsm->hash, (gpointer) key, (gpointer) key); -} - -static void -free_hash (ETableSelectionModel *etsm) -{ - if (etsm->hash) { - g_hash_table_destroy (etsm->hash); - etsm->hash = NULL; - } - if (etsm->cursor_id) - g_free (etsm->cursor_id); - etsm->cursor_id = NULL; -} - -static void -model_pre_change (ETableModel *etm, - ETableSelectionModel *etsm) -{ - free_hash (etsm); - - if (etsm->model && e_table_model_has_save_id (etsm->model)) { - gint cursor_row; - - etsm->hash = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) NULL); - e_selection_model_foreach (E_SELECTION_MODEL (etsm), save_to_hash, etsm); - - g_object_get ( - etsm, - "cursor_row", &cursor_row, - NULL); - g_free (etsm->cursor_id); - if (cursor_row != -1) - etsm->cursor_id = e_table_model_get_save_id (etm, cursor_row); - else - etsm->cursor_id = NULL; - } -} - -static gint -model_changed_idle (ETableSelectionModel *etsm) -{ - ETableModel *etm = etsm->model; - - e_selection_model_clear (E_SELECTION_MODEL (etsm)); - - if (etsm->cursor_id && etm && e_table_model_has_save_id (etm)) { - gint row_count = e_table_model_row_count (etm); - gint cursor_row = -1; - gint cursor_col = -1; - gint i; - e_selection_model_array_confirm_row_count (E_SELECTION_MODEL_ARRAY (etsm)); - for (i = 0; i < row_count; i++) { - gchar *save_id = e_table_model_get_save_id (etm, i); - if (g_hash_table_lookup (etsm->hash, save_id)) - e_selection_model_change_one_row (E_SELECTION_MODEL (etsm), i, TRUE); - - if (etsm->cursor_id && !strcmp (etsm->cursor_id, save_id)) { - cursor_row = i; - cursor_col = e_selection_model_cursor_col (E_SELECTION_MODEL (etsm)); - if (cursor_col == -1) { - if (etsm->eth) { - cursor_col = e_table_header_prioritized_column (etsm->eth); - } else - cursor_col = 0; - } - e_selection_model_change_cursor (E_SELECTION_MODEL (etsm), cursor_row, cursor_col); - g_free (etsm->cursor_id); - etsm->cursor_id = NULL; - } - g_free (save_id); - } - free_hash (etsm); - e_selection_model_cursor_changed (E_SELECTION_MODEL (etsm), cursor_row, cursor_col); - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - } - etsm->model_changed_idle_id = 0; - return FALSE; -} - -static void -model_changed (ETableModel *etm, - ETableSelectionModel *etsm) -{ - e_selection_model_clear (E_SELECTION_MODEL (etsm)); - if (!etsm->model_changed_idle_id && etm && e_table_model_has_save_id (etm)) { - etsm->model_changed_idle_id = g_idle_add_full (G_PRIORITY_HIGH, (GSourceFunc) model_changed_idle, etsm, NULL); - } -} - -static void -model_row_changed (ETableModel *etm, - gint row, - ETableSelectionModel *etsm) -{ - free_hash (etsm); -} - -static void -model_cell_changed (ETableModel *etm, - gint col, - gint row, - ETableSelectionModel *etsm) -{ - free_hash (etsm); -} - -#if 1 -static void -model_rows_inserted (ETableModel *etm, - gint row, - gint count, - ETableSelectionModel *etsm) -{ - e_selection_model_array_insert_rows (E_SELECTION_MODEL_ARRAY (etsm), row, count); - free_hash (etsm); -} - -static void -model_rows_deleted (ETableModel *etm, - gint row, - gint count, - ETableSelectionModel *etsm) -{ - e_selection_model_array_delete_rows (E_SELECTION_MODEL_ARRAY (etsm), row, count); - free_hash (etsm); -} - -#else - -static void -model_rows_inserted (ETableModel *etm, - gint row, - gint count, - ETableSelectionModel *etsm) -{ - model_changed (etm, etsm); -} - -static void -model_rows_deleted (ETableModel *etm, - gint row, - gint count, - ETableSelectionModel *etsm) -{ - model_changed (etm, etsm); -} -#endif - -inline static void -add_model (ETableSelectionModel *etsm, - ETableModel *model) -{ - etsm->model = model; - if (model) { - g_object_ref (model); - etsm->model_pre_change_id = g_signal_connect ( - model, "model_pre_change", - G_CALLBACK (model_pre_change), etsm); - etsm->model_changed_id = g_signal_connect ( - model, "model_changed", - G_CALLBACK (model_changed), etsm); - etsm->model_row_changed_id = g_signal_connect ( - model, "model_row_changed", - G_CALLBACK (model_row_changed), etsm); - etsm->model_cell_changed_id = g_signal_connect ( - model, "model_cell_changed", - G_CALLBACK (model_cell_changed), etsm); - etsm->model_rows_inserted_id = g_signal_connect ( - model, "model_rows_inserted", - G_CALLBACK (model_rows_inserted), etsm); - etsm->model_rows_deleted_id = g_signal_connect ( - model, "model_rows_deleted", - G_CALLBACK (model_rows_deleted), etsm); - } - e_selection_model_array_confirm_row_count (E_SELECTION_MODEL_ARRAY (etsm)); -} - -inline static void -drop_model (ETableSelectionModel *etsm) -{ - if (etsm->model) { - g_signal_handler_disconnect ( - etsm->model, - etsm->model_pre_change_id); - g_signal_handler_disconnect ( - etsm->model, - etsm->model_changed_id); - g_signal_handler_disconnect ( - etsm->model, - etsm->model_row_changed_id); - g_signal_handler_disconnect ( - etsm->model, - etsm->model_cell_changed_id); - g_signal_handler_disconnect ( - etsm->model, - etsm->model_rows_inserted_id); - g_signal_handler_disconnect ( - etsm->model, - etsm->model_rows_deleted_id); - - g_object_unref (etsm->model); - } - etsm->model = NULL; -} - -static void -etsm_dispose (GObject *object) -{ - ETableSelectionModel *etsm; - - etsm = E_TABLE_SELECTION_MODEL (object); - - if (etsm->model_changed_idle_id) - g_source_remove (etsm->model_changed_idle_id); - etsm->model_changed_idle_id = 0; - - drop_model (etsm); - free_hash (etsm); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_table_selection_model_parent_class)->dispose (object); -} - -static void -etsm_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_MODEL: - g_value_set_object (value, etsm->model); - break; - case PROP_HEADER: - g_value_set_object (value, etsm->eth); - break; - } -} - -static void -etsm_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_MODEL: - drop_model (etsm); - add_model (etsm, g_value_get_object (value) ? E_TABLE_MODEL (g_value_get_object (value)) : NULL); - break; - case PROP_HEADER: - etsm->eth = E_TABLE_HEADER (g_value_get_object (value)); - break; - } -} - -static void -e_table_selection_model_init (ETableSelectionModel *selection) -{ - selection->model = NULL; - selection->hash = NULL; - selection->cursor_id = NULL; - - selection->model_changed_idle_id = 0; -} - -static void -e_table_selection_model_class_init (ETableSelectionModelClass *class) -{ - GObjectClass *object_class; - ESelectionModelArrayClass *esma_class; - - object_class = G_OBJECT_CLASS (class); - esma_class = E_SELECTION_MODEL_ARRAY_CLASS (class); - - object_class->dispose = etsm_dispose; - object_class->get_property = etsm_get_property; - object_class->set_property = etsm_set_property; - - esma_class->get_row_count = etsm_get_row_count; - - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Model", - NULL, - E_TYPE_TABLE_MODEL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_HEADER, - g_param_spec_object ( - "header", - "Header", - NULL, - E_TYPE_TABLE_HEADER, - G_PARAM_READWRITE)); -} - -/** - * e_table_selection_model_new - * - * This routine creates a new #ETableSelectionModel. - * - * Returns: The new #ETableSelectionModel. - */ -ETableSelectionModel * -e_table_selection_model_new (void) -{ - return g_object_new (E_TYPE_TABLE_SELECTION_MODEL, NULL); -} - -static gint -etsm_get_row_count (ESelectionModelArray *esma) -{ - ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (esma); - - if (etsm->model) - return e_table_model_row_count (etsm->model); - else - return 0; -} diff --git a/widgets/table/e-table-selection-model.h b/widgets/table/e-table-selection-model.h deleted file mode 100644 index 02309c047a..0000000000 --- a/widgets/table/e-table-selection-model.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SELECTION_MODEL_H_ -#define _E_TABLE_SELECTION_MODEL_H_ - -#include <misc/e-selection-model-array.h> -#include <table/e-table-model.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SELECTION_MODEL \ - (e_table_selection_model_get_type ()) -#define E_TABLE_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SELECTION_MODEL, ETableSelectionModel)) -#define E_TABLE_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE - CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SELECTION_MODEL, ETableSelectionModelClass)) -#define E_IS_TABLE_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SELECTION_MODEL)) -#define E_IS_TABLE_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SELECTION_MODEL)) -#define E_TABLE_SELECTION_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SELECTION_MODEL, ETableSelectionModelClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSelectionModel ETableSelectionModel; -typedef struct _ETableSelectionModelClass ETableSelectionModelClass; - -struct _ETableSelectionModel { - ESelectionModelArray parent; - - ETableModel *model; - ETableHeader *eth; - - guint model_pre_change_id; - guint model_changed_id; - guint model_row_changed_id; - guint model_cell_changed_id; - guint model_rows_inserted_id; - guint model_rows_deleted_id; - - guint model_changed_idle_id; - - guint selection_model_changed : 1; - guint group_info_changed : 1; - - GHashTable *hash; - gchar *cursor_id; -}; - -struct _ETableSelectionModelClass { - ESelectionModelArrayClass parent_class; -}; - -GType e_table_selection_model_get_type (void) G_GNUC_CONST; -ETableSelectionModel * - e_table_selection_model_new (void); - -G_END_DECLS - -#endif /* _E_TABLE_SELECTION_MODEL_H_ */ diff --git a/widgets/table/e-table-sort-info.c b/widgets/table/e-table-sort-info.c deleted file mode 100644 index 7ce56d7c75..0000000000 --- a/widgets/table/e-table-sort-info.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-sort-info.h" - -#define ETM_CLASS(e) (E_TABLE_SORT_INFO_GET_CLASS (e)) - -G_DEFINE_TYPE (ETableSortInfo , e_table_sort_info, G_TYPE_OBJECT) - -enum { - SORT_INFO_CHANGED, - GROUP_INFO_CHANGED, - LAST_SIGNAL -}; - -static guint e_table_sort_info_signals[LAST_SIGNAL] = { 0, }; - -static void -etsi_finalize (GObject *object) -{ - ETableSortInfo *etsi = E_TABLE_SORT_INFO (object); - - if (etsi->groupings) - g_free (etsi->groupings); - etsi->groupings = NULL; - - if (etsi->sortings) - g_free (etsi->sortings); - etsi->sortings = NULL; - - G_OBJECT_CLASS (e_table_sort_info_parent_class)->finalize (object); -} - -static void -e_table_sort_info_init (ETableSortInfo *info) -{ - info->group_count = 0; - info->groupings = NULL; - info->sort_count = 0; - info->sortings = NULL; - info->frozen = 0; - info->sort_info_changed = 0; - info->group_info_changed = 0; - info->can_group = 1; -} - -static void -e_table_sort_info_class_init (ETableSortInfoClass *class) -{ - GObjectClass * object_class = G_OBJECT_CLASS (class); - - object_class->finalize = etsi_finalize; - - e_table_sort_info_signals[SORT_INFO_CHANGED] = g_signal_new ( - "sort_info_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableSortInfoClass, sort_info_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_table_sort_info_signals[GROUP_INFO_CHANGED] = g_signal_new ( - "group_info_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableSortInfoClass, group_info_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - class->sort_info_changed = NULL; - class->group_info_changed = NULL; -} - -static void -e_table_sort_info_sort_info_changed (ETableSortInfo *info) -{ - g_return_if_fail (info != NULL); - g_return_if_fail (E_IS_TABLE_SORT_INFO (info)); - - if (info->frozen) { - info->sort_info_changed = 1; - } else { - g_signal_emit (info, e_table_sort_info_signals[SORT_INFO_CHANGED], 0); - } -} - -static void -e_table_sort_info_group_info_changed (ETableSortInfo *info) -{ - g_return_if_fail (info != NULL); - g_return_if_fail (E_IS_TABLE_SORT_INFO (info)); - - if (info->frozen) { - info->group_info_changed = 1; - } else { - g_signal_emit (info, e_table_sort_info_signals[GROUP_INFO_CHANGED], 0); - } -} - -/** - * e_table_sort_info_freeze: - * @info: The ETableSortInfo object - * - * This functions allows the programmer to cluster various changes to the - * ETableSortInfo (grouping and sorting) without having the object emit - * "group_info_changed" or "sort_info_changed" signals on each change. - * - * To thaw, invoke the e_table_sort_info_thaw() function, which will - * trigger any signals that might have been queued. - */ -void -e_table_sort_info_freeze (ETableSortInfo *info) -{ - info->frozen++; -} - -/** - * e_table_sort_info_thaw: - * @info: The ETableSortInfo object - * - * This functions allows the programmer to cluster various changes to the - * ETableSortInfo (grouping and sorting) without having the object emit - * "group_info_changed" or "sort_info_changed" signals on each change. - * - * This function will flush any pending signals that might be emited by - * this object. - */ -void -e_table_sort_info_thaw (ETableSortInfo *info) -{ - info->frozen--; - if (info->frozen != 0) - return; - - if (info->sort_info_changed) { - info->sort_info_changed = 0; - e_table_sort_info_sort_info_changed (info); - } - if (info->group_info_changed) { - info->group_info_changed = 0; - e_table_sort_info_group_info_changed (info); - } -} - -/** - * e_table_sort_info_grouping_get_count: - * @info: The ETableSortInfo object - * - * Returns: the number of grouping criteria in the object. - */ -guint -e_table_sort_info_grouping_get_count (ETableSortInfo *info) -{ - if (info->can_group) - return info->group_count; - else - return 0; -} - -static void -e_table_sort_info_grouping_real_truncate (ETableSortInfo *info, - gint length) -{ - if (length < info->group_count) { - info->group_count = length; - } - if (length > info->group_count) { - info->groupings = g_realloc (info->groupings, length * sizeof (ETableSortColumn)); - info->group_count = length; - } -} - -/** - * e_table_sort_info_grouping_truncate: - * @info: The ETableSortInfo object - * @lenght: position where the truncation happens. - * - * This routine can be used to reduce or grow the number of grouping - * criteria in the object. - */ -void -e_table_sort_info_grouping_truncate (ETableSortInfo *info, - gint length) -{ - e_table_sort_info_grouping_real_truncate (info, length); - e_table_sort_info_group_info_changed (info); -} - -/** - * e_table_sort_info_grouping_get_nth: - * @info: The ETableSortInfo object - * @n: Item information to fetch. - * - * Returns: the description of the @n-th grouping criteria in the @info object. - */ -ETableSortColumn -e_table_sort_info_grouping_get_nth (ETableSortInfo *info, - gint n) -{ - if (info->can_group && n < info->group_count) { - return info->groupings[n]; - } else { - ETableSortColumn fake = {0, 0}; - return fake; - } -} - -/** - * e_table_sort_info_grouping_set_nth: - * @info: The ETableSortInfo object - * @n: Item information to fetch. - * @column: new values for the grouping - * - * Sets the grouping criteria for index @n to be given by @column (a column number and - * whether it is ascending or descending). - */ -void -e_table_sort_info_grouping_set_nth (ETableSortInfo *info, - gint n, - ETableSortColumn column) -{ - if (n >= info->group_count) { - e_table_sort_info_grouping_real_truncate (info, n + 1); - } - info->groupings[n] = column; - e_table_sort_info_group_info_changed (info); -} - -/** - * e_table_sort_info_get_count: - * @info: The ETableSortInfo object - * - * Returns: the number of sorting criteria in the object. - */ -guint -e_table_sort_info_sorting_get_count (ETableSortInfo *info) -{ - return info->sort_count; -} - -static void -e_table_sort_info_sorting_real_truncate (ETableSortInfo *info, - gint length) -{ - if (length < info->sort_count) { - info->sort_count = length; - } - if (length > info->sort_count) { - info->sortings = g_realloc (info->sortings, length * sizeof (ETableSortColumn)); - info->sort_count = length; - } -} - -/** - * e_table_sort_info_sorting_truncate: - * @info: The ETableSortInfo object - * @lenght: position where the truncation happens. - * - * This routine can be used to reduce or grow the number of sort - * criteria in the object. - */ -void -e_table_sort_info_sorting_truncate (ETableSortInfo *info, - gint length) -{ - e_table_sort_info_sorting_real_truncate (info, length); - e_table_sort_info_sort_info_changed (info); -} - -/** - * e_table_sort_info_sorting_get_nth: - * @info: The ETableSortInfo object - * @n: Item information to fetch. - * - * Returns: the description of the @n-th grouping criteria in the @info object. - */ -ETableSortColumn -e_table_sort_info_sorting_get_nth (ETableSortInfo *info, - gint n) -{ - if (n < info->sort_count) { - return info->sortings[n]; - } else { - ETableSortColumn fake = {0, 0}; - return fake; - } -} - -/** - * e_table_sort_info_sorting_get_nth: - * @info: The ETableSortInfo object - * @n: Item information to fetch. - * @column: new values for the sorting - * - * Sets the sorting criteria for index @n to be given by @column (a - * column number and whether it is ascending or descending). - */ -void -e_table_sort_info_sorting_set_nth (ETableSortInfo *info, - gint n, - ETableSortColumn column) -{ - if (n >= info->sort_count) { - e_table_sort_info_sorting_real_truncate (info, n + 1); - } - info->sortings[n] = column; - e_table_sort_info_sort_info_changed (info); -} - -/** - * e_table_sort_info_new: - * - * This creates a new e_table_sort_info object that contains no - * grouping and no sorting defined as of yet. This object is used - * to keep track of multi-level sorting and multi-level grouping of - * the ETable. - * - * Returns: A new %ETableSortInfo object - */ -ETableSortInfo * -e_table_sort_info_new (void) -{ - return g_object_new (E_TYPE_TABLE_SORT_INFO, NULL); -} - -/** - * e_table_sort_info_load_from_node: - * @info: The ETableSortInfo object - * @node: pointer to the xmlNode that describes the sorting and grouping information - * @state_version: - * - * This loads the state for the %ETableSortInfo object @info from the - * xml node @node. - */ -void -e_table_sort_info_load_from_node (ETableSortInfo *info, - xmlNode *node, - gdouble state_version) -{ - gint i; - xmlNode *grouping; - - if (state_version <= 0.05) { - i = 0; - for (grouping = node->xmlChildrenNode; grouping && !strcmp ((gchar *) grouping->name, "group"); grouping = grouping->xmlChildrenNode) { - ETableSortColumn column; - column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column"); - column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar *)"ascending"); - e_table_sort_info_grouping_set_nth (info, i++, column); - } - i = 0; - for (; grouping && !strcmp ((gchar *) grouping->name, "leaf"); grouping = grouping->xmlChildrenNode) { - ETableSortColumn column; - column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column"); - column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar *)"ascending"); - e_table_sort_info_sorting_set_nth (info, i++, column); - } - } else { - gint gcnt = 0; - gint scnt = 0; - for (grouping = node->children; grouping; grouping = grouping->next) { - ETableSortColumn column; - - if (grouping->type != XML_ELEMENT_NODE) - continue; - - if (!strcmp ((gchar *) grouping->name, "group")) { - column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column"); - column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar *)"ascending"); - e_table_sort_info_grouping_set_nth (info, gcnt++, column); - } else if (!strcmp ((gchar *) grouping->name, "leaf")) { - column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column"); - column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar *)"ascending"); - e_table_sort_info_sorting_set_nth (info, scnt++, column); - } - } - } - g_signal_emit (info, e_table_sort_info_signals[SORT_INFO_CHANGED], 0); -} - -/** - * e_table_sort_info_save_to_node: - * @info: The ETableSortInfo object - * @parent: xmlNode that will be hosting the saved state of the @info object. - * - * This function is used - * - * Returns: the node that has been appended to @parent as a child containing - * the sorting and grouping information for this ETableSortInfo object. - */ -xmlNode * -e_table_sort_info_save_to_node (ETableSortInfo *info, - xmlNode *parent) -{ - xmlNode *grouping; - gint i; - const gint sort_count = e_table_sort_info_sorting_get_count (info); - const gint group_count = e_table_sort_info_grouping_get_count (info); - - grouping = xmlNewChild (parent, NULL, (const guchar *)"grouping", NULL); - - for (i = 0; i < group_count; i++) { - ETableSortColumn column = e_table_sort_info_grouping_get_nth (info, i); - xmlNode *new_node = xmlNewChild (grouping, NULL, (const guchar *)"group", NULL); - - e_xml_set_integer_prop_by_name (new_node, (const guchar *)"column", column.column); - e_xml_set_bool_prop_by_name (new_node, (const guchar *)"ascending", column.ascending); - } - - for (i = 0; i < sort_count; i++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (info, i); - xmlNode *new_node = xmlNewChild (grouping, NULL, (const guchar *)"leaf", NULL); - - e_xml_set_integer_prop_by_name (new_node, (const guchar *)"column", column.column); - e_xml_set_bool_prop_by_name (new_node, (const guchar *)"ascending", column.ascending); - } - - return grouping; -} - -ETableSortInfo * -e_table_sort_info_duplicate (ETableSortInfo *info) -{ - ETableSortInfo *new_info; - - new_info = e_table_sort_info_new (); - - new_info->group_count = info->group_count; - new_info->groupings = g_new (ETableSortColumn, new_info->group_count); - memmove (new_info->groupings, info->groupings, sizeof (ETableSortColumn) * new_info->group_count); - - new_info->sort_count = info->sort_count; - new_info->sortings = g_new (ETableSortColumn, new_info->sort_count); - memmove (new_info->sortings, info->sortings, sizeof (ETableSortColumn) * new_info->sort_count); - - new_info->can_group = info->can_group; - - return new_info; -} - -void -e_table_sort_info_set_can_group (ETableSortInfo *info, - gboolean can_group) -{ - info->can_group = can_group; -} - -gboolean -e_table_sort_info_get_can_group (ETableSortInfo *info) -{ - return info->can_group; -} - diff --git a/widgets/table/e-table-sort-info.h b/widgets/table/e-table-sort-info.h deleted file mode 100644 index a577481150..0000000000 --- a/widgets/table/e-table-sort-info.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SORT_INFO_H_ -#define _E_TABLE_SORT_INFO_H_ - -#include <glib-object.h> -#include <libxml/tree.h> - -#define E_TYPE_TABLE_SORT_INFO \ - (e_table_sort_info_get_type ()) -#define E_TABLE_SORT_INFO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SORT_INFO, ETableSortInfo)) -#define E_TABLE_SORT_INFO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SORT_INFO, ETableSortInfoClass)) -#define E_IS_TABLE_SORT_INFO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SORT_INFO)) -#define E_IS_TABLE_SORT_INFO_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SORT_INFO)) -#define E_TABLE_SORT_INFO_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SORT_INFO, ETableSortInfoClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSortColumn ETableSortColumn; - -typedef struct _ETableSortInfo ETableSortInfo; -typedef struct _ETableSortInfoClass ETableSortInfoClass; - -struct _ETableSortColumn { - guint column : 31; - guint ascending : 1; -}; - -struct _ETableSortInfo { - GObject parent; - - gint group_count; - ETableSortColumn *groupings; - gint sort_count; - ETableSortColumn *sortings; - - guint frozen : 1; - guint sort_info_changed : 1; - guint group_info_changed : 1; - - guint can_group : 1; -}; - -struct _ETableSortInfoClass { - GObjectClass parent_class; - - /* Signals */ - void (*sort_info_changed) (ETableSortInfo *info); - void (*group_info_changed) (ETableSortInfo *info); -}; - -GType e_table_sort_info_get_type (void) G_GNUC_CONST; - -void e_table_sort_info_freeze (ETableSortInfo *info); -void e_table_sort_info_thaw (ETableSortInfo *info); - -guint e_table_sort_info_grouping_get_count - (ETableSortInfo *info); -void e_table_sort_info_grouping_truncate - (ETableSortInfo *info, - gint length); -ETableSortColumn - e_table_sort_info_grouping_get_nth - (ETableSortInfo *info, - gint n); -void e_table_sort_info_grouping_set_nth - (ETableSortInfo *info, - gint n, - ETableSortColumn column); - -guint e_table_sort_info_sorting_get_count - (ETableSortInfo *info); -void e_table_sort_info_sorting_truncate - (ETableSortInfo *info, - gint length); -ETableSortColumn - e_table_sort_info_sorting_get_nth - (ETableSortInfo *info, - gint n); -void e_table_sort_info_sorting_set_nth - (ETableSortInfo *info, - gint n, - ETableSortColumn column); - -ETableSortInfo *e_table_sort_info_new (void); -void e_table_sort_info_load_from_node - (ETableSortInfo *info, - xmlNode *node, - gdouble state_version); -xmlNode * e_table_sort_info_save_to_node (ETableSortInfo *info, - xmlNode *parent); -ETableSortInfo *e_table_sort_info_duplicate (ETableSortInfo *info); -void e_table_sort_info_set_can_group (ETableSortInfo *info, - gboolean can_group); -gboolean e_table_sort_info_get_can_group (ETableSortInfo *info); - -G_END_DECLS - -#endif /* _E_TABLE_SORT_INFO_H_ */ diff --git a/widgets/table/e-table-sorted-variable.c b/widgets/table/e-table-sorted-variable.c deleted file mode 100644 index 73a92c35ef..0000000000 --- a/widgets/table/e-table-sorted-variable.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-sorted-variable.h" -#include "e-table-sorting-utils.h" - -#define d(x) - -#define INCREMENT_AMOUNT 100 - -/* maximum insertions between an idle event that we will do without scheduling an idle sort */ -#define ETSV_INSERT_MAX (4) - -/* workaround for avoiding API breakage */ -#define etsv_get_type e_table_sorted_variable_get_type -G_DEFINE_TYPE (ETableSortedVariable, etsv, E_TYPE_TABLE_SUBSET_VARIABLE) - -static void etsv_sort_info_changed (ETableSortInfo *info, ETableSortedVariable *etsv); -static void etsv_sort (ETableSortedVariable *etsv); -static void etsv_add (ETableSubsetVariable *etssv, gint row); -static void etsv_add_all (ETableSubsetVariable *etssv); - -static void -etsv_dispose (GObject *object) -{ - ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE (object); - - if (etsv->sort_info_changed_id) - g_signal_handler_disconnect ( - etsv->sort_info, - etsv->sort_info_changed_id); - etsv->sort_info_changed_id = 0; - - if (etsv->sort_idle_id) { - g_source_remove (etsv->sort_idle_id); - etsv->sort_idle_id = 0; - } - if (etsv->insert_idle_id) { - g_source_remove (etsv->insert_idle_id); - etsv->insert_idle_id = 0; - } - - if (etsv->sort_info) - g_object_unref (etsv->sort_info); - etsv->sort_info = NULL; - - if (etsv->full_header) - g_object_unref (etsv->full_header); - etsv->full_header = NULL; - - G_OBJECT_CLASS (etsv_parent_class)->dispose (object); -} - -static void -etsv_class_init (ETableSortedVariableClass *class) -{ - ETableSubsetVariableClass *etssv_class = E_TABLE_SUBSET_VARIABLE_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etsv_dispose; - - etssv_class->add = etsv_add; - etssv_class->add_all = etsv_add_all; -} - -static void -etsv_init (ETableSortedVariable *etsv) -{ - etsv->full_header = NULL; - etsv->sort_info = NULL; - - etsv->sort_info_changed_id = 0; - - etsv->sort_idle_id = 0; - etsv->insert_count = 0; -} - -static gboolean -etsv_sort_idle (ETableSortedVariable *etsv) -{ - g_object_ref (etsv); - etsv_sort (etsv); - etsv->sort_idle_id = 0; - etsv->insert_count = 0; - g_object_unref (etsv); - return FALSE; -} - -static gboolean -etsv_insert_idle (ETableSortedVariable *etsv) -{ - etsv->insert_count = 0; - etsv->insert_idle_id = 0; - return FALSE; -} - -static void -etsv_add (ETableSubsetVariable *etssv, - gint row) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE (etssv); - gint i; - - e_table_model_pre_change (etm); - - if (etss->n_map + 1 > etssv->n_vals_allocated) { - etssv->n_vals_allocated += INCREMENT_AMOUNT; - etss->map_table = g_realloc (etss->map_table, (etssv->n_vals_allocated) * sizeof (gint)); - } - i = etss->n_map; - if (etsv->sort_idle_id == 0) { - /* this is to see if we're inserting a lot of things between idle loops. - * If we are, we're busy, its faster to just append and perform a full sort later */ - etsv->insert_count++; - if (etsv->insert_count > ETSV_INSERT_MAX) { - /* schedule a sort, and append instead */ - etsv->sort_idle_id = g_idle_add_full (50, (GSourceFunc) etsv_sort_idle, etsv, NULL); - } else { - /* make sure we have an idle handler to reset the count every now and then */ - if (etsv->insert_idle_id == 0) { - etsv->insert_idle_id = g_idle_add_full (40, (GSourceFunc) etsv_insert_idle, etsv, NULL); - } - i = e_table_sorting_utils_insert (etss->source, etsv->sort_info, etsv->full_header, etss->map_table, etss->n_map, row); - memmove (etss->map_table + i + 1, etss->map_table + i, (etss->n_map - i) * sizeof (gint)); - } - } - etss->map_table[i] = row; - etss->n_map++; - - e_table_model_row_inserted (etm, i); -} - -static void -etsv_add_all (ETableSubsetVariable *etssv) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE (etssv); - gint rows; - gint i; - - e_table_model_pre_change (etm); - - rows = e_table_model_row_count (etss->source); - - if (etss->n_map + rows > etssv->n_vals_allocated) { - etssv->n_vals_allocated += MAX (INCREMENT_AMOUNT, rows); - etss->map_table = g_realloc (etss->map_table, etssv->n_vals_allocated * sizeof (gint)); - } - for (i = 0; i < rows; i++) - etss->map_table[etss->n_map++] = i; - - if (etsv->sort_idle_id == 0) { - etsv->sort_idle_id = g_idle_add_full (50, (GSourceFunc) etsv_sort_idle, etsv, NULL); - } - - e_table_model_changed (etm); -} - -ETableModel * -e_table_sorted_variable_new (ETableModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info) -{ - ETableSortedVariable *etsv = g_object_new (E_TYPE_TABLE_SORTED_VARIABLE, NULL); - ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE (etsv); - - if (e_table_subset_variable_construct (etssv, source) == NULL) { - g_object_unref (etsv); - return NULL; - } - - etsv->sort_info = sort_info; - g_object_ref (etsv->sort_info); - etsv->full_header = full_header; - g_object_ref (etsv->full_header); - - etsv->sort_info_changed_id = g_signal_connect ( - sort_info, "sort_info_changed", - G_CALLBACK (etsv_sort_info_changed), etsv); - - return E_TABLE_MODEL (etsv); -} - -static void -etsv_sort_info_changed (ETableSortInfo *info, - ETableSortedVariable *etsv) -{ - etsv_sort (etsv); -} - -static void -etsv_sort (ETableSortedVariable *etsv) -{ - ETableSubset *etss = E_TABLE_SUBSET (etsv); - static gint reentering = 0; - if (reentering) - return; - reentering = 1; - - e_table_model_pre_change (E_TABLE_MODEL (etsv)); - - e_table_sorting_utils_sort (etss->source, etsv->sort_info, etsv->full_header, etss->map_table, etss->n_map); - - e_table_model_changed (E_TABLE_MODEL (etsv)); - reentering = 0; -} diff --git a/widgets/table/e-table-sorted-variable.h b/widgets/table/e-table-sorted-variable.h deleted file mode 100644 index 917338ae4d..0000000000 --- a/widgets/table/e-table-sorted-variable.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SORTED_VARIABLE_H_ -#define _E_TABLE_SORTED_VARIABLE_H_ - -#include <table/e-table-model.h> -#include <table/e-table-subset-variable.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SORTED_VARIABLE \ - (e_table_sorted_variable_get_type ()) -#define E_TABLE_SORTED_VARIABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SORTED_VARIABLE, ETableSortedVariable)) -#define E_TABLE_SORTED_VARIABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SORTED_VARIABLE, ETableSortedVariableClass)) -#define E_IS_TABLE_SORTED_VARIABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SORTED_VARIABLE)) -#define E_IS_TABLE_SORTED_VARIABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SORTED_VARIABLE)) -#define E_TABLE_SORTED_VARIABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SORTED_VARIABLE, ETableSortedVariableClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSortedVariable ETableSortedVariable; -typedef struct _ETableSortedVariableClass ETableSortedVariableClass; - -struct _ETableSortedVariable { - ETableSubsetVariable parent; - - ETableSortInfo *sort_info; - - ETableHeader *full_header; - - gint sort_info_changed_id; - gint sort_idle_id; - gint insert_idle_id; - gint insert_count; -}; - -struct _ETableSortedVariableClass { - ETableSubsetVariableClass parent_class; -}; - -GType e_table_sorted_variable_get_type - (void) G_GNUC_CONST; -ETableModel * e_table_sorted_variable_new (ETableModel *etm, - ETableHeader *header, - ETableSortInfo *sort_info); - -G_END_DECLS - -#endif /* _E_TABLE_SORTED_VARIABLE_H_ */ diff --git a/widgets/table/e-table-sorted.c b/widgets/table/e-table-sorted.c deleted file mode 100644 index 31f0fa60b4..0000000000 --- a/widgets/table/e-table-sorted.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-sorted.h" -#include "e-table-sorting-utils.h" - -#define d(x) - -#define INCREMENT_AMOUNT 100 - -/* workaround for avoding API breakage */ -#define ets_get_type e_table_sorted_get_type -G_DEFINE_TYPE (ETableSorted, ets, E_TYPE_TABLE_SUBSET) - -/* maximum insertions between an idle event that we will do without scheduling an idle sort */ -#define ETS_INSERT_MAX (4) - -static void ets_sort_info_changed (ETableSortInfo *info, ETableSorted *ets); -static void ets_sort (ETableSorted *ets); -static void ets_proxy_model_changed (ETableSubset *etss, ETableModel *source); -static void ets_proxy_model_row_changed (ETableSubset *etss, ETableModel *source, gint row); -static void ets_proxy_model_cell_changed (ETableSubset *etss, ETableModel *source, gint col, gint row); -static void ets_proxy_model_rows_inserted (ETableSubset *etss, ETableModel *source, gint row, gint count); -static void ets_proxy_model_rows_deleted (ETableSubset *etss, ETableModel *source, gint row, gint count); - -static void -ets_dispose (GObject *object) -{ - ETableSorted *ets = E_TABLE_SORTED (object); - - if (ets->sort_idle_id) - g_source_remove (ets->sort_idle_id); - ets->sort_idle_id = 0; - - if (ets->insert_idle_id) - g_source_remove (ets->insert_idle_id); - ets->insert_idle_id = 0; - - if (ets->sort_info) { - g_signal_handler_disconnect ( - ets->sort_info, - ets->sort_info_changed_id); - g_object_unref (ets->sort_info); - ets->sort_info = NULL; - } - - if (ets->full_header) - g_object_unref (ets->full_header); - ets->full_header = NULL; - - G_OBJECT_CLASS (ets_parent_class)->dispose (object); -} - -static void -ets_class_init (ETableSortedClass *class) -{ - ETableSubsetClass *etss_class = E_TABLE_SUBSET_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - etss_class->proxy_model_changed = ets_proxy_model_changed; - etss_class->proxy_model_row_changed = ets_proxy_model_row_changed; - etss_class->proxy_model_cell_changed = ets_proxy_model_cell_changed; - etss_class->proxy_model_rows_inserted = ets_proxy_model_rows_inserted; - etss_class->proxy_model_rows_deleted = ets_proxy_model_rows_deleted; - - object_class->dispose = ets_dispose; -} - -static void -ets_init (ETableSorted *ets) -{ - ets->full_header = NULL; - ets->sort_info = NULL; - - ets->sort_info_changed_id = 0; - - ets->sort_idle_id = 0; - ets->insert_count = 0; -} - -static gboolean -ets_sort_idle (ETableSorted *ets) -{ - g_object_ref (ets); - ets_sort (ets); - ets->sort_idle_id = 0; - ets->insert_count = 0; - g_object_unref (ets); - return FALSE; -} - -static gboolean -ets_insert_idle (ETableSorted *ets) -{ - ets->insert_count = 0; - ets->insert_idle_id = 0; - return FALSE; -} - -ETableModel * -e_table_sorted_new (ETableModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info) -{ - ETableSorted *ets = g_object_new (E_TYPE_TABLE_SORTED, NULL); - ETableSubset *etss = E_TABLE_SUBSET (ets); - - if (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_pre_change) - (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_pre_change) (etss, source); - - if (e_table_subset_construct (etss, source, 0) == NULL) { - g_object_unref (ets); - return NULL; - } - - ets->sort_info = sort_info; - g_object_ref (ets->sort_info); - ets->full_header = full_header; - g_object_ref (ets->full_header); - - ets_proxy_model_changed (etss, source); - - ets->sort_info_changed_id = g_signal_connect ( - sort_info, "sort_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - - return E_TABLE_MODEL (ets); -} - -static void -ets_sort_info_changed (ETableSortInfo *info, - ETableSorted *ets) -{ - ets_sort (ets); -} - -static void -ets_proxy_model_changed (ETableSubset *subset, - ETableModel *source) -{ - gint rows, i; - - rows = e_table_model_row_count (source); - - g_free (subset->map_table); - subset->n_map = rows; - subset->map_table = g_new (int, rows); - - for (i = 0; i < rows; i++) { - subset->map_table[i] = i; - } - - if (!E_TABLE_SORTED (subset)->sort_idle_id) - E_TABLE_SORTED (subset)->sort_idle_id = g_idle_add_full (50, (GSourceFunc) ets_sort_idle, subset, NULL); - - e_table_model_changed (E_TABLE_MODEL (subset)); -} - -static void -ets_proxy_model_row_changed (ETableSubset *subset, - ETableModel *source, - gint row) -{ - if (!E_TABLE_SORTED (subset)->sort_idle_id) - E_TABLE_SORTED (subset)->sort_idle_id = g_idle_add_full (50, (GSourceFunc) ets_sort_idle, subset, NULL); - - if (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_row_changed) - (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_row_changed) (subset, source, row); -} - -static void -ets_proxy_model_cell_changed (ETableSubset *subset, - ETableModel *source, - gint col, - gint row) -{ - ETableSorted *ets = E_TABLE_SORTED (subset); - if (e_table_sorting_utils_affects_sort (ets->sort_info, ets->full_header, col)) - ets_proxy_model_row_changed (subset, source, row); - else if (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_cell_changed) - (E_TABLE_SUBSET_CLASS (ets_parent_class)->proxy_model_cell_changed) (subset, source, col, row); -} - -static void -ets_proxy_model_rows_inserted (ETableSubset *etss, - ETableModel *source, - gint row, - gint count) -{ - ETableModel *etm = E_TABLE_MODEL (etss); - ETableSorted *ets = E_TABLE_SORTED (etss); - gint i; - gboolean full_change = FALSE; - - if (count == 0) { - e_table_model_no_change (etm); - return; - } - - if (row != etss->n_map) { - full_change = TRUE; - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= row) { - etss->map_table[i] += count; - } - } - } - - etss->map_table = g_realloc (etss->map_table, (etss->n_map + count) * sizeof (gint)); - - for (; count > 0; count--) { - if (!full_change) - e_table_model_pre_change (etm); - i = etss->n_map; - if (ets->sort_idle_id == 0) { - /* this is to see if we're inserting a lot of things between idle loops. - * If we are, we're busy, its faster to just append and perform a full sort later */ - ets->insert_count++; - if (ets->insert_count > ETS_INSERT_MAX) { - /* schedule a sort, and append instead */ - ets->sort_idle_id = g_idle_add_full (50, (GSourceFunc) ets_sort_idle, ets, NULL); - } else { - /* make sure we have an idle handler to reset the count every now and then */ - if (ets->insert_idle_id == 0) { - ets->insert_idle_id = g_idle_add_full (40, (GSourceFunc) ets_insert_idle, ets, NULL); - } - i = e_table_sorting_utils_insert (etss->source, ets->sort_info, ets->full_header, etss->map_table, etss->n_map, row); - memmove (etss->map_table + i + 1, etss->map_table + i, (etss->n_map - i) * sizeof (gint)); - } - } - etss->map_table[i] = row; - etss->n_map++; - if (!full_change) { - e_table_model_row_inserted (etm, i); - } - - d (g_print ("inserted row %d", row)); - row++; - } - if (full_change) - e_table_model_changed (etm); - else - e_table_model_no_change (etm); - d (e_table_subset_print_debugging (etss)); -} - -static void -ets_proxy_model_rows_deleted (ETableSubset *etss, - ETableModel *source, - gint row, - gint count) -{ - ETableModel *etm = E_TABLE_MODEL (etss); - gint i; - gboolean shift; - gint j; - - shift = row == etss->n_map - count; - - for (j = 0; j < count; j++) { - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] == row + j) { - if (shift) - e_table_model_pre_change (etm); - memmove (etss->map_table + i, etss->map_table + i + 1, (etss->n_map - i - 1) * sizeof (gint)); - etss->n_map--; - if (shift) - e_table_model_row_deleted (etm, i); - } - } - } - if (!shift) { - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= row) - etss->map_table[i] -= count; - } - - e_table_model_changed (etm); - } else { - e_table_model_no_change (etm); - } - - d (g_print ("deleted row %d count %d", row, count)); - d (e_table_subset_print_debugging (etss)); -} - -static void -ets_sort (ETableSorted *ets) -{ - ETableSubset *etss = E_TABLE_SUBSET (ets); - static gint reentering = 0; - if (reentering) - return; - reentering = 1; - - e_table_model_pre_change (E_TABLE_MODEL (ets)); - - e_table_sorting_utils_sort (etss->source, ets->sort_info, ets->full_header, etss->map_table, etss->n_map); - - e_table_model_changed (E_TABLE_MODEL (ets)); - reentering = 0; -} diff --git a/widgets/table/e-table-sorted.h b/widgets/table/e-table-sorted.h deleted file mode 100644 index feff6e2ad5..0000000000 --- a/widgets/table/e-table-sorted.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SORTED_H_ -#define _E_TABLE_SORTED_H_ - -#include <table/e-table-model.h> -#include <table/e-table-subset.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SORTED \ - (e_table_sorted_get_type ()) -#define E_TABLE_SORTED(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SORTED, ETableSorted)) -#define E_TABLE_SORTED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SORTED, ETableSortedClass)) -#define E_IS_TABLE_SORTED(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SORTED)) -#define E_IS_TABLE_SORTED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SORTED)) -#define E_TABLE_SORTED_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SORTED, ETableSortedClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSorted ETableSorted; -typedef struct _ETableSortedClass ETableSortedClass; - -struct _ETableSorted { - ETableSubset parent; - - ETableSortInfo *sort_info; - - ETableHeader *full_header; - - gint sort_info_changed_id; - gint sort_idle_id; - gint insert_idle_id; - gint insert_count; -}; - -struct _ETableSortedClass { - ETableSubsetClass parent_class; -}; - -GType e_table_sorted_get_type (void) G_GNUC_CONST; -ETableModel * e_table_sorted_new (ETableModel *etm, - ETableHeader *header, - ETableSortInfo *sort_info); - -G_END_DECLS - -#endif /* _E_TABLE_SORTED_H_ */ diff --git a/widgets/table/e-table-sorter.c b/widgets/table/e-table-sorter.c deleted file mode 100644 index 2815d13b1b..0000000000 --- a/widgets/table/e-table-sorter.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-table-sorter.h" -#include "e-table-sorting-utils.h" - -#define d(x) - -enum { - PROP_0, - PROP_SORT_INFO -}; - -/* workaround for avoiding API breakage */ -#define ets_get_type e_table_sorter_get_type -G_DEFINE_TYPE (ETableSorter, ets, E_SORTER_TYPE) - -#define INCREMENT_AMOUNT 100 - -static void ets_model_changed (ETableModel *etm, ETableSorter *ets); -static void ets_model_row_changed (ETableModel *etm, gint row, ETableSorter *ets); -static void ets_model_cell_changed (ETableModel *etm, gint col, gint row, ETableSorter *ets); -static void ets_model_rows_inserted (ETableModel *etm, gint row, gint count, ETableSorter *ets); -static void ets_model_rows_deleted (ETableModel *etm, gint row, gint count, ETableSorter *ets); -static void ets_sort_info_changed (ETableSortInfo *info, ETableSorter *ets); -static void ets_clean (ETableSorter *ets); -static void ets_sort (ETableSorter *ets); -static void ets_backsort (ETableSorter *ets); - -static gint ets_model_to_sorted (ESorter *sorter, gint row); -static gint ets_sorted_to_model (ESorter *sorter, gint row); -static void ets_get_model_to_sorted_array (ESorter *sorter, gint **array, gint *count); -static void ets_get_sorted_to_model_array (ESorter *sorter, gint **array, gint *count); -static gboolean ets_needs_sorting (ESorter *ets); - -static void -ets_dispose (GObject *object) -{ - ETableSorter *ets = E_TABLE_SORTER (object); - - if (ets->sort_info) { - if (ets->table_model_changed_id) - g_signal_handler_disconnect ( - ets->source, - ets->table_model_changed_id); - if (ets->table_model_row_changed_id) - g_signal_handler_disconnect ( - ets->source, - ets->table_model_row_changed_id); - if (ets->table_model_cell_changed_id) - g_signal_handler_disconnect ( - ets->source, - ets->table_model_cell_changed_id); - if (ets->table_model_rows_inserted_id) - g_signal_handler_disconnect ( - ets->source, - ets->table_model_rows_inserted_id); - if (ets->table_model_rows_deleted_id) - g_signal_handler_disconnect ( - ets->source, - ets->table_model_rows_deleted_id); - if (ets->sort_info_changed_id) - g_signal_handler_disconnect ( - ets->sort_info, - ets->sort_info_changed_id); - if (ets->group_info_changed_id) - g_signal_handler_disconnect ( - ets->sort_info, - ets->group_info_changed_id); - - ets->table_model_changed_id = 0; - ets->table_model_row_changed_id = 0; - ets->table_model_cell_changed_id = 0; - ets->table_model_rows_inserted_id = 0; - ets->table_model_rows_deleted_id = 0; - ets->sort_info_changed_id = 0; - ets->group_info_changed_id = 0; - - g_object_unref (ets->sort_info); - ets->sort_info = NULL; - } - - if (ets->full_header) - g_object_unref (ets->full_header); - ets->full_header = NULL; - - if (ets->source) - g_object_unref (ets->source); - ets->source = NULL; - - G_OBJECT_CLASS (ets_parent_class)->dispose (object); -} - -static void -ets_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETableSorter *ets = E_TABLE_SORTER (object); - - switch (property_id) { - case PROP_SORT_INFO: - if (ets->sort_info) { - if (ets->sort_info_changed_id) - g_signal_handler_disconnect (ets->sort_info, ets->sort_info_changed_id); - if (ets->group_info_changed_id) - g_signal_handler_disconnect (ets->sort_info, ets->group_info_changed_id); - g_object_unref (ets->sort_info); - } - - ets->sort_info = E_TABLE_SORT_INFO (g_value_get_object (value)); - g_object_ref (ets->sort_info); - ets->sort_info_changed_id = g_signal_connect ( - ets->sort_info, "sort_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - ets->group_info_changed_id = g_signal_connect ( - ets->sort_info, "group_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - - ets_clean (ets); - break; - default: - break; - } -} - -static void -ets_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETableSorter *ets = E_TABLE_SORTER (object); - switch (property_id) { - case PROP_SORT_INFO: - g_value_set_object (value, ets->sort_info); - break; - } -} - -static void -ets_class_init (ETableSorterClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - ESorterClass *sorter_class = E_SORTER_CLASS (class); - - object_class->dispose = ets_dispose; - object_class->set_property = ets_set_property; - object_class->get_property = ets_get_property; - - sorter_class->model_to_sorted = ets_model_to_sorted; - sorter_class->sorted_to_model = ets_sorted_to_model; - sorter_class->get_model_to_sorted_array = ets_get_model_to_sorted_array; - sorter_class->get_sorted_to_model_array = ets_get_sorted_to_model_array; - sorter_class->needs_sorting = ets_needs_sorting; - - g_object_class_install_property ( - object_class, - PROP_SORT_INFO, - g_param_spec_object ( - "sort_info", - "Sort Info", - NULL, - E_TYPE_TABLE_SORT_INFO, - G_PARAM_READWRITE)); -} - -static void -ets_init (ETableSorter *ets) -{ - ets->full_header = NULL; - ets->sort_info = NULL; - ets->source = NULL; - - ets->needs_sorting = -1; - - ets->table_model_changed_id = 0; - ets->table_model_row_changed_id = 0; - ets->table_model_cell_changed_id = 0; - ets->table_model_rows_inserted_id = 0; - ets->table_model_rows_deleted_id = 0; - ets->sort_info_changed_id = 0; - ets->group_info_changed_id = 0; -} - -ETableSorter * -e_table_sorter_new (ETableModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info) -{ - ETableSorter *ets = g_object_new (E_TYPE_TABLE_SORTER, NULL); - - ets->sort_info = sort_info; - g_object_ref (ets->sort_info); - ets->full_header = full_header; - g_object_ref (ets->full_header); - ets->source = source; - g_object_ref (ets->source); - - ets->table_model_changed_id = g_signal_connect ( - source, "model_changed", - G_CALLBACK (ets_model_changed), ets); - - ets->table_model_row_changed_id = g_signal_connect ( - source, "model_row_changed", - G_CALLBACK (ets_model_row_changed), ets); - - ets->table_model_cell_changed_id = g_signal_connect ( - source, "model_cell_changed", - G_CALLBACK (ets_model_cell_changed), ets); - - ets->table_model_rows_inserted_id = g_signal_connect ( - source, "model_rows_inserted", - G_CALLBACK (ets_model_rows_inserted), ets); - - ets->table_model_rows_deleted_id = g_signal_connect ( - source, "model_rows_deleted", - G_CALLBACK (ets_model_rows_deleted), ets); - - ets->sort_info_changed_id = g_signal_connect ( - sort_info, "sort_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - - ets->group_info_changed_id = g_signal_connect ( - sort_info, "group_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - - return ets; -} - -static void -ets_model_changed (ETableModel *etm, - ETableSorter *ets) -{ - ets_clean (ets); -} - -static void -ets_model_row_changed (ETableModel *etm, - gint row, - ETableSorter *ets) -{ - ets_clean (ets); -} - -static void -ets_model_cell_changed (ETableModel *etm, - gint col, - gint row, - ETableSorter *ets) -{ - ets_clean (ets); -} - -static void -ets_model_rows_inserted (ETableModel *etm, - gint row, - gint count, - ETableSorter *ets) -{ - ets_clean (ets); -} - -static void -ets_model_rows_deleted (ETableModel *etm, - gint row, - gint count, - ETableSorter *ets) -{ - ets_clean (ets); -} - -static void -ets_sort_info_changed (ETableSortInfo *info, - ETableSorter *ets) -{ - d (g_print ("sort info changed\n")); - ets_clean (ets); -} - -struct qsort_data { - ETableSorter *ets; - gpointer *vals; - gint cols; - gint *ascending; - GCompareDataFunc *compare; - gpointer cmp_cache; -}; - -/* FIXME: Make it not cache the second and later columns (as if anyone cares.) */ - -static gint -qsort_callback (gconstpointer data1, - gconstpointer data2, - gpointer user_data) -{ - struct qsort_data *qd = (struct qsort_data *) user_data; - gint row1 = *(gint *) data1; - gint row2 = *(gint *) data2; - gint j; - gint sort_count = e_table_sort_info_sorting_get_count (qd->ets->sort_info) + e_table_sort_info_grouping_get_count (qd->ets->sort_info); - gint comp_val = 0; - gint ascending = 1; - for (j = 0; j < sort_count; j++) { - comp_val = (*(qd->compare[j]))(qd->vals[qd->cols * row1 + j], qd->vals[qd->cols * row2 + j], qd->cmp_cache); - ascending = qd->ascending[j]; - if (comp_val != 0) - break; - } - if (comp_val == 0) { - if (row1 < row2) - comp_val = -1; - if (row1 > row2) - comp_val = 1; - } - if (!ascending) - comp_val = -comp_val; - return comp_val; -} - -static void -ets_clean (ETableSorter *ets) -{ - g_free (ets->sorted); - ets->sorted = NULL; - - g_free (ets->backsorted); - ets->backsorted = NULL; - - ets->needs_sorting = -1; -} - -static void -ets_sort (ETableSorter *ets) -{ - gint rows; - gint i; - gint j; - gint cols; - gint group_cols; - struct qsort_data qd; - - if (ets->sorted) - return; - - rows = e_table_model_row_count (ets->source); - group_cols = e_table_sort_info_grouping_get_count (ets->sort_info); - cols = e_table_sort_info_sorting_get_count (ets->sort_info) + group_cols; - - ets->sorted = g_new (int, rows); - for (i = 0; i < rows; i++) - ets->sorted[i] = i; - - qd.cols = cols; - qd.ets = ets; - - qd.vals = g_new (gpointer , rows * cols); - qd.ascending = g_new (int, cols); - qd.compare = g_new (GCompareDataFunc, cols); - qd.cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - for (j = 0; j < cols; j++) { - ETableSortColumn column; - ETableCol *col; - - if (j < group_cols) - column = e_table_sort_info_grouping_get_nth (ets->sort_info, j); - else - column = e_table_sort_info_sorting_get_nth (ets->sort_info, j - group_cols); - - col = e_table_header_get_column_by_col_idx (ets->full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (ets->full_header, e_table_header_count (ets->full_header) - 1); - - for (i = 0; i < rows; i++) { - qd.vals[i * cols + j] = e_table_model_value_at (ets->source, col->col_idx, i); - } - - qd.compare[j] = col->compare; - qd.ascending[j] = column.ascending; - } - - g_qsort_with_data (ets->sorted, rows, sizeof (gint), qsort_callback, &qd); - - g_free (qd.vals); - g_free (qd.ascending); - g_free (qd.compare); - e_table_sorting_utils_free_cmp_cache (qd.cmp_cache); -} - -static void -ets_backsort (ETableSorter *ets) -{ - gint i, rows; - - if (ets->backsorted) - return; - - ets_sort (ets); - - rows = e_table_model_row_count (ets->source); - ets->backsorted = g_new0 (int, rows); - - for (i = 0; i < rows; i++) { - ets->backsorted[ets->sorted[i]] = i; - } -} - -static gint -ets_model_to_sorted (ESorter *es, - gint row) -{ - ETableSorter *ets = E_TABLE_SORTER (es); - gint rows = e_table_model_row_count (ets->source); - - g_return_val_if_fail (row >= 0, -1); - g_return_val_if_fail (row < rows, -1); - - if (ets_needs_sorting (es)) - ets_backsort (ets); - - if (ets->backsorted) - return ets->backsorted[row]; - else - return row; -} - -static gint -ets_sorted_to_model (ESorter *es, - gint row) -{ - ETableSorter *ets = E_TABLE_SORTER (es); - gint rows = e_table_model_row_count (ets->source); - - g_return_val_if_fail (row >= 0, -1); - g_return_val_if_fail (row < rows, -1); - - if (ets_needs_sorting (es)) - ets_sort (ets); - - if (ets->sorted) - return ets->sorted[row]; - else - return row; -} - -static void -ets_get_model_to_sorted_array (ESorter *es, - gint **array, - gint *count) -{ - ETableSorter *ets = E_TABLE_SORTER (es); - if (array || count) { - ets_backsort (ets); - - if (array) - *array = ets->backsorted; - if (count) - *count = e_table_model_row_count(ets->source); - } -} - -static void -ets_get_sorted_to_model_array (ESorter *es, - gint **array, - gint *count) -{ - ETableSorter *ets = E_TABLE_SORTER (es); - if (array || count) { - ets_sort (ets); - - if (array) - *array = ets->sorted; - if (count) - *count = e_table_model_row_count(ets->source); - } -} - -static gboolean -ets_needs_sorting (ESorter *es) -{ - ETableSorter *ets = E_TABLE_SORTER (es); - if (ets->needs_sorting < 0) { - if (e_table_sort_info_sorting_get_count (ets->sort_info) + e_table_sort_info_grouping_get_count (ets->sort_info)) - ets->needs_sorting = 1; - else - ets->needs_sorting = 0; - } - return ets->needs_sorting; -} diff --git a/widgets/table/e-table-sorter.h b/widgets/table/e-table-sorter.h deleted file mode 100644 index 0f36f441f6..0000000000 --- a/widgets/table/e-table-sorter.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SORTER_H_ -#define _E_TABLE_SORTER_H_ - -#include <e-util/e-sorter.h> -#include <table/e-table-model.h> -#include <table/e-table-subset-variable.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SORTER \ - (e_table_sorter_get_type ()) -#define E_TABLE_SORTER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SORTER, ETableSorter)) -#define E_TABLE_SORTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SORTER, ETableSorterClass)) -#define E_IS_TABLE_SORTER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SORTER)) -#define E_IS_TABLE_SORTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SORTER)) -#define E_TABLE_SORTER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SORTER, ETableSorterClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSorter ETableSorter; -typedef struct _ETableSorterClass ETableSorterClass; - -struct _ETableSorter { - ESorter parent; - - ETableModel *source; - ETableHeader *full_header; - ETableSortInfo *sort_info; - - /* If needs_sorting is 0, then model_to_sorted - * and sorted_to_model are no-ops. */ - gint needs_sorting; - - gint *sorted; - gint *backsorted; - - gint table_model_changed_id; - gint table_model_row_changed_id; - gint table_model_cell_changed_id; - gint table_model_rows_inserted_id; - gint table_model_rows_deleted_id; - gint sort_info_changed_id; - gint group_info_changed_id; -}; - -struct _ETableSorterClass { - ESorterClass parent_class; -}; - -GType e_table_sorter_get_type (void) G_GNUC_CONST; -ETableSorter * e_table_sorter_new (ETableModel *etm, - ETableHeader *full_header, - ETableSortInfo *sort_info); - -G_END_DECLS - -#endif /* _E_TABLE_SORTER_H_ */ diff --git a/widgets/table/e-table-sorting-utils.c b/widgets/table/e-table-sorting-utils.c deleted file mode 100644 index a94c45f7b0..0000000000 --- a/widgets/table/e-table-sorting-utils.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <camel/camel.h> - -#include "e-util/e-util.h" - -#include "e-table-sorting-utils.h" - -#define d(x) - -/* This takes source rows. */ -static gint -etsu_compare (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint row1, - gint row2, - gpointer cmp_cache) -{ - gint j; - gint sort_count = e_table_sort_info_sorting_get_count (sort_info); - gint comp_val = 0; - gint ascending = 1; - - for (j = 0; j < sort_count; j++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j); - ETableCol *col; - col = e_table_header_get_column_by_col_idx (full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - comp_val = (*col->compare)(e_table_model_value_at (source, col->compare_col, row1), - e_table_model_value_at (source, col->compare_col, row2), - cmp_cache); - ascending = column.ascending; - if (comp_val != 0) - break; - } - if (comp_val == 0) { - if (row1 < row2) - comp_val = -1; - if (row1 > row2) - comp_val = 1; - } - if (!ascending) - comp_val = -comp_val; - return comp_val; -} - -typedef struct { - gint cols; - gpointer *vals; - gint *ascending; - GCompareDataFunc *compare; - gpointer cmp_cache; -} ETableSortClosure; - -typedef struct { - ETreeModel *tree; - ETableSortInfo *sort_info; - ETableHeader *full_header; - gpointer cmp_cache; -} ETreeSortClosure; - -/* FIXME: Make it not cache the second and later columns (as if anyone cares.) */ - -static gint -e_sort_callback (gconstpointer data1, - gconstpointer data2, - gpointer user_data) -{ - gint row1 = *(gint *) data1; - gint row2 = *(gint *) data2; - ETableSortClosure *closure = user_data; - gint j; - gint sort_count = closure->cols; - gint comp_val = 0; - gint ascending = 1; - for (j = 0; j < sort_count; j++) { - comp_val = (*(closure->compare[j]))(closure->vals[closure->cols * row1 + j], closure->vals[closure->cols * row2 + j], closure->cmp_cache); - ascending = closure->ascending[j]; - if (comp_val != 0) - break; - } - if (comp_val == 0) { - if (row1 < row2) - comp_val = -1; - if (row1 > row2) - comp_val = 1; - } - if (!ascending) - comp_val = -comp_val; - return comp_val; -} - -void -e_table_sorting_utils_sort (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows) -{ - gint total_rows; - gint i; - gint j; - gint cols; - ETableSortClosure closure; - - g_return_if_fail (source != NULL); - g_return_if_fail (E_IS_TABLE_MODEL (source)); - g_return_if_fail (sort_info != NULL); - g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); - g_return_if_fail (full_header != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (full_header)); - - total_rows = e_table_model_row_count (source); - cols = e_table_sort_info_sorting_get_count (sort_info); - closure.cols = cols; - - closure.vals = g_new (gpointer , total_rows * cols); - closure.ascending = g_new (int, cols); - closure.compare = g_new (GCompareDataFunc, cols); - closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - for (j = 0; j < cols; j++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j); - ETableCol *col; - col = e_table_header_get_column_by_col_idx (full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - for (i = 0; i < rows; i++) { - closure.vals[map_table[i] * cols + j] = e_table_model_value_at (source, col->compare_col, map_table[i]); - } - closure.compare[j] = col->compare; - closure.ascending[j] = column.ascending; - } - - g_qsort_with_data ( - map_table, rows, sizeof (gint), e_sort_callback, &closure); - - g_free (closure.vals); - g_free (closure.ascending); - g_free (closure.compare); - e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); -} - -gboolean -e_table_sorting_utils_affects_sort (ETableSortInfo *sort_info, - ETableHeader *full_header, - gint col) -{ - gint j; - gint cols; - - g_return_val_if_fail (sort_info != NULL, TRUE); - g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), TRUE); - g_return_val_if_fail (full_header != NULL, TRUE); - g_return_val_if_fail (E_IS_TABLE_HEADER (full_header), TRUE); - - cols = e_table_sort_info_sorting_get_count (sort_info); - - for (j = 0; j < cols; j++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j); - ETableCol *tablecol; - tablecol = e_table_header_get_column_by_col_idx (full_header, column.column); - if (tablecol == NULL) - tablecol = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - if (col == tablecol->compare_col) - return TRUE; - } - return FALSE; -} - -/* FIXME: This could be done in time log n instead of time n with a binary search. */ -gint -e_table_sorting_utils_insert (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows, - gint row) -{ - gint i; - gpointer cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - i = 0; - /* handle insertions when we have a 'sort group' */ - while (i < rows && etsu_compare (source, sort_info, full_header, map_table[i], row, cmp_cache) < 0) - i++; - - e_table_sorting_utils_free_cmp_cache (cmp_cache); - - return i; -} - -/* FIXME: This could be done in time log n instead of time n with a binary search. */ -gint -e_table_sorting_utils_check_position (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows, - gint view_row) -{ - gint i; - gint row; - gpointer cmp_cache; - - i = view_row; - row = map_table[i]; - cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - i = view_row; - if (i < rows - 1 && etsu_compare (source, sort_info, full_header, map_table[i + 1], row, cmp_cache) < 0) { - i++; - while (i < rows - 1 && etsu_compare (source, sort_info, full_header, map_table[i], row, cmp_cache) < 0) - i++; - } else if (i > 0 && etsu_compare (source, sort_info, full_header, map_table[i - 1], row, cmp_cache) > 0) { - i--; - while (i > 0 && etsu_compare (source, sort_info, full_header, map_table[i], row, cmp_cache) > 0) - i--; - } - - e_table_sorting_utils_free_cmp_cache (cmp_cache); - - return i; -} - -/* This takes source rows. */ -static gint -etsu_tree_compare (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath path1, - ETreePath path2, - gpointer cmp_cache) -{ - gint j; - gint sort_count = e_table_sort_info_sorting_get_count (sort_info); - gint comp_val = 0; - gint ascending = 1; - - for (j = 0; j < sort_count; j++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j); - ETableCol *col; - col = e_table_header_get_column_by_col_idx (full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - comp_val = (*col->compare)(e_tree_model_value_at (source, path1, col->compare_col), - e_tree_model_value_at (source, path2, col->compare_col), - cmp_cache); - ascending = column.ascending; - if (comp_val != 0) - break; - } - if (!ascending) - comp_val = -comp_val; - return comp_val; -} - -static gint -e_sort_tree_callback (gconstpointer data1, - gconstpointer data2, - gpointer user_data) -{ - ETreePath *path1 = *(ETreePath *) data1; - ETreePath *path2 = *(ETreePath *) data2; - ETreeSortClosure *closure = user_data; - - return etsu_tree_compare (closure->tree, closure->sort_info, closure->full_header, path1, path2, closure->cmp_cache); -} - -void -e_table_sorting_utils_tree_sort (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count) -{ - ETableSortClosure closure; - gint cols; - gint i, j; - gint *map; - ETreePath *map_copy; - g_return_if_fail (source != NULL); - g_return_if_fail (E_IS_TREE_MODEL (source)); - g_return_if_fail (sort_info != NULL); - g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); - g_return_if_fail (full_header != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (full_header)); - - cols = e_table_sort_info_sorting_get_count (sort_info); - closure.cols = cols; - - closure.vals = g_new (gpointer , count * cols); - closure.ascending = g_new (int, cols); - closure.compare = g_new (GCompareDataFunc, cols); - closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - for (j = 0; j < cols; j++) { - ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j); - ETableCol *col; - - col = e_table_header_get_column_by_col_idx (full_header, column.column); - if (col == NULL) - col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1); - - for (i = 0; i < count; i++) { - closure.vals[i * cols + j] = e_tree_model_sort_value_at (source, map_table[i], col->compare_col); - } - closure.ascending[j] = column.ascending; - closure.compare[j] = col->compare; - } - - map = g_new (int, count); - for (i = 0; i < count; i++) { - map[i] = i; - } - - g_qsort_with_data ( - map, count, sizeof (gint), e_sort_callback, &closure); - - map_copy = g_new (ETreePath, count); - for (i = 0; i < count; i++) { - map_copy[i] = map_table[i]; - } - for (i = 0; i < count; i++) { - map_table[i] = map_copy[map[i]]; - } - - g_free (map); - g_free (map_copy); - - g_free (closure.vals); - g_free (closure.ascending); - g_free (closure.compare); - e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); -} - -/* FIXME: This could be done in time log n instead of time n with a binary search. */ -gint -e_table_sorting_utils_tree_check_position (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count, - gint old_index) -{ - gint i; - ETreePath path; - gpointer cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - i = old_index; - path = map_table[i]; - - if (i < count - 1 && etsu_tree_compare (source, sort_info, full_header, map_table[i + 1], path, cmp_cache) < 0) { - i++; - while (i < count - 1 && etsu_tree_compare (source, sort_info, full_header, map_table[i], path, cmp_cache) < 0) - i++; - } else if (i > 0 && etsu_tree_compare (source, sort_info, full_header, map_table[i - 1], path, cmp_cache) > 0) { - i--; - while (i > 0 && etsu_tree_compare (source, sort_info, full_header, map_table[i], path, cmp_cache) > 0) - i--; - } - - e_table_sorting_utils_free_cmp_cache (cmp_cache); - - return i; -} - -/* FIXME: This does not pay attention to making sure that it's a stable insert. This needs to be fixed. */ -gint -e_table_sorting_utils_tree_insert (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count, - ETreePath path) -{ - gsize start; - gsize end; - ETreeSortClosure closure; - - closure.tree = source; - closure.sort_info = sort_info; - closure.full_header = full_header; - closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); - - e_bsearch (&path, map_table, count, sizeof (ETreePath), e_sort_tree_callback, &closure, &start, &end); - - e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); - - return end; -} - -/** - * e_table_sorting_utils_create_cmp_cache: - * - * Creates a new compare cache, which is storing pairs of string keys and - * string values. This can be accessed by - * e_table_sorting_utils_lookup_cmp_cache() and - * e_table_sorting_utils_add_to_cmp_cache(). - * - * Returned pointer should be freed with - * e_table_sorting_utils_free_cmp_cache(). - **/ -gpointer -e_table_sorting_utils_create_cmp_cache (void) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, g_free); -} - -/** - * e_table_sorting_utils_free_cmp_cache: - * @cmp_cache: a compare cache; cannot be %NULL - * - * Frees a compare cache previously created with - * e_table_sorting_utils_create_cmp_cache(). - **/ -void -e_table_sorting_utils_free_cmp_cache (gpointer cmp_cache) -{ - g_return_if_fail (cmp_cache != NULL); - - g_hash_table_destroy (cmp_cache); -} - -/** - * e_table_sorting_utils_add_to_cmp_cache: - * @cmp_cache: a compare cache; cannot be %NULL - * @key: unique key to a cache; cannot be %NULL - * @value: value to store for a key - * - * Adds a new value for a given key to a compare cache. If such key - * already exists in a cache then its value will be replaced. - * Note: Given @value will be stolen and later freed with g_free. - **/ -void -e_table_sorting_utils_add_to_cmp_cache (gpointer cmp_cache, - const gchar *key, - gchar *value) -{ - g_return_if_fail (cmp_cache != NULL); - g_return_if_fail (key != NULL); - - g_hash_table_insert (cmp_cache, (gchar *) camel_pstring_strdup (key), value); -} - -/** - * e_table_sorting_utils_lookup_cmp_cache: - * @cmp_cache: a compare cache - * @key: unique key to a cache - * - * Lookups for a key in a compare cache, which is passed in GCompareDataFunc as 'data'. - * Returns %NULL when not found or the cache wasn't provided, otherwise value stored - * with a key. - **/ -const gchar * -e_table_sorting_utils_lookup_cmp_cache (gpointer cmp_cache, - const gchar *key) -{ - g_return_val_if_fail (key != NULL, NULL); - - if (!cmp_cache) - return NULL; - - return g_hash_table_lookup (cmp_cache, key); -} diff --git a/widgets/table/e-table-sorting-utils.h b/widgets/table/e-table-sorting-utils.h deleted file mode 100644 index 5a0a3cd3d7..0000000000 --- a/widgets/table/e-table-sorting-utils.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SORTING_UTILS_H_ -#define _E_TABLE_SORTING_UTILS_H_ - -G_BEGIN_DECLS - -#include <table/e-table-model.h> -#include <table/e-tree-model.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> - -gboolean e_table_sorting_utils_affects_sort - (ETableSortInfo *sort_info, - ETableHeader *full_header, - gint col); - -void e_table_sorting_utils_sort (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows); -gint e_table_sorting_utils_insert (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows, - gint row); -gint e_table_sorting_utils_check_position - (ETableModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - gint *map_table, - gint rows, - gint view_row); - -void e_table_sorting_utils_tree_sort (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count); -gint e_table_sorting_utils_tree_check_position - (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count, - gint old_index); -gint e_table_sorting_utils_tree_insert - (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *full_header, - ETreePath *map_table, - gint count, - ETreePath path); - -gpointer e_table_sorting_utils_create_cmp_cache - (void); -void e_table_sorting_utils_free_cmp_cache - (gpointer cmp_cache); -void e_table_sorting_utils_add_to_cmp_cache - (gpointer cmp_cache, - const gchar *key, - gchar *value); -const gchar * e_table_sorting_utils_lookup_cmp_cache - (gpointer cmp_cache, - const gchar *key); - -G_END_DECLS - -#endif /* _E_TABLE_SORTING_UTILS_H_ */ diff --git a/widgets/table/e-table-specification.c b/widgets/table/e-table-specification.c deleted file mode 100644 index 9f301f6852..0000000000 --- a/widgets/table/e-table-specification.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <glib/gstdio.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include <libedataserver/libedataserver.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-specification.h" - -/* workaround for avoiding API breakage */ -#define etsp_get_type e_table_specification_get_type -G_DEFINE_TYPE (ETableSpecification, etsp, G_TYPE_OBJECT) - -static void -etsp_finalize (GObject *object) -{ - ETableSpecification *etsp = E_TABLE_SPECIFICATION (object); - gint i; - - if (etsp->columns) { - for (i = 0; etsp->columns[i]; i++) { - g_object_unref (etsp->columns[i]); - } - g_free (etsp->columns); - etsp->columns = NULL; - } - - if (etsp->state) - g_object_unref (etsp->state); - etsp->state = NULL; - - g_free (etsp->click_to_add_message); - etsp->click_to_add_message = NULL; - - g_free (etsp->domain); - etsp->domain = NULL; - - G_OBJECT_CLASS (etsp_parent_class)->finalize (object); -} - -static void -etsp_class_init (ETableSpecificationClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->finalize = etsp_finalize; -} - -static void -etsp_init (ETableSpecification *etsp) -{ - etsp->columns = NULL; - etsp->state = NULL; - - etsp->alternating_row_colors = TRUE; - etsp->no_headers = FALSE; - etsp->click_to_add = FALSE; - etsp->click_to_add_end = FALSE; - etsp->horizontal_draw_grid = FALSE; - etsp->vertical_draw_grid = FALSE; - etsp->draw_focus = TRUE; - etsp->horizontal_scrolling = FALSE; - etsp->horizontal_resize = FALSE; - etsp->allow_grouping = TRUE; - - etsp->cursor_mode = E_CURSOR_SIMPLE; - etsp->selection_mode = GTK_SELECTION_MULTIPLE; - - etsp->click_to_add_message = NULL; - etsp->domain = NULL; -} - -/** - * e_table_specification_new: - * - * Creates a new %ETableSpecification object. This object is used to hold the - * information about the rendering information for ETable. - * - * Returns: a newly created %ETableSpecification object. - */ -ETableSpecification * -e_table_specification_new (void) -{ - ETableSpecification *etsp = g_object_new (E_TYPE_TABLE_SPECIFICATION, NULL); - - return (ETableSpecification *) etsp; -} - -/** - * e_table_specification_load_from_file: - * @specification: An ETableSpecification that you want to modify - * @filename: a filename that contains an ETableSpecification - * - * This routine modifies @specification to reflect the state described - * by the file @filename. - * - * Returns: TRUE on success, FALSE on failure. - */ -gboolean -e_table_specification_load_from_file (ETableSpecification *specification, - const gchar *filename) -{ - xmlDoc *doc; - - doc = e_xml_parse_file (filename); - if (doc) { - xmlNode *node = xmlDocGetRootElement (doc); - e_table_specification_load_from_node (specification, node); - xmlFreeDoc (doc); - return TRUE; - } - return FALSE; -} - -/** - * e_table_specification_load_from_string: - * @specification: An ETableSpecification that you want to modify - * @xml: a stringified representation of an ETableSpecification description. - * - * This routine modifies @specification to reflect the state described - * by @xml. @xml is typically returned by e_table_specification_save_to_string - * or it can be embedded in your source code. - * - * Returns: TRUE on success, FALSE on failure. - */ -gboolean -e_table_specification_load_from_string (ETableSpecification *specification, - const gchar *xml) -{ - xmlDoc *doc; - doc = xmlParseMemory ((gchar *) xml, strlen (xml)); - if (doc) { - xmlNode *node = xmlDocGetRootElement (doc); - e_table_specification_load_from_node (specification, node); - xmlFreeDoc (doc); - return TRUE; - } - - return FALSE; -} - -/** - * e_table_specification_load_from_node: - * @specification: An ETableSpecification that you want to modify - * @node: an xmlNode with an XML ETableSpecification description. - * - * This routine modifies @specification to reflect the state described - * by @node. - */ -void -e_table_specification_load_from_node (ETableSpecification *specification, - const xmlNode *node) -{ - gchar *temp; - xmlNode *children; - GList *list = NULL, *list2; - gint i; - - specification->no_headers = e_xml_get_bool_prop_by_name (node, (const guchar *)"no-headers"); - specification->click_to_add = e_xml_get_bool_prop_by_name (node, (const guchar *)"click-to-add"); - specification->click_to_add_end = e_xml_get_bool_prop_by_name (node, (const guchar *)"click-to-add-end") && specification->click_to_add; - specification->alternating_row_colors = e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"alternating-row-colors", TRUE); - specification->horizontal_draw_grid = e_xml_get_bool_prop_by_name (node, (const guchar *)"horizontal-draw-grid"); - specification->vertical_draw_grid = e_xml_get_bool_prop_by_name (node, (const guchar *)"vertical-draw-grid"); - if (e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"draw-grid", TRUE) == - e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"draw-grid", FALSE)) { - specification->horizontal_draw_grid = - specification->vertical_draw_grid = e_xml_get_bool_prop_by_name (node, (const guchar *)"draw-grid"); - } - specification->draw_focus = e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"draw-focus", TRUE); - specification->horizontal_scrolling = e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"horizontal-scrolling", FALSE); - specification->horizontal_resize = e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"horizontal-resize", FALSE); - specification->allow_grouping = e_xml_get_bool_prop_by_name_with_default (node, (const guchar *)"allow-grouping", TRUE); - - specification->selection_mode = GTK_SELECTION_MULTIPLE; - temp = e_xml_get_string_prop_by_name (node, (const guchar *)"selection-mode"); - if (temp && !g_ascii_strcasecmp (temp, "single")) { - specification->selection_mode = GTK_SELECTION_SINGLE; - } else if (temp && !g_ascii_strcasecmp (temp, "browse")) { - specification->selection_mode = GTK_SELECTION_BROWSE; - } else if (temp && !g_ascii_strcasecmp (temp, "extended")) { - specification->selection_mode = GTK_SELECTION_MULTIPLE; - } - g_free (temp); - - specification->cursor_mode = E_CURSOR_SIMPLE; - temp = e_xml_get_string_prop_by_name (node, (const guchar *)"cursor-mode"); - if (temp && !g_ascii_strcasecmp (temp, "line")) { - specification->cursor_mode = E_CURSOR_LINE; - } else if (temp && !g_ascii_strcasecmp (temp, "spreadsheet")) { - specification->cursor_mode = E_CURSOR_SPREADSHEET; - } - g_free (temp); - - g_free (specification->click_to_add_message); - specification->click_to_add_message = - e_xml_get_string_prop_by_name ( - node, (const guchar *)"_click-to-add-message"); - - g_free (specification->domain); - specification->domain = - e_xml_get_string_prop_by_name ( - node, (const guchar *)"gettext-domain"); - if (specification->domain && !*specification->domain) { - g_free (specification->domain); - specification->domain = NULL; - } - - if (specification->state) - g_object_unref (specification->state); - specification->state = NULL; - if (specification->columns) { - for (i = 0; specification->columns[i]; i++) { - g_object_unref (specification->columns[i]); - } - g_free (specification->columns); - } - specification->columns = NULL; - - for (children = node->xmlChildrenNode; children; children = children->next) { - if (!strcmp ((gchar *) children->name, "ETableColumn")) { - ETableColumnSpecification *col_spec = e_table_column_specification_new (); - - e_table_column_specification_load_from_node (col_spec, children); - list = g_list_append (list, col_spec); - } else if (specification->state == NULL && !strcmp ((gchar *) children->name, "ETableState")) { - specification->state = e_table_state_new (); - e_table_state_load_from_node (specification->state, children); - e_table_sort_info_set_can_group (specification->state->sort_info, specification->allow_grouping); - } - } - - if (specification->state == NULL) { - /* Make the default state. */ - specification->state = e_table_state_vanilla (g_list_length (list)); - } - - specification->columns = g_new (ETableColumnSpecification *, g_list_length (list) + 1); - for (list2 = list, i = 0; list2; list2 = g_list_next (list2), i++) { - specification->columns[i] = list2->data; - } - specification->columns[i] = NULL; - g_list_free (list); -} - -/** - * e_table_specification_save_to_file: - * @specification: An %ETableSpecification that you want to save - * @filename: a file name to store the specification. - * - * This routine stores the @specification into @filename. - * - * Returns: 0 on success or -1 on error. - */ -gint -e_table_specification_save_to_file (ETableSpecification *specification, - const gchar *filename) -{ - xmlDoc *doc; - gint ret; - - g_return_val_if_fail (specification != NULL, -1); - g_return_val_if_fail (filename != NULL, -1); - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), -1); - - if ((doc = xmlNewDoc ((const guchar *)"1.0")) == NULL) - return -1; - - xmlDocSetRootElement (doc, e_table_specification_save_to_node (specification, doc)); - - ret = e_xml_save_file (filename, doc); - - xmlFreeDoc (doc); - - return ret; -} - -/** - * e_table_specification_save_to_string: - * @specification: An %ETableSpecification that you want to stringify - * - * Saves the state of @specification to a string. - * - * Returns: an g_alloc() allocated string containing the stringified - * representation of @specification. This stringified representation - * uses XML as a convenience. - */ -gchar * -e_table_specification_save_to_string (ETableSpecification *specification) -{ - gchar *ret_val; - xmlChar *string; - gint length; - xmlDoc *doc; - - g_return_val_if_fail (specification != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), NULL); - - doc = xmlNewDoc ((const guchar *)"1.0"); - xmlDocSetRootElement (doc, e_table_specification_save_to_node (specification, doc)); - xmlDocDumpMemory (doc, &string, &length); - - ret_val = g_strdup ((gchar *) string); - xmlFree (string); - return ret_val; -} - -/** - * e_table_specification_save_to_node: - * @specification: An ETableSpecification that you want to store. - * @doc: Node where the specification is saved - * - * This routine saves the %ETableSpecification state in the object @specification - * into the xmlDoc represented by @doc. - * - * Returns: The node that has been attached to @doc with the contents - * of the ETableSpecification. - */ -xmlNode * -e_table_specification_save_to_node (ETableSpecification *specification, - xmlDoc *doc) -{ - xmlNode *node; - const gchar *s; - - g_return_val_if_fail (doc != NULL, NULL); - g_return_val_if_fail (specification != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), NULL); - - node = xmlNewNode (NULL, (const guchar *)"ETableSpecification"); - e_xml_set_bool_prop_by_name (node, (const guchar *)"no-headers", specification->no_headers); - e_xml_set_bool_prop_by_name (node, (const guchar *)"click-to-add", specification->click_to_add); - e_xml_set_bool_prop_by_name (node, (const guchar *)"click-to-add-end", specification->click_to_add_end && specification->click_to_add); - e_xml_set_bool_prop_by_name (node, (const guchar *)"alternating-row-colors", specification->alternating_row_colors); - e_xml_set_bool_prop_by_name (node, (const guchar *)"horizontal-draw-grid", specification->horizontal_draw_grid); - e_xml_set_bool_prop_by_name (node, (const guchar *)"vertical-draw-grid", specification->vertical_draw_grid); - e_xml_set_bool_prop_by_name (node, (const guchar *)"draw-focus", specification->draw_focus); - e_xml_set_bool_prop_by_name (node, (const guchar *)"horizontal-scrolling", specification->horizontal_scrolling); - e_xml_set_bool_prop_by_name (node, (const guchar *)"horizontal-resize", specification->horizontal_resize); - e_xml_set_bool_prop_by_name (node, (const guchar *)"allow-grouping", specification->allow_grouping); - - switch (specification->selection_mode) { - case GTK_SELECTION_SINGLE: - s = "single"; - break; - case GTK_SELECTION_BROWSE: - s = "browse"; - break; - default: - case GTK_SELECTION_MULTIPLE: - s = "extended"; - } - xmlSetProp (node, (const guchar *)"selection-mode", (guchar *) s); - if (specification->cursor_mode == E_CURSOR_LINE) - s = "line"; - else - s = "cell"; - xmlSetProp (node, (const guchar *)"cursor-mode", (guchar *) s); - - xmlSetProp (node, (const guchar *)"_click-to-add-message", (guchar *) specification->click_to_add_message); - xmlSetProp (node, (const guchar *)"gettext-domain", (guchar *) specification->domain); - - if (specification->columns) { - gint i; - - for (i = 0; specification->columns[i]; i++) - e_table_column_specification_save_to_node ( - specification->columns[i], - node); - } - - if (specification->state) - e_table_state_save_to_node (specification->state, node); - - return node; -} - -/** - * e_table_specification_duplicate: - * @spec: specification to duplicate - * - * This creates a copy of the %ETableSpecification @spec - * - * Returns: The duplicated %ETableSpecification. - */ -ETableSpecification * -e_table_specification_duplicate (ETableSpecification *spec) -{ - ETableSpecification *new_spec; - gchar *spec_str; - - g_return_val_if_fail (spec != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (spec), NULL); - - new_spec = e_table_specification_new (); - spec_str = e_table_specification_save_to_string (spec); - if (!e_table_specification_load_from_string (new_spec, spec_str)) { - g_warning ("Unable to duplicate ETable specification"); - g_object_unref (new_spec); - new_spec = NULL; - } - g_free (spec_str); - - return new_spec; -} diff --git a/widgets/table/e-table-specification.h b/widgets/table/e-table-specification.h deleted file mode 100644 index 021c0524c5..0000000000 --- a/widgets/table/e-table-specification.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SPECIFICATION_H_ -#define _E_TABLE_SPECIFICATION_H_ - -#include <libxml/tree.h> -#include <misc/e-selection-model.h> -#include <table/e-table-state.h> -#include <table/e-table-column-specification.h> -#include <table/e-table-defines.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SPECIFICATION \ - (e_table_specification_get_type ()) -#define E_TABLE_SPECIFICATION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SPECIFICATION, ETableSpecification)) -#define E_TABLE_SPECIFICATION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SPECIFICATION, ETableSpecificationClass)) -#define E_IS_TABLE_SPECIFICATION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SPECIFICATION)) -#define E_IS_TABLE_SPECIFICATION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SPECIFICATION)) -#define E_TABLE_SPECIFICATION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SPECIFICATION, ETableSpecificationClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSpecification ETableSpecification; -typedef struct _ETableSpecificationClass ETableSpecificationClass; - -struct _ETableSpecification { - GObject parent; - - ETableColumnSpecification **columns; - ETableState *state; - - guint alternating_row_colors : 1; - guint no_headers : 1; - guint click_to_add : 1; - guint click_to_add_end : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint horizontal_scrolling : 1; - guint horizontal_resize : 1; - guint allow_grouping : 1; - GtkSelectionMode selection_mode; - ECursorMode cursor_mode; - - gchar *click_to_add_message; - gchar *domain; -}; - -struct _ETableSpecificationClass { - GObjectClass parent_class; -}; - -GType e_table_specification_get_type (void) G_GNUC_CONST; -ETableSpecification * - e_table_specification_new (void); - -gboolean e_table_specification_load_from_file - (ETableSpecification *specification, - const gchar *filename); -gboolean e_table_specification_load_from_string - (ETableSpecification *specification, - const gchar *xml); -void e_table_specification_load_from_node - (ETableSpecification *specification, - const xmlNode *node); - -gint e_table_specification_save_to_file - (ETableSpecification *specification, - const gchar *filename); -gchar * e_table_specification_save_to_string - (ETableSpecification *specification); -xmlNode * e_table_specification_save_to_node - (ETableSpecification *specification, - xmlDoc *doc); -ETableSpecification * - e_table_specification_duplicate (ETableSpecification *specification); - -G_END_DECLS - -#endif /* _E_TABLE_SPECIFICATION_H_ */ diff --git a/widgets/table/e-table-state.c b/widgets/table/e-table-state.c deleted file mode 100644 index 61c0e5ced5..0000000000 --- a/widgets/table/e-table-state.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include <libedataserver/libedataserver.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-state.h" - -#define STATE_VERSION 0.1 - -G_DEFINE_TYPE (ETableState, e_table_state, G_TYPE_OBJECT) - -static void -etst_dispose (GObject *object) -{ - ETableState *etst = E_TABLE_STATE (object); - - if (etst->sort_info) { - g_object_unref (etst->sort_info); - etst->sort_info = NULL; - } - - G_OBJECT_CLASS (e_table_state_parent_class)->dispose (object); -} - -static void -etst_finalize (GObject *object) -{ - ETableState *etst = E_TABLE_STATE (object); - - if (etst->columns) { - g_free (etst->columns); - etst->columns = NULL; - } - - if (etst->expansions) { - g_free (etst->expansions); - etst->expansions = NULL; - } - - G_OBJECT_CLASS (e_table_state_parent_class)->finalize (object); -} - -static void -e_table_state_class_init (ETableStateClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etst_dispose; - object_class->finalize = etst_finalize; -} - -static void -e_table_state_init (ETableState *state) -{ - state->columns = NULL; - state->expansions = NULL; - state->sort_info = e_table_sort_info_new (); -} - -ETableState * -e_table_state_new (void) -{ - return g_object_new (E_TYPE_TABLE_STATE, NULL); -} - -ETableState * -e_table_state_vanilla (gint col_count) -{ - GString *str; - gint i; - ETableState *res; - - str = g_string_new ("<ETableState>\n"); - for (i = 0; i < col_count; i++) - g_string_append_printf (str, " <column source=\"%d\"/>\n", i); - g_string_append (str, " <grouping></grouping>\n"); - g_string_append (str, "</ETableState>\n"); - - res = e_table_state_new (); - e_table_state_load_from_string (res, str->str); - - g_string_free (str, TRUE); - return res; -} - -gboolean -e_table_state_load_from_file (ETableState *state, - const gchar *filename) -{ - xmlDoc *doc; - - g_return_val_if_fail (E_IS_TABLE_STATE (state), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - doc = e_xml_parse_file (filename); - if (doc) { - xmlNode *node = xmlDocGetRootElement (doc); - e_table_state_load_from_node (state, node); - xmlFreeDoc (doc); - return TRUE; - } - return FALSE; -} - -void -e_table_state_load_from_string (ETableState *state, - const gchar *xml) -{ - xmlDoc *doc; - - g_return_if_fail (E_IS_TABLE_STATE (state)); - g_return_if_fail (xml != NULL); - - doc = xmlParseMemory ((gchar *) xml, strlen (xml)); - if (doc) { - xmlNode *node = xmlDocGetRootElement (doc); - e_table_state_load_from_node (state, node); - xmlFreeDoc (doc); - } -} - -typedef struct { - gint column; - gdouble expansion; -} int_and_double; - -void -e_table_state_load_from_node (ETableState *state, - const xmlNode *node) -{ - xmlNode *children; - GList *list = NULL, *iterator; - gdouble state_version; - gint i; - gboolean can_group = TRUE; - - g_return_if_fail (E_IS_TABLE_STATE (state)); - g_return_if_fail (node != NULL); - - state_version = e_xml_get_double_prop_by_name_with_default ( - node, (const guchar *)"state-version", STATE_VERSION); - - if (state->sort_info) { - can_group = e_table_sort_info_get_can_group (state->sort_info); - g_object_unref (state->sort_info); - } - - state->sort_info = NULL; - children = node->xmlChildrenNode; - for (; children; children = children->next) { - if (!strcmp ((gchar *) children->name, "column")) { - int_and_double *column_info = g_new (int_and_double, 1); - - column_info->column = e_xml_get_integer_prop_by_name ( - children, (const guchar *)"source"); - column_info->expansion = - e_xml_get_double_prop_by_name_with_default ( - children, (const guchar *)"expansion", 1); - - list = g_list_append (list, column_info); - } else if (state->sort_info == NULL && - !strcmp ((gchar *) children->name, "grouping")) { - state->sort_info = e_table_sort_info_new (); - e_table_sort_info_load_from_node ( - state->sort_info, children, state_version); - } - } - g_free (state->columns); - g_free (state->expansions); - state->col_count = g_list_length (list); - state->columns = g_new (int, state->col_count); - state->expansions = g_new (double, state->col_count); - - if (!state->sort_info) - state->sort_info = e_table_sort_info_new (); - e_table_sort_info_set_can_group (state->sort_info, can_group); - - for (iterator = list, i = 0; iterator; i++) { - int_and_double *column_info = iterator->data; - - state->columns[i] = column_info->column; - state->expansions[i] = column_info->expansion; - g_free (column_info); - iterator = g_list_next (iterator); - } - g_list_free (list); -} - -void -e_table_state_save_to_file (ETableState *state, - const gchar *filename) -{ - xmlDoc *doc; - - if ((doc = xmlNewDoc ((const guchar *)"1.0")) == NULL) - return; - - xmlDocSetRootElement (doc, e_table_state_save_to_node (state, NULL)); - - e_xml_save_file (filename, doc); - - xmlFreeDoc (doc); -} - -gchar * -e_table_state_save_to_string (ETableState *state) -{ - gchar *ret_val; - xmlChar *string; - gint length; - xmlDoc *doc; - - g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); - - doc = xmlNewDoc ((const guchar *)"1.0"); - xmlDocSetRootElement (doc, e_table_state_save_to_node (state, NULL)); - xmlDocDumpMemory (doc, &string, &length); - xmlFreeDoc (doc); - - ret_val = g_strdup ((gchar *) string); - xmlFree (string); - return ret_val; -} - -xmlNode * -e_table_state_save_to_node (ETableState *state, - xmlNode *parent) -{ - gint i; - xmlNode *node; - - g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); - - if (parent) - node = xmlNewChild ( - parent, NULL, (const guchar *) "ETableState", NULL); - else - node = xmlNewNode (NULL, (const guchar *) "ETableState"); - - e_xml_set_double_prop_by_name ( - node, (const guchar *)"state-version", STATE_VERSION); - - for (i = 0; i < state->col_count; i++) { - gint column = state->columns[i]; - gdouble expansion = state->expansions[i]; - xmlNode *new_node; - - new_node = xmlNewChild ( - node, NULL, (const guchar *) "column", NULL); - e_xml_set_integer_prop_by_name ( - new_node, (const guchar *) "source", column); - if (expansion >= -1) - e_xml_set_double_prop_by_name ( - new_node, (const guchar *) - "expansion", expansion); - } - - e_table_sort_info_save_to_node (state->sort_info, node); - - return node; -} - -/** - * e_table_state_duplicate: - * @state: The ETableState to duplicate - * - * This creates a copy of the %ETableState @state - * - * Returns: The duplicated %ETableState. - */ -ETableState * -e_table_state_duplicate (ETableState *state) -{ - ETableState *new_state; - gchar *copy; - - g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); - - new_state = e_table_state_new (); - copy = e_table_state_save_to_string (state); - e_table_state_load_from_string (new_state, copy); - g_free (copy); - - e_table_sort_info_set_can_group - (new_state->sort_info, - e_table_sort_info_get_can_group (state->sort_info)); - - return new_state; -} diff --git a/widgets/table/e-table-state.h b/widgets/table/e-table-state.h deleted file mode 100644 index 23fc5b2fb2..0000000000 --- a/widgets/table/e-table-state.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_STATE_H_ -#define _E_TABLE_STATE_H_ - -#include <libxml/tree.h> -#include <table/e-table-sort-info.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_STATE \ - (e_table_state_get_type ()) -#define E_TABLE_STATE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_STATE, ETableState)) -#define E_TABLE_STATE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_STATE, ETableStateClass)) -#define E_IS_TABLE_STATE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_STATE)) -#define E_IS_TABLE_STATE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_STATE)) -#define E_TABLE_STATE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_STATE, ETableStateClass)) - -G_BEGIN_DECLS - -typedef struct _ETableState ETableState; -typedef struct _ETableStateClass ETableStateClass; - -struct _ETableState { - GObject parent; - - ETableSortInfo *sort_info; - gint col_count; - gint *columns; - gdouble *expansions; -}; - -struct _ETableStateClass { - GObjectClass parent_class; -}; - -GType e_table_state_get_type (void) G_GNUC_CONST; -ETableState * e_table_state_new (void); -ETableState * e_table_state_vanilla (gint col_count); -gboolean e_table_state_load_from_file (ETableState *state, - const gchar *filename); -void e_table_state_load_from_string (ETableState *state, - const gchar *xml); -void e_table_state_load_from_node (ETableState *state, - const xmlNode *node); -void e_table_state_save_to_file (ETableState *state, - const gchar *filename); -gchar * e_table_state_save_to_string (ETableState *state); -xmlNode * e_table_state_save_to_node (ETableState *state, - xmlNode *parent); -ETableState * e_table_state_duplicate (ETableState *state); - -G_END_DECLS - -#endif /* _E_TABLE_STATE_H_ */ diff --git a/widgets/table/e-table-subset-variable.c b/widgets/table/e-table-subset-variable.c deleted file mode 100644 index a40859b492..0000000000 --- a/widgets/table/e-table-subset-variable.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-subset-variable.h" - -#define ETSSV_CLASS(e) (E_TABLE_SUBSET_VARIABLE_GET_CLASS (e)) - -/* workaround for avoiding API breakage */ -#define etssv_get_type e_table_subset_variable_get_type -G_DEFINE_TYPE (ETableSubsetVariable, etssv, E_TYPE_TABLE_SUBSET) - -#define INCREMENT_AMOUNT 10 - -static void -etssv_add (ETableSubsetVariable *etssv, - gint row) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - - e_table_model_pre_change (etm); - - if (etss->n_map + 1 > etssv->n_vals_allocated) { - etssv->n_vals_allocated += INCREMENT_AMOUNT; - etss->map_table = g_realloc ( - etss->map_table, - etssv->n_vals_allocated * sizeof (gint)); - } - - etss->map_table[etss->n_map++] = row; - - e_table_model_row_inserted (etm, etss->n_map - 1); -} - -static void -etssv_add_array (ETableSubsetVariable *etssv, - const gint *array, - gint count) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - gint i; - - e_table_model_pre_change (etm); - - if (etss->n_map + count > etssv->n_vals_allocated) { - etssv->n_vals_allocated += MAX (INCREMENT_AMOUNT, count); - etss->map_table = g_realloc ( - etss->map_table, - etssv->n_vals_allocated * sizeof (gint)); - } - for (i = 0; i < count; i++) - etss->map_table[etss->n_map++] = array[i]; - - e_table_model_changed (etm); -} - -static void -etssv_add_all (ETableSubsetVariable *etssv) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - gint rows; - gint i; - - e_table_model_pre_change (etm); - - rows = e_table_model_row_count (etss->source); - if (etss->n_map + rows > etssv->n_vals_allocated) { - etssv->n_vals_allocated += MAX (INCREMENT_AMOUNT, rows); - etss->map_table = g_realloc ( - etss->map_table, - etssv->n_vals_allocated * sizeof (gint)); - } - for (i = 0; i < rows; i++) - etss->map_table[etss->n_map++] = i; - - e_table_model_changed (etm); -} - -static gboolean -etssv_remove (ETableSubsetVariable *etssv, - gint row) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - gint i; - - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] == row) { - e_table_model_pre_change (etm); - memmove ( - etss->map_table + i, - etss->map_table + i + 1, - (etss->n_map - i - 1) * sizeof (gint)); - etss->n_map--; - - e_table_model_row_deleted (etm, i); - return TRUE; - } - } - return FALSE; -} - -static void -etssv_class_init (ETableSubsetVariableClass *class) -{ - class->add = etssv_add; - class->add_array = etssv_add_array; - class->add_all = etssv_add_all; - class->remove = etssv_remove; -} - -static void -etssv_init (ETableSubsetVariable *etssv) -{ - /* nothing to do */ -} - -ETableModel * -e_table_subset_variable_construct (ETableSubsetVariable *etssv, - ETableModel *source) -{ - if (e_table_subset_construct (E_TABLE_SUBSET (etssv), source, 1) == NULL) - return NULL; - E_TABLE_SUBSET (etssv)->n_map = 0; - - return E_TABLE_MODEL (etssv); -} - -ETableModel * -e_table_subset_variable_new (ETableModel *source) -{ - ETableSubsetVariable *etssv = g_object_new (E_TYPE_TABLE_SUBSET_VARIABLE, NULL); - - if (e_table_subset_variable_construct (etssv, source) == NULL) { - g_object_unref (etssv); - return NULL; - } - - return (ETableModel *) etssv; -} - -void -e_table_subset_variable_add (ETableSubsetVariable *etssv, - gint row) -{ - g_return_if_fail (etssv != NULL); - g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv)); - - if (ETSSV_CLASS (etssv)->add) - ETSSV_CLASS (etssv)->add (etssv, row); -} - -void -e_table_subset_variable_add_array (ETableSubsetVariable *etssv, - const gint *array, - gint count) -{ - g_return_if_fail (etssv != NULL); - g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv)); - - if (ETSSV_CLASS (etssv)->add_array) - ETSSV_CLASS (etssv)->add_array (etssv, array, count); -} - -void -e_table_subset_variable_add_all (ETableSubsetVariable *etssv) -{ - g_return_if_fail (etssv != NULL); - g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv)); - - if (ETSSV_CLASS (etssv)->add_all) - ETSSV_CLASS (etssv)->add_all (etssv); -} - -gboolean -e_table_subset_variable_remove (ETableSubsetVariable *etssv, - gint row) -{ - g_return_val_if_fail (etssv != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv), FALSE); - - if (ETSSV_CLASS (etssv)->remove) - return ETSSV_CLASS (etssv)->remove (etssv, row); - else - return FALSE; -} - -void -e_table_subset_variable_clear (ETableSubsetVariable *etssv) -{ - ETableModel *etm = E_TABLE_MODEL (etssv); - ETableSubset *etss = E_TABLE_SUBSET (etssv); - - e_table_model_pre_change (etm); - etss->n_map = 0; - g_free (etss->map_table); - etss->map_table = (gint *) g_new (guint, 1); - etssv->n_vals_allocated = 1; - - e_table_model_changed (etm); -} - -void -e_table_subset_variable_increment (ETableSubsetVariable *etssv, - gint position, - gint amount) -{ - gint i; - ETableSubset *etss = E_TABLE_SUBSET (etssv); - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= position) - etss->map_table[i] += amount; - } -} - -void -e_table_subset_variable_decrement (ETableSubsetVariable *etssv, - gint position, - gint amount) -{ - gint i; - ETableSubset *etss = E_TABLE_SUBSET (etssv); - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= position) - etss->map_table[i] -= amount; - } -} - -void -e_table_subset_variable_set_allocation (ETableSubsetVariable *etssv, - gint total) -{ - ETableSubset *etss = E_TABLE_SUBSET (etssv); - if (total <= 0) - total = 1; - if (total > etss->n_map) { - etss->map_table = g_realloc (etss->map_table, total * sizeof (gint)); - } -} diff --git a/widgets/table/e-table-subset-variable.h b/widgets/table/e-table-subset-variable.h deleted file mode 100644 index da8186a1df..0000000000 --- a/widgets/table/e-table-subset-variable.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SUBSET_VARIABLE_H_ -#define _E_TABLE_SUBSET_VARIABLE_H_ - -#include <table/e-table-subset.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SUBSET_VARIABLE \ - (e_table_subset_variable_get_type ()) -#define E_TABLE_SUBSET_VARIABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SUBSET_VARIABLE, ETableSubsetVariable)) -#define E_TABLE_SUBSET_VARIABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SUBSET_VARIABLE, ETableSubsetVariableClass)) -#define E_IS_TABLE_SUBSET_VARIABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SUBSET_VARIABLE)) -#define E_IS_TABLE_SUBSET_VARIABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SUBSET_VARIABLE)) -#define E_TABLE_SUBSET_VARIABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SUBSET_VARIABLE, ETableSubsetVariableClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSubsetVariable ETableSubsetVariable; -typedef struct _ETableSubsetVariableClass ETableSubsetVariableClass; - -struct _ETableSubsetVariable { - ETableSubset parent; - gint n_vals_allocated; -}; - -struct _ETableSubsetVariableClass { - ETableSubsetClass parent_class; - - void (*add) (ETableSubsetVariable *ets, - gint row); - void (*add_array) (ETableSubsetVariable *ets, - const gint *array, - gint count); - void (*add_all) (ETableSubsetVariable *ets); - gboolean (*remove) (ETableSubsetVariable *ets, - gint row); -}; - -GType e_table_subset_variable_get_type - (void) G_GNUC_CONST; -ETableModel * e_table_subset_variable_new (ETableModel *etm); -ETableModel * e_table_subset_variable_construct - (ETableSubsetVariable *etssv, - ETableModel *source); -void e_table_subset_variable_add (ETableSubsetVariable *ets, - gint row); -void e_table_subset_variable_add_array - (ETableSubsetVariable *ets, - const gint *array, - gint count); -void e_table_subset_variable_add_all (ETableSubsetVariable *ets); -gboolean e_table_subset_variable_remove (ETableSubsetVariable *ets, - gint row); -void e_table_subset_variable_clear (ETableSubsetVariable *ets); -void e_table_subset_variable_increment - (ETableSubsetVariable *ets, - gint position, - gint amount); -void e_table_subset_variable_decrement - (ETableSubsetVariable *ets, - gint position, - gint amount); -void e_table_subset_variable_set_allocation - (ETableSubsetVariable *ets, - gint total); - -G_END_DECLS - -#endif /* _E_TABLE_SUBSET_VARIABLE_H_ */ - diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c deleted file mode 100644 index 411102eac1..0000000000 --- a/widgets/table/e-table-subset.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "e-util/e-util.h" - -#include "e-table-subset.h" - -static void etss_proxy_model_pre_change_real - (ETableSubset *etss, - ETableModel *etm); -static void etss_proxy_model_no_change_real (ETableSubset *etss, - ETableModel *etm); -static void etss_proxy_model_changed_real (ETableSubset *etss, - ETableModel *etm); -static void etss_proxy_model_row_changed_real - (ETableSubset *etss, - ETableModel *etm, - gint row); -static void etss_proxy_model_cell_changed_real - (ETableSubset *etss, - ETableModel *etm, - gint col, - gint row); -static void etss_proxy_model_rows_inserted_real - (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count); -static void etss_proxy_model_rows_deleted_real - (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count); - -#define d(x) - -/* workaround for avoding API breakage */ -#define etss_get_type e_table_subset_get_type -G_DEFINE_TYPE (ETableSubset, etss, E_TYPE_TABLE_MODEL) - -#define ETSS_CLASS(object) (E_TABLE_SUBSET_GET_CLASS(object)) - -#define VALID_ROW(etss, row) (row >= -1 && row < etss->n_map) -#define MAP_ROW(etss, row) (row == -1 ? -1 : etss->map_table[row]) - -static gint -etss_get_view_row (ETableSubset *etss, - gint row) -{ - const gint n = etss->n_map; - const gint * const map_table = etss->map_table; - gint i; - - gint end = MIN (etss->n_map, etss->last_access + 10); - gint start = MAX (0, etss->last_access - 10); - gint initial = MAX (MIN (etss->last_access, end), start); - - for (i = initial; i < end; i++) { - if (map_table[i] == row) { - d (g_print ("a) Found %d from %d\n", i, etss->last_access)); - etss->last_access = i; - return i; - } - } - - for (i = initial - 1; i >= start; i--) { - if (map_table[i] == row) { - d (g_print ("b) Found %d from %d\n", i, etss->last_access)); - etss->last_access = i; - return i; - } - } - - for (i = 0; i < n; i++) { - if (map_table[i] == row) { - d (g_print ("c) Found %d from %d\n", i, etss->last_access)); - etss->last_access = i; - return i; - } - } - return -1; -} - -static void -etss_dispose (GObject *object) -{ - ETableSubset *etss = E_TABLE_SUBSET (object); - - if (etss->source) { - g_signal_handler_disconnect ( - etss->source, - etss->table_model_pre_change_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_no_change_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_changed_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_row_changed_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_cell_changed_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_rows_inserted_id); - g_signal_handler_disconnect ( - etss->source, - etss->table_model_rows_deleted_id); - - g_object_unref (etss->source); - etss->source = NULL; - - etss->table_model_changed_id = 0; - etss->table_model_row_changed_id = 0; - etss->table_model_cell_changed_id = 0; - etss->table_model_rows_inserted_id = 0; - etss->table_model_rows_deleted_id = 0; - } - - G_OBJECT_CLASS (etss_parent_class)->dispose (object); -} - -static void -etss_finalize (GObject *object) -{ - ETableSubset *etss = E_TABLE_SUBSET (object); - - g_free (etss->map_table); - etss->map_table = NULL; - - G_OBJECT_CLASS (etss_parent_class)->finalize (object); -} - -static gint -etss_column_count (ETableModel *etm) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return e_table_model_column_count (etss->source); -} - -static gint -etss_row_count (ETableModel *etm) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return etss->n_map; -} - -static gpointer -etss_value_at (ETableModel *etm, - gint col, - gint row) -{ - ETableSubset *etss = (ETableSubset *) etm; - - g_return_val_if_fail (VALID_ROW (etss, row), NULL); - - etss->last_access = row; - d (g_print ("g) Setting last_access to %d\n", row)); - return e_table_model_value_at (etss->source, col, MAP_ROW (etss, row)); -} - -static void -etss_set_value_at (ETableModel *etm, - gint col, - gint row, - gconstpointer val) -{ - ETableSubset *etss = (ETableSubset *) etm; - - g_return_if_fail (VALID_ROW (etss, row)); - - etss->last_access = row; - d (g_print ("h) Setting last_access to %d\n", row)); - e_table_model_set_value_at (etss->source, col, MAP_ROW (etss, row), val); -} - -static gboolean -etss_is_cell_editable (ETableModel *etm, - gint col, - gint row) -{ - ETableSubset *etss = (ETableSubset *) etm; - - g_return_val_if_fail (VALID_ROW (etss, row), FALSE); - - return e_table_model_is_cell_editable (etss->source, col, MAP_ROW (etss, row)); -} - -static gboolean -etss_has_save_id (ETableModel *etm) -{ - return TRUE; -} - -static gchar * -etss_get_save_id (ETableModel *etm, - gint row) -{ - ETableSubset *etss = (ETableSubset *) etm; - - g_return_val_if_fail (VALID_ROW (etss, row), NULL); - - if (e_table_model_has_save_id (etss->source)) - return e_table_model_get_save_id (etss->source, MAP_ROW (etss, row)); - else - return g_strdup_printf ("%d", MAP_ROW (etss, row)); -} - -static void -etss_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ - ETableSubset *etss = (ETableSubset *) etm; - e_table_model_append_row (etss->source, source, row); -} - -static gpointer -etss_duplicate_value (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return e_table_model_duplicate_value (etss->source, col, value); -} - -static void -etss_free_value (ETableModel *etm, - gint col, - gpointer value) -{ - ETableSubset *etss = (ETableSubset *) etm; - - e_table_model_free_value (etss->source, col, value); -} - -static gpointer -etss_initialize_value (ETableModel *etm, - gint col) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return e_table_model_initialize_value (etss->source, col); -} - -static gboolean -etss_value_is_empty (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return e_table_model_value_is_empty (etss->source, col, value); -} - -static gchar * -etss_value_to_string (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETableSubset *etss = (ETableSubset *) etm; - - return e_table_model_value_to_string (etss->source, col, value); -} - -static void -etss_class_init (ETableSubsetClass *class) -{ - ETableModelClass *table_class = E_TABLE_MODEL_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = etss_dispose; - object_class->finalize = etss_finalize; - - table_class->column_count = etss_column_count; - table_class->row_count = etss_row_count; - table_class->append_row = etss_append_row; - - table_class->value_at = etss_value_at; - table_class->set_value_at = etss_set_value_at; - table_class->is_cell_editable = etss_is_cell_editable; - - table_class->has_save_id = etss_has_save_id; - table_class->get_save_id = etss_get_save_id; - - table_class->duplicate_value = etss_duplicate_value; - table_class->free_value = etss_free_value; - table_class->initialize_value = etss_initialize_value; - table_class->value_is_empty = etss_value_is_empty; - table_class->value_to_string = etss_value_to_string; - - class->proxy_model_pre_change = etss_proxy_model_pre_change_real; - class->proxy_model_no_change = etss_proxy_model_no_change_real; - class->proxy_model_changed = etss_proxy_model_changed_real; - class->proxy_model_row_changed = etss_proxy_model_row_changed_real; - class->proxy_model_cell_changed = etss_proxy_model_cell_changed_real; - class->proxy_model_rows_inserted = etss_proxy_model_rows_inserted_real; - class->proxy_model_rows_deleted = etss_proxy_model_rows_deleted_real; -} - -static void -etss_init (ETableSubset *etss) -{ - etss->last_access = 0; -} - -static void -etss_proxy_model_pre_change_real (ETableSubset *etss, - ETableModel *etm) -{ - e_table_model_pre_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_no_change_real (ETableSubset *etss, - ETableModel *etm) -{ - e_table_model_no_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_changed_real (ETableSubset *etss, - ETableModel *etm) -{ - e_table_model_changed (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_row_changed_real (ETableSubset *etss, - ETableModel *etm, - gint row) -{ - gint view_row = etss_get_view_row (etss, row); - if (view_row != -1) - e_table_model_row_changed (E_TABLE_MODEL (etss), view_row); - else - e_table_model_no_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_cell_changed_real (ETableSubset *etss, - ETableModel *etm, - gint col, - gint row) -{ - gint view_row = etss_get_view_row (etss, row); - if (view_row != -1) - e_table_model_cell_changed (E_TABLE_MODEL (etss), col, view_row); - else - e_table_model_no_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_rows_inserted_real (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count) -{ - e_table_model_no_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_rows_deleted_real (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count) -{ - e_table_model_no_change (E_TABLE_MODEL (etss)); -} - -static void -etss_proxy_model_pre_change (ETableModel *etm, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_pre_change) - (ETSS_CLASS (etss)->proxy_model_pre_change) (etss, etm); -} - -static void -etss_proxy_model_no_change (ETableModel *etm, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_no_change) - (ETSS_CLASS (etss)->proxy_model_no_change) (etss, etm); -} - -static void -etss_proxy_model_changed (ETableModel *etm, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_changed) - (ETSS_CLASS (etss)->proxy_model_changed) (etss, etm); -} - -static void -etss_proxy_model_row_changed (ETableModel *etm, - gint row, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_row_changed) - (ETSS_CLASS (etss)->proxy_model_row_changed) (etss, etm, row); -} - -static void -etss_proxy_model_cell_changed (ETableModel *etm, - gint col, - gint row, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_cell_changed) - (ETSS_CLASS (etss)->proxy_model_cell_changed) (etss, etm, col, row); -} - -static void -etss_proxy_model_rows_inserted (ETableModel *etm, - gint row, - gint col, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_rows_inserted) - (ETSS_CLASS (etss)->proxy_model_rows_inserted) (etss, etm, row, col); -} - -static void -etss_proxy_model_rows_deleted (ETableModel *etm, - gint row, - gint col, - ETableSubset *etss) -{ - if (ETSS_CLASS (etss)->proxy_model_rows_deleted) - (ETSS_CLASS (etss)->proxy_model_rows_deleted) (etss, etm, row, col); -} - -ETableModel * -e_table_subset_construct (ETableSubset *etss, - ETableModel *source, - gint nvals) -{ - guint *buffer; - gint i; - - if (nvals) { - buffer = (guint *) g_malloc (sizeof (guint) * nvals); - if (buffer == NULL) - return NULL; - } else - buffer = NULL; - etss->map_table = (gint *) buffer; - etss->n_map = nvals; - etss->source = source; - g_object_ref (source); - - /* Init */ - for (i = 0; i < nvals; i++) - etss->map_table[i] = i; - - etss->table_model_pre_change_id = g_signal_connect ( - source, "model_pre_change", - G_CALLBACK (etss_proxy_model_pre_change), etss); - etss->table_model_no_change_id = g_signal_connect ( - source, "model_no_change", - G_CALLBACK (etss_proxy_model_no_change), etss); - etss->table_model_changed_id = g_signal_connect ( - source, "model_changed", - G_CALLBACK (etss_proxy_model_changed), etss); - etss->table_model_row_changed_id = g_signal_connect ( - source, "model_row_changed", - G_CALLBACK (etss_proxy_model_row_changed), etss); - etss->table_model_cell_changed_id = g_signal_connect ( - source, "model_cell_changed", - G_CALLBACK (etss_proxy_model_cell_changed), etss); - etss->table_model_rows_inserted_id = g_signal_connect ( - source, "model_rows_inserted", - G_CALLBACK (etss_proxy_model_rows_inserted), etss); - etss->table_model_rows_deleted_id = g_signal_connect ( - source, "model_rows_deleted", - G_CALLBACK (etss_proxy_model_rows_deleted), etss); - - return E_TABLE_MODEL (etss); -} - -ETableModel * -e_table_subset_new (ETableModel *source, - const gint nvals) -{ - ETableSubset *etss = g_object_new (E_TYPE_TABLE_SUBSET, NULL); - - if (e_table_subset_construct (etss, source, nvals) == NULL) { - g_object_unref (etss); - return NULL; - } - - return (ETableModel *) etss; -} - -gint -e_table_subset_model_to_view_row (ETableSubset *ets, - gint model_row) -{ - gint i; - for (i = 0; i < ets->n_map; i++) { - if (ets->map_table[i] == model_row) - return i; - } - return -1; -} - -gint -e_table_subset_view_to_model_row (ETableSubset *ets, - gint view_row) -{ - if (view_row >= 0 && view_row < ets->n_map) - return ets->map_table[view_row]; - else - return -1; -} - -ETableModel * -e_table_subset_get_toplevel (ETableSubset *table) -{ - g_return_val_if_fail (table != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_SUBSET (table), NULL); - - if (E_IS_TABLE_SUBSET (table->source)) - return e_table_subset_get_toplevel (E_TABLE_SUBSET (table->source)); - else - return table->source; -} - -void -e_table_subset_print_debugging (ETableSubset *table_model) -{ - gint i; - for (i = 0; i < table_model->n_map; i++) { - g_print ("%8d\n", table_model->map_table[i]); - } -} diff --git a/widgets/table/e-table-subset.h b/widgets/table/e-table-subset.h deleted file mode 100644 index 9729bdd6b0..0000000000 --- a/widgets/table/e-table-subset.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_SUBSET_H_ -#define _E_TABLE_SUBSET_H_ - -#include <table/e-table-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_SUBSET \ - (e_table_subset_get_type ()) -#define E_TABLE_SUBSET(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_SUBSET, ETableSubset)) -#define E_TABLE_SUBSET_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_SUBSET, ETableSubsetClass)) -#define E_IS_TABLE_SUBSET(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_SUBSET)) -#define E_IS_TABLE_SUBSET_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_SUBSET)) -#define E_TABLE_SUBSET_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_SUBSET, ETableSubsetClass)) - -G_BEGIN_DECLS - -typedef struct _ETableSubset ETableSubset; -typedef struct _ETableSubsetClass ETableSubsetClass; - -struct _ETableSubset { - ETableModel parent; - - ETableModel *source; - gint n_map; - gint *map_table; - - gint last_access; - - gint table_model_pre_change_id; - gint table_model_no_change_id; - gint table_model_changed_id; - gint table_model_row_changed_id; - gint table_model_cell_changed_id; - gint table_model_rows_inserted_id; - gint table_model_rows_deleted_id; -}; - -struct _ETableSubsetClass { - ETableModelClass parent_class; - - void (*proxy_model_pre_change) (ETableSubset *etss, - ETableModel *etm); - void (*proxy_model_no_change) (ETableSubset *etss, - ETableModel *etm); - void (*proxy_model_changed) (ETableSubset *etss, - ETableModel *etm); - void (*proxy_model_row_changed) (ETableSubset *etss, - ETableModel *etm, - gint row); - void (*proxy_model_cell_changed) (ETableSubset *etss, - ETableModel *etm, - gint col, - gint row); - void (*proxy_model_rows_inserted) (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count); - void (*proxy_model_rows_deleted) (ETableSubset *etss, - ETableModel *etm, - gint row, - gint count); -}; - -GType e_table_subset_get_type (void) G_GNUC_CONST; -ETableModel * e_table_subset_new (ETableModel *etm, - gint n_vals); -ETableModel * e_table_subset_construct (ETableSubset *ets, - ETableModel *source, - gint nvals); -gint e_table_subset_model_to_view_row - (ETableSubset *ets, - gint model_row); -gint e_table_subset_view_to_model_row - (ETableSubset *ets, - gint view_row); -ETableModel * e_table_subset_get_toplevel (ETableSubset *table_model); -void e_table_subset_print_debugging (ETableSubset *table_model); - -G_END_DECLS - -#endif /* _E_TABLE_SUBSET_H_ */ - diff --git a/widgets/table/e-table-utils.c b/widgets/table/e-table-utils.c deleted file mode 100644 index 2bdfddc949..0000000000 --- a/widgets/table/e-table-utils.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <libintl.h> /* This file uses dgettext() but no _() */ -#include <string.h> - -#include "e-util/e-util.h" -#include "e-util/e-unicode.h" - -#include "e-table-utils.h" -#include "e-table-header-utils.h" - -ETableHeader * -e_table_state_to_header (GtkWidget *widget, - ETableHeader *full_header, - ETableState *state) -{ - ETableHeader *nh; - const gint max_cols = e_table_header_count (full_header); - gint column; - GValue *val = g_new0 (GValue, 1); - - g_return_val_if_fail (widget, NULL); - g_return_val_if_fail (full_header, NULL); - g_return_val_if_fail (state, NULL); - - nh = e_table_header_new (); - g_value_init (val, G_TYPE_DOUBLE); - g_value_set_double (val, e_table_header_width_extras (widget)); - g_object_set_property (G_OBJECT (nh), "width_extras", val); - g_free (val); - - for (column = 0; column < state->col_count; column++) { - gint col; - gdouble expansion; - ETableCol *table_col; - - col = state->columns[column]; - expansion = state->expansions[column]; - - if (col >= max_cols) - continue; - - table_col = e_table_header_get_column (full_header, col); - - if (expansion >= -1) - table_col->expansion = expansion; - - e_table_header_add_column (nh, table_col, -1); - } - - return nh; -} - -static ETableCol * -et_col_spec_to_col (ETableColumnSpecification *col_spec, - ETableExtras *ete, - const gchar *domain) -{ - ETableCol *col = NULL; - ECell *cell = NULL; - GCompareDataFunc compare = NULL; - ETableSearchFunc search = NULL; - - if (col_spec->cell) - cell = e_table_extras_get_cell (ete, col_spec->cell); - if (col_spec->compare) - compare = e_table_extras_get_compare (ete, col_spec->compare); - if (col_spec->search) - search = e_table_extras_get_search (ete, col_spec->search); - - if (cell && compare) { - gchar *title = dgettext (domain, col_spec->title); - - title = g_strdup (title); - - if (col_spec->pixbuf && *col_spec->pixbuf) { - const gchar *icon_name; - - icon_name = e_table_extras_get_icon_name ( - ete, col_spec->pixbuf); - if (icon_name != NULL) { - col = e_table_col_new ( - col_spec->model_col, - title, icon_name, - col_spec->expansion, - col_spec->minimum_width, - cell, compare, - col_spec->resizable, - col_spec->disabled, - col_spec->priority); - } - } - - if (col == NULL && col_spec->title && *col_spec->title) { - col = e_table_col_new ( - col_spec->model_col, title, NULL, - col_spec->expansion, - col_spec->minimum_width, - cell, compare, - col_spec->resizable, - col_spec->disabled, - col_spec->priority); - } - - if (col) { - col->search = search; - if (col_spec->sortable && !strcmp (col_spec->sortable, "false")) - col->sortable = FALSE; - else - col->sortable = TRUE; - } - g_free (title); - } - if (col && col_spec->compare_col != col_spec->model_col) - g_object_set ( - col, - "compare_col", col_spec->compare_col, - NULL); - return col; -} - -ETableHeader * -e_table_spec_to_full_header (ETableSpecification *spec, - ETableExtras *ete) -{ - ETableHeader *nh; - gint column; - - g_return_val_if_fail (spec, NULL); - g_return_val_if_fail (ete, NULL); - - nh = e_table_header_new (); - - for (column = 0; spec->columns[column]; column++) { - ETableCol *col = et_col_spec_to_col ( - spec->columns[column], ete, spec->domain); - - if (col) { - e_table_header_add_column (nh, col, -1); - g_object_unref (col); - } - } - - return nh; -} - -static gboolean -check_col (ETableCol *col, - gpointer user_data) -{ - return col->search ? TRUE : FALSE; -} - -ETableCol * -e_table_util_calculate_current_search_col (ETableHeader *header, - ETableHeader *full_header, - ETableSortInfo *sort_info, - gboolean always_search) -{ - gint i; - gint count; - ETableCol *col = NULL; - - count = e_table_sort_info_grouping_get_count (sort_info); - - for (i = 0; i < count; i++) { - ETableSortColumn column; - - column = e_table_sort_info_grouping_get_nth (sort_info, i); - - col = e_table_header_get_column (full_header, column.column); - - if (col && col->search) - break; - - col = NULL; - } - - if (col == NULL) { - count = e_table_sort_info_sorting_get_count (sort_info); - for (i = 0; i < count; i++) { - ETableSortColumn column; - - column = e_table_sort_info_sorting_get_nth (sort_info, i); - - col = e_table_header_get_column (full_header, column.column); - - if (col && col->search) - break; - - col = NULL; - } - } - - if (col == NULL && always_search) { - col = e_table_header_prioritized_column_selected (header, check_col, NULL); - } - - return col; -} diff --git a/widgets/table/e-table-utils.h b/widgets/table/e-table-utils.h deleted file mode 100644 index a53e7e4060..0000000000 --- a/widgets/table/e-table-utils.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_UTILS_H_ -#define _E_TABLE_UTILS_H_ - -#include <table/e-table-header.h> -#include <table/e-table-state.h> -#include <table/e-table-specification.h> -#include <table/e-table-extras.h> - -G_BEGIN_DECLS - -ETableHeader * e_table_state_to_header (GtkWidget *widget, - ETableHeader *full_header, - ETableState *state); - -ETableHeader * e_table_spec_to_full_header (ETableSpecification *spec, - ETableExtras *ete); - -ETableCol * e_table_util_calculate_current_search_col - (ETableHeader *header, - ETableHeader *full_header, - ETableSortInfo *sort_info, - gboolean always_search); - -G_END_DECLS - -#endif /* _E_TABLE_UTILS_H_ */ - diff --git a/widgets/table/e-table-without.c b/widgets/table/e-table-without.c deleted file mode 100644 index 6fba6cbe12..0000000000 --- a/widgets/table/e-table-without.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include "e-util/e-util.h" - -#include "e-table-without.h" - -#define E_TABLE_WITHOUT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TABLE_WITHOUT, ETableWithoutPrivate)) - -/* workaround for avoiding API breakage */ -#define etw_get_type e_table_without_get_type -G_DEFINE_TYPE (ETableWithout, etw, E_TYPE_TABLE_SUBSET) - -#define INCREMENT_AMOUNT 10 - -struct _ETableWithoutPrivate { - GHashTable *hash; - - GHashFunc hash_func; - GCompareFunc compare_func; - - ETableWithoutGetKeyFunc get_key_func; - ETableWithoutDuplicateKeyFunc duplicate_key_func; - ETableWithoutFreeKeyFunc free_gotten_key_func; - ETableWithoutFreeKeyFunc free_duplicated_key_func; - - gpointer closure; -}; - -static gboolean -check (ETableWithout *etw, - gint model_row) -{ - gboolean ret_val; - gpointer key; - ETableSubset *etss = E_TABLE_SUBSET (etw); - - if (etw->priv->get_key_func) - key = etw->priv->get_key_func (etss->source, model_row, etw->priv->closure); - else - key = GINT_TO_POINTER (model_row); - ret_val = (g_hash_table_lookup (etw->priv->hash, key) != NULL); - if (etw->priv->free_gotten_key_func) - etw->priv->free_gotten_key_func (key, etw->priv->closure); - return ret_val; -} - -static gboolean -check_with_key (ETableWithout *etw, - gpointer key, - gint model_row) -{ - gboolean ret_val; - gpointer key2; - ETableSubset *etss = E_TABLE_SUBSET (etw); - - if (etw->priv->get_key_func) - key2 = etw->priv->get_key_func (etss->source, model_row, etw->priv->closure); - else - key2 = GINT_TO_POINTER (model_row); - if (etw->priv->compare_func) - ret_val = (etw->priv->compare_func (key, key2)); - else - ret_val = (key == key2); - if (etw->priv->free_gotten_key_func) - etw->priv->free_gotten_key_func (key2, etw->priv->closure); - return ret_val; -} - -static gint -etw_view_to_model_row (ETableWithout *etw, - gint view_row) -{ - ETableSubset *etss = E_TABLE_SUBSET (etw); - return etss->map_table[view_row]; -} - -static void -add_row (ETableWithout *etw, - gint model_row) -{ - ETableSubset *etss = E_TABLE_SUBSET (etw); - - e_table_model_pre_change (E_TABLE_MODEL (etw)); - - etss->map_table = g_renew (int, etss->map_table, etss->n_map + 1); - - etss->map_table[etss->n_map++] = model_row; - - e_table_model_row_inserted (E_TABLE_MODEL (etw), etss->n_map - 1); -} - -static void -remove_row (ETableWithout *etw, - gint view_row) -{ - ETableSubset *etss = E_TABLE_SUBSET (etw); - - e_table_model_pre_change (E_TABLE_MODEL (etw)); - memmove ( - etss->map_table + view_row, - etss->map_table + view_row + 1, - (etss->n_map - view_row - 1) * sizeof (gint)); - etss->n_map--; - e_table_model_row_deleted (E_TABLE_MODEL (etw), view_row); -} - -static void -delete_hash_element (gpointer key, - gpointer value, - gpointer closure) -{ - ETableWithout *etw = closure; - if (etw->priv->free_duplicated_key_func) - etw->priv->free_duplicated_key_func (key, etw->priv->closure); -} - -static void -etw_dispose (GObject *object) -{ - ETableWithoutPrivate *priv; - - priv = E_TABLE_WITHOUT_GET_PRIVATE (object); - - if (priv->hash != NULL) { - g_hash_table_foreach (priv->hash, delete_hash_element, object); - g_hash_table_destroy (priv->hash); - priv->hash = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etw_parent_class)->dispose (object); -} - -static void -etw_proxy_model_rows_inserted (ETableSubset *etss, - ETableModel *etm, - gint model_row, - gint count) -{ - gint i; - ETableWithout *etw = E_TABLE_WITHOUT (etss); - gboolean shift = FALSE; - - /* i is View row */ - if (model_row != etss->n_map) { - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] > model_row) - etss->map_table[i] += count; - } - shift = TRUE; - } - - /* i is Model row */ - for (i = model_row; i < model_row + count; i++) { - if (!check (etw, i)) { - add_row (etw, i); - } - } - if (shift) - e_table_model_changed (E_TABLE_MODEL (etw)); - else - e_table_model_no_change (E_TABLE_MODEL (etw)); -} - -static void -etw_proxy_model_rows_deleted (ETableSubset *etss, - ETableModel *etm, - gint model_row, - gint count) -{ - gint i; /* View row */ - ETableWithout *etw = E_TABLE_WITHOUT (etss); - gboolean shift = FALSE; - - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= model_row && - etss->map_table[i] < model_row + count) { - remove_row (etw, i); - i--; - } else if (etss->map_table[i] >= model_row + count) { - etss->map_table[i] -= count; - shift = TRUE; - } - } - if (shift) - e_table_model_changed (E_TABLE_MODEL (etw)); - else - e_table_model_no_change (E_TABLE_MODEL (etw)); -} - -static void -etw_proxy_model_changed (ETableSubset *etss, - ETableModel *etm) -{ - gint i; /* Model row */ - gint j; /* View row */ - gint row_count; - ETableWithout *etw = E_TABLE_WITHOUT (etss); - - g_free (etss->map_table); - row_count = e_table_model_row_count (etm); - etss->map_table = g_new (int, row_count); - - for (i = 0, j = 0; i < row_count; i++) { - if (!check (etw, i)) { - etss->map_table[j++] = i; - } - } - etss->n_map = j; - - if (E_TABLE_SUBSET_CLASS (etw_parent_class)->proxy_model_changed) - E_TABLE_SUBSET_CLASS (etw_parent_class)->proxy_model_changed (etss, etm); -} - -static void -etw_class_init (ETableWithoutClass *class) -{ - GObjectClass *object_class; - ETableSubsetClass *etss_class; - - g_type_class_add_private (class, sizeof (ETableWithoutPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = etw_dispose; - - etss_class = E_TABLE_SUBSET_CLASS (class); - etss_class->proxy_model_rows_inserted = etw_proxy_model_rows_inserted; - etss_class->proxy_model_rows_deleted = etw_proxy_model_rows_deleted; - etss_class->proxy_model_changed = etw_proxy_model_changed; -} - -static void -etw_init (ETableWithout *etw) -{ - etw->priv = E_TABLE_WITHOUT_GET_PRIVATE (etw); -} - -ETableModel * -e_table_without_construct (ETableWithout *etw, - ETableModel *source, - GHashFunc hash_func, - GCompareFunc compare_func, - ETableWithoutGetKeyFunc get_key_func, - ETableWithoutDuplicateKeyFunc duplicate_key_func, - ETableWithoutFreeKeyFunc free_gotten_key_func, - ETableWithoutFreeKeyFunc free_duplicated_key_func, - gpointer closure) -{ - if (e_table_subset_construct (E_TABLE_SUBSET (etw), source, 1) == NULL) - return NULL; - E_TABLE_SUBSET (etw)->n_map = 0; - - etw->priv->hash_func = hash_func; - etw->priv->compare_func = compare_func; - etw->priv->get_key_func = get_key_func; - etw->priv->duplicate_key_func = duplicate_key_func; - etw->priv->free_gotten_key_func = free_gotten_key_func; - etw->priv->free_duplicated_key_func = free_duplicated_key_func; - etw->priv->closure = closure; - - etw->priv->hash = g_hash_table_new ( - etw->priv->hash_func, etw->priv->compare_func); - - return E_TABLE_MODEL (etw); -} - -ETableModel * -e_table_without_new (ETableModel *source, - GHashFunc hash_func, - GCompareFunc compare_func, - ETableWithoutGetKeyFunc get_key_func, - ETableWithoutDuplicateKeyFunc duplicate_key_func, - ETableWithoutFreeKeyFunc free_gotten_key_func, - ETableWithoutFreeKeyFunc free_duplicated_key_func, - gpointer closure) -{ - ETableWithout *etw = g_object_new (E_TYPE_TABLE_WITHOUT, NULL); - - if (e_table_without_construct (etw, - source, - hash_func, - compare_func, - get_key_func, - duplicate_key_func, - free_gotten_key_func, - free_duplicated_key_func, - closure) - == NULL) { - g_object_unref (etw); - return NULL; - } - - return (ETableModel *) etw; -} - -void -e_table_without_hide (ETableWithout *etw, - gpointer key) -{ - gint i; /* View row */ - ETableSubset *etss = E_TABLE_SUBSET (etw); - - if (etw->priv->duplicate_key_func) - key = etw->priv->duplicate_key_func (key, etw->priv->closure); - - g_hash_table_insert (etw->priv->hash, key, key); - for (i = 0; i < etss->n_map; i++) { - if (check_with_key (etw, key, etw_view_to_model_row (etw, i))) { - remove_row (etw, i); - i--; - } - } -} - -/* An adopted key will later be freed using the free_duplicated_key function. */ -void -e_table_without_hide_adopt (ETableWithout *etw, - gpointer key) -{ - gint i; /* View row */ - ETableSubset *etss = E_TABLE_SUBSET (etw); - - g_hash_table_insert (etw->priv->hash, key, key); - for (i = 0; i < etss->n_map; i++) { - if (check_with_key (etw, key, etw_view_to_model_row (etw, i))) { - remove_row (etw, i); - i--; - } - } -} - -void -e_table_without_show (ETableWithout *etw, - gpointer key) -{ - gint i; /* Model row */ - ETableSubset *etss = E_TABLE_SUBSET (etw); - gint count; - gpointer old_key; - - count = e_table_model_row_count (etss->source); - - for (i = 0; i < count; i++) { - if (check_with_key (etw, key, i)) { - add_row (etw, i); - } - } - if (g_hash_table_lookup_extended (etw->priv->hash, key, &old_key, NULL)) { -#if 0 - if (etw->priv->free_duplicated_key_func) - etw->priv->free_duplicated_key_func (key, etw->priv->closure); -#endif - g_hash_table_remove (etw->priv->hash, key); - } -} - -void -e_table_without_show_all (ETableWithout *etw) -{ - gint i; /* Model row */ - gint row_count; - ETableSubset *etss = E_TABLE_SUBSET (etw); - - e_table_model_pre_change (E_TABLE_MODEL (etw)); - - if (etw->priv->hash) { - g_hash_table_foreach (etw->priv->hash, delete_hash_element, etw); - g_hash_table_destroy (etw->priv->hash); - etw->priv->hash = NULL; - } - etw->priv->hash = g_hash_table_new ( - etw->priv->hash_func, etw->priv->compare_func); - - row_count = e_table_model_row_count (E_TABLE_MODEL (etss->source)); - g_free (etss->map_table); - etss->map_table = g_new (int, row_count); - - for (i = 0; i < row_count; i++) { - etss->map_table[i] = i; - } - etss->n_map = row_count; - - e_table_model_changed (E_TABLE_MODEL (etw)); -} diff --git a/widgets/table/e-table-without.h b/widgets/table/e-table-without.h deleted file mode 100644 index 03e1db6702..0000000000 --- a/widgets/table/e-table-without.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_WITHOUT_H_ -#define _E_TABLE_WITHOUT_H_ - -#include <table/e-table-subset.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE_WITHOUT \ - (e_table_without_get_type ()) -#define E_TABLE_WITHOUT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE_WITHOUT, ETableWithout)) -#define E_TABLE_WITHOUT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE_WITHOUT, ETableWithoutClass)) -#define E_IS_TABLE_WITHOUT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE_WITHOUT)) -#define E_IS_TABLE_WITHOUT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE_WITHOUT)) -#define E_TABLE_WITHOUT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE_WITHOUT, ETableWithoutClass)) - -G_BEGIN_DECLS - -typedef struct _ETableWithout ETableWithout; -typedef struct _ETableWithoutClass ETableWithoutClass; -typedef struct _ETableWithoutPrivate ETableWithoutPrivate; - -typedef gpointer (*ETableWithoutGetKeyFunc) (ETableModel *source, - gint row, - gpointer closure); -typedef gpointer (*ETableWithoutDuplicateKeyFunc)(gconstpointer key, - gpointer closure); -typedef void (*ETableWithoutFreeKeyFunc) (gpointer key, - gpointer closure); - -struct _ETableWithout { - ETableSubset parent; - ETableWithoutPrivate *priv; -}; - -struct _ETableWithoutClass { - ETableSubsetClass parent_class; -}; - -GType e_table_without_get_type (void) G_GNUC_CONST; -ETableModel * e_table_without_new (ETableModel *source, - GHashFunc hash_func, - GCompareFunc compare_func, - ETableWithoutGetKeyFunc get_key_func, - ETableWithoutDuplicateKeyFunc duplicate_key_func, - ETableWithoutFreeKeyFunc free_gotten_key_func, - ETableWithoutFreeKeyFunc free_duplicated_key_func, - gpointer closure); -ETableModel * e_table_without_construct (ETableWithout *etw, - ETableModel *source, - GHashFunc hash_func, - GCompareFunc compare_func, - ETableWithoutGetKeyFunc get_key_func, - ETableWithoutDuplicateKeyFunc duplicate_key_func, - ETableWithoutFreeKeyFunc free_gotten_key_func, - ETableWithoutFreeKeyFunc free_duplicated_key_func, - gpointer closure); -void e_table_without_hide (ETableWithout *etw, - gpointer key); -void e_table_without_hide_adopt (ETableWithout *etw, - gpointer key); -void e_table_without_show (ETableWithout *etw, - gpointer key); -void e_table_without_show_all (ETableWithout *etw); - -G_END_DECLS - -#endif /* _E_TABLE_WITHOUT_H_ */ - diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c deleted file mode 100644 index b73ae55ba6..0000000000 --- a/widgets/table/e-table.c +++ /dev/null @@ -1,3626 +0,0 @@ -/* - * e-table.c - A graphical view of a Table. - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <glib/gstdio.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "gal-a11y-e-table.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas.h" -#include "misc/e-canvas-background.h" -#include "misc/e-canvas-vbox.h" -#include "e-util/e-unicode.h" - -#include "e-table.h" -#include "e-table-click-to-add.h" -#include "e-table-column-specification.h" -#include "e-table-group-leaf.h" -#include "e-table-header-item.h" -#include "e-table-header-utils.h" -#include "e-table-subset.h" -#include "e-table-utils.h" - -#define COLUMN_HEADER_HEIGHT 16 - -#define d(x) - -#if d(!)0 -#define e_table_item_leave_edit_(x) \ - (e_table_item_leave_edit ((x)), \ - g_print ("%s: e_table_item_leave_edit\n", __FUNCTION__)) -#else -#define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x))) -#endif - -enum { - CURSOR_CHANGE, - CURSOR_ACTIVATED, - SELECTION_CHANGE, - DOUBLE_CLICK, - RIGHT_CLICK, - CLICK, - KEY_PRESS, - START_DRAG, - STATE_CHANGE, - WHITE_SPACE_EVENT, - - CUT_CLIPBOARD, - COPY_CLIPBOARD, - PASTE_CLIPBOARD, - SELECT_ALL, - - TABLE_DRAG_BEGIN, - TABLE_DRAG_END, - TABLE_DRAG_DATA_GET, - TABLE_DRAG_DATA_DELETE, - - TABLE_DRAG_LEAVE, - TABLE_DRAG_MOTION, - TABLE_DRAG_DROP, - TABLE_DRAG_DATA_RECEIVED, - - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_LENGTH_THRESHOLD, - PROP_MODEL, - PROP_UNIFORM_ROW_HEIGHT, - PROP_ALWAYS_SEARCH, - PROP_USE_CLICK_TO_ADD, - PROP_HADJUSTMENT, - PROP_VADJUSTMENT, - PROP_HSCROLL_POLICY, - PROP_VSCROLL_POLICY -}; - -enum { - ET_SCROLL_UP = 1 << 0, - ET_SCROLL_DOWN = 1 << 1, - ET_SCROLL_LEFT = 1 << 2, - ET_SCROLL_RIGHT = 1 << 3 -}; - -static guint et_signals[LAST_SIGNAL] = { 0 }; - -static void e_table_fill_table (ETable *e_table, ETableModel *model); -static gboolean changed_idle (gpointer data); - -static void et_grab_focus (GtkWidget *widget); - -static void et_drag_begin (GtkWidget *widget, - GdkDragContext *context, - ETable *et); -static void et_drag_end (GtkWidget *widget, - GdkDragContext *context, - ETable *et); -static void et_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETable *et); -static void et_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - ETable *et); - -static void et_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - ETable *et); -static gboolean et_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETable *et); -static gboolean et_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETable *et); -static void et_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - ETable *et); - -static gint et_focus (GtkWidget *container, GtkDirectionType direction); - -static void scroll_off (ETable *et); -static void scroll_on (ETable *et, guint scroll_direction); - -G_DEFINE_TYPE_WITH_CODE (ETable, e_table, GTK_TYPE_TABLE, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) - -static void -et_disconnect_model (ETable *et) -{ - if (et->model == NULL) - return; - - if (et->table_model_change_id != 0) - g_signal_handler_disconnect ( - et->model, et->table_model_change_id); - if (et->table_row_change_id != 0) - g_signal_handler_disconnect ( - et->model, et->table_row_change_id); - if (et->table_cell_change_id != 0) - g_signal_handler_disconnect ( - et->model, et->table_cell_change_id); - if (et->table_rows_inserted_id != 0) - g_signal_handler_disconnect ( - et->model, et->table_rows_inserted_id); - if (et->table_rows_deleted_id != 0) - g_signal_handler_disconnect ( - et->model, et->table_rows_deleted_id); - - et->table_model_change_id = 0; - et->table_row_change_id = 0; - et->table_cell_change_id = 0; - et->table_rows_inserted_id = 0; - et->table_rows_deleted_id = 0; -} - -static void -e_table_state_change (ETable *et) -{ - if (et->state_change_freeze) - et->state_changed = TRUE; - else - g_signal_emit (et, et_signals[STATE_CHANGE], 0); -} - -#define CHECK_HORIZONTAL(et) \ - if ((et)->horizontal_scrolling || (et)->horizontal_resize) \ - e_table_header_update_horizontal (et->header); - -static void -clear_current_search_col (ETable *et) -{ - et->search_col_set = FALSE; -} - -static ETableCol * -current_search_col (ETable *et) -{ - if (!et->search_col_set) { - et->current_search_col = - e_table_util_calculate_current_search_col ( - et->header, - et->full_header, - et->sort_info, - et->always_search); - et->search_col_set = TRUE; - } - - return et->current_search_col; -} - -static void -et_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - ETable *et = E_TABLE (widget); - - GTK_WIDGET_CLASS (e_table_parent_class)-> - get_preferred_width (widget, minimum, natural); - - if (et->horizontal_resize) { - *minimum = MAX (*minimum, et->header_width); - *natural = MAX (*natural, et->header_width); - } -} - -static void -et_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - GTK_WIDGET_CLASS (e_table_parent_class)-> - get_preferred_height (widget, minimum, natural); -} - -static void -set_header_width (ETable *et) -{ - if (et->horizontal_resize) { - et->header_width = e_table_header_min_width (et->header); - gtk_widget_queue_resize (GTK_WIDGET (et)); - } -} - -static void -structure_changed (ETableHeader *header, - ETable *et) -{ - e_table_state_change (et); - set_header_width (et); - clear_current_search_col (et); -} - -static void -expansion_changed (ETableHeader *header, - ETable *et) -{ - e_table_state_change (et); - set_header_width (et); -} - -static void -dimension_changed (ETableHeader *header, - gint total_width, - ETable *et) -{ - set_header_width (et); -} - -static void -disconnect_header (ETable *e_table) -{ - if (e_table->header == NULL) - return; - - if (e_table->structure_change_id) - g_signal_handler_disconnect ( - e_table->header, e_table->structure_change_id); - if (e_table->expansion_change_id) - g_signal_handler_disconnect ( - e_table->header, e_table->expansion_change_id); - if (e_table->dimension_change_id) - g_signal_handler_disconnect ( - e_table->header, e_table->dimension_change_id); - - g_object_unref (e_table->header); - e_table->header = NULL; -} - -static void -connect_header (ETable *e_table, - ETableState *state) -{ - if (e_table->header != NULL) - disconnect_header (e_table); - - e_table->header = e_table_state_to_header ( - GTK_WIDGET (e_table), e_table->full_header, state); - - e_table->structure_change_id = g_signal_connect ( - e_table->header, "structure_change", - G_CALLBACK (structure_changed), e_table); - e_table->expansion_change_id = g_signal_connect ( - e_table->header, "expansion_change", - G_CALLBACK (expansion_changed), e_table); - e_table->dimension_change_id = g_signal_connect ( - e_table->header, "dimension_change", - G_CALLBACK (dimension_changed), e_table); -} - -static void -et_dispose (GObject *object) -{ - ETable *et = E_TABLE (object); - - et_disconnect_model (et); - - if (et->search) { - if (et->search_search_id) - g_signal_handler_disconnect ( - et->search, et->search_search_id); - if (et->search_accept_id) - g_signal_handler_disconnect ( - et->search, et->search_accept_id); - g_object_unref (et->search); - et->search = NULL; - } - - if (et->group_info_change_id) { - g_signal_handler_disconnect ( - et->sort_info, et->group_info_change_id); - et->group_info_change_id = 0; - } - - if (et->sort_info_change_id) { - g_signal_handler_disconnect ( - et->sort_info, et->sort_info_change_id); - et->sort_info_change_id = 0; - } - - if (et->reflow_idle_id) { - g_source_remove (et->reflow_idle_id); - et->reflow_idle_id = 0; - } - - scroll_off (et); - - disconnect_header (et); - - if (et->model) { - g_object_unref (et->model); - et->model = NULL; - } - - if (et->full_header) { - g_object_unref (et->full_header); - et->full_header = NULL; - } - - if (et->sort_info) { - g_object_unref (et->sort_info); - et->sort_info = NULL; - } - - if (et->sorter) { - g_object_unref (et->sorter); - et->sorter = NULL; - } - - if (et->selection) { - g_object_unref (et->selection); - et->selection = NULL; - } - - if (et->spec) { - g_object_unref (et->spec); - et->spec = NULL; - } - - if (et->header_canvas != NULL) { - gtk_widget_destroy (GTK_WIDGET (et->header_canvas)); - et->header_canvas = NULL; - } - - if (et->site != NULL) { - e_table_drag_source_unset (et); - et->site = NULL; - } - - if (et->table_canvas != NULL) { - gtk_widget_destroy (GTK_WIDGET (et->table_canvas)); - et->table_canvas = NULL; - } - - if (et->rebuild_idle_id != 0) { - g_source_remove (et->rebuild_idle_id); - et->rebuild_idle_id = 0; - } - - g_free (et->click_to_add_message); - et->click_to_add_message = NULL; - - g_free (et->domain); - et->domain = NULL; - - G_OBJECT_CLASS (e_table_parent_class)->dispose (object); -} - -static void -et_unrealize (GtkWidget *widget) -{ - scroll_off (E_TABLE (widget)); - - if (GTK_WIDGET_CLASS (e_table_parent_class)->unrealize) - GTK_WIDGET_CLASS (e_table_parent_class)->unrealize (widget); -} - -static gboolean -check_row (ETable *et, - gint model_row, - gint col, - ETableSearchFunc search, - gchar *string) -{ - gconstpointer value; - - value = e_table_model_value_at (et->model, col, model_row); - - return search (value, string); -} - -static gboolean -et_search_search (ETableSearch *search, - gchar *string, - ETableSearchFlags flags, - ETable *et) -{ - gint cursor; - gint rows; - gint i; - ETableCol *col = current_search_col (et); - - if (col == NULL) - return FALSE; - - rows = e_table_model_row_count (et->model); - - g_object_get ( - et->selection, - "cursor_row", &cursor, - NULL); - - if ((flags & E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST) && - cursor < rows && cursor >= 0 && - check_row (et, cursor, col->col_idx, col->search, string)) - return TRUE; - - cursor = e_sorter_model_to_sorted (E_SORTER (et->sorter), cursor); - - for (i = cursor + 1; i < rows; i++) { - gint model_row = e_sorter_sorted_to_model (E_SORTER (et->sorter), i); - if (check_row (et, model_row, col->col_idx, col->search, string)) { - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->selection), - model_row, col->col_idx, GDK_CONTROL_MASK); - return TRUE; - } - } - - for (i = 0; i < cursor; i++) { - gint model_row = e_sorter_sorted_to_model (E_SORTER (et->sorter), i); - if (check_row (et, model_row, col->col_idx, col->search, string)) { - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->selection), - model_row, col->col_idx, GDK_CONTROL_MASK); - return TRUE; - } - } - - cursor = e_sorter_sorted_to_model (E_SORTER (et->sorter), cursor); - - /* Check if the cursor row is the only matching row. */ - return (!(flags & E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST) && - cursor < rows && cursor >= 0 && - check_row (et, cursor, col->col_idx, col->search, string)); -} - -static void -et_search_accept (ETableSearch *search, - ETable *et) -{ - gint cursor; - ETableCol *col = current_search_col (et); - - if (col == NULL) - return; - - g_object_get (et->selection, "cursor_row", &cursor, NULL); - - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->selection), cursor, col->col_idx, 0); -} - -static void -init_search (ETable *e_table) -{ - if (e_table->search != NULL) - return; - - e_table->search = e_table_search_new (); - - e_table->search_search_id = g_signal_connect ( - e_table->search, "search", - G_CALLBACK (et_search_search), e_table); - e_table->search_accept_id = g_signal_connect ( - e_table->search, "accept", - G_CALLBACK (et_search_accept), e_table); -} - -static void -et_finalize (GObject *object) -{ - ETable *et = E_TABLE (object); - - g_free (et->click_to_add_message); - et->click_to_add_message = NULL; - - g_free (et->domain); - et->domain = NULL; - - G_OBJECT_CLASS (e_table_parent_class)->finalize (object); -} - -static void -e_table_init (ETable *e_table) -{ - gtk_widget_set_can_focus (GTK_WIDGET (e_table), TRUE); - - gtk_table_set_homogeneous (GTK_TABLE (e_table), FALSE); - - e_table->sort_info = NULL; - e_table->group_info_change_id = 0; - e_table->sort_info_change_id = 0; - e_table->structure_change_id = 0; - e_table->expansion_change_id = 0; - e_table->dimension_change_id = 0; - e_table->reflow_idle_id = 0; - e_table->scroll_idle_id = 0; - - e_table->alternating_row_colors = 1; - e_table->horizontal_draw_grid = 1; - e_table->vertical_draw_grid = 1; - e_table->draw_focus = 1; - e_table->cursor_mode = E_CURSOR_SIMPLE; - e_table->length_threshold = 200; - e_table->uniform_row_height = FALSE; - - e_table->need_rebuild = 0; - e_table->rebuild_idle_id = 0; - - e_table->horizontal_scrolling = FALSE; - e_table->horizontal_resize = FALSE; - - e_table->click_to_add_message = NULL; - e_table->domain = NULL; - - e_table->drop_row = -1; - e_table->drop_col = -1; - e_table->site = NULL; - - e_table->do_drag = 0; - - e_table->sorter = NULL; - e_table->selection = e_table_selection_model_new (); - e_table->cursor_loc = E_TABLE_CURSOR_LOC_NONE; - e_table->spec = NULL; - - e_table->always_search = g_getenv ("GAL_ALWAYS_SEARCH") ? TRUE : FALSE; - - e_table->search = NULL; - e_table->search_search_id = 0; - e_table->search_accept_id = 0; - - e_table->current_search_col = NULL; - - e_table->header_width = 0; - - e_table->state_changed = FALSE; - e_table->state_change_freeze = 0; -} - -/* Grab_focus handler for the ETable */ -static void -et_grab_focus (GtkWidget *widget) -{ - ETable *e_table; - - e_table = E_TABLE (widget); - - gtk_widget_grab_focus (GTK_WIDGET (e_table->table_canvas)); -} - -/* Focus handler for the ETable */ -static gint -et_focus (GtkWidget *container, - GtkDirectionType direction) -{ - ETable *e_table; - - e_table = E_TABLE (container); - - if (gtk_container_get_focus_child (GTK_CONTAINER (container))) { - gtk_container_set_focus_child (GTK_CONTAINER (container), NULL); - return FALSE; - } - - return gtk_widget_child_focus (GTK_WIDGET (e_table->table_canvas), direction); -} - -static void -set_header_canvas_width (ETable *e_table) -{ - gdouble oldwidth, oldheight, width; - - if (!(e_table->header_item && e_table->header_canvas && e_table->table_canvas)) - return; - - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_table->table_canvas), - NULL, NULL, &width, NULL); - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_table->header_canvas), - NULL, NULL, &oldwidth, &oldheight); - - if (oldwidth != width || - oldheight != E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1) - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (e_table->header_canvas), - 0, 0, width, /* COLUMN_HEADER_HEIGHT - 1 */ - E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1); - -} - -static void -header_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *alloc, - ETable *e_table) -{ - GtkAllocation allocation; - - set_header_canvas_width (e_table); - - gtk_widget_get_allocation ( - GTK_WIDGET (e_table->header_canvas), &allocation); - - /* When the header item is created ->height == 0, - * as the font is only created when everything is realized. - * So we set the usize here as well, so that the size of the - * header is correct */ - if (allocation.height != E_TABLE_HEADER_ITEM (e_table->header_item)->height) - g_object_set ( - e_table->header_canvas, "height-request", - E_TABLE_HEADER_ITEM (e_table->header_item)->height, - NULL); -} - -static void -group_info_changed (ETableSortInfo *info, - ETable *et) -{ - gboolean will_be_grouped = e_table_sort_info_grouping_get_count (info) > 0; - clear_current_search_col (et); - if (et->is_grouped || will_be_grouped) { - et->need_rebuild = TRUE; - if (!et->rebuild_idle_id) { - g_object_run_dispose (G_OBJECT (et->group)); - et->group = NULL; - et->rebuild_idle_id = g_idle_add_full (20, changed_idle, et, NULL); - } - } - e_table_state_change (et); -} - -static void -sort_info_changed (ETableSortInfo *info, - ETable *et) -{ - clear_current_search_col (et); - e_table_state_change (et); -} - -static void -e_table_setup_header (ETable *e_table) -{ - gchar *pointer; - e_table->header_canvas = GNOME_CANVAS (e_canvas_new ()); - - gtk_widget_show (GTK_WIDGET (e_table->header_canvas)); - - pointer = g_strdup_printf ("%p", (gpointer) e_table); - - e_table->header_item = gnome_canvas_item_new ( - gnome_canvas_root (e_table->header_canvas), - e_table_header_item_get_type (), - "ETableHeader", e_table->header, - "full_header", e_table->full_header, - "sort_info", e_table->sort_info, - "dnd_code", pointer, - "table", e_table, - NULL); - - g_free (pointer); - - g_signal_connect ( - e_table->header_canvas, "size_allocate", - G_CALLBACK (header_canvas_size_allocate), e_table); - - g_object_set ( - e_table->header_canvas, "height-request", - E_TABLE_HEADER_ITEM (e_table->header_item)->height, NULL); -} - -static gboolean -table_canvas_reflow_idle (ETable *e_table) -{ - gdouble height, width; - gdouble oldheight, oldwidth; - GtkAllocation allocation; - - gtk_widget_get_allocation ( - GTK_WIDGET (e_table->table_canvas), &allocation); - - g_object_get ( - e_table->canvas_vbox, - "height", &height, "width", &width, NULL); - height = MAX ((gint) height, allocation.height); - width = MAX ((gint) width, allocation.width); - /* I have no idea why this needs to be -1, but it works. */ - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_table->table_canvas), - NULL, NULL, &oldwidth, &oldheight); - - if (oldwidth != width - 1 || - oldheight != height - 1) { - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (e_table->table_canvas), - 0, 0, width - 1, height - 1); - set_header_canvas_width (e_table); - } - e_table->reflow_idle_id = 0; - return FALSE; -} - -static void -table_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *alloc, - ETable *e_table) -{ - gdouble width; - gdouble height; - GValue *val = g_new0 (GValue, 1); - g_value_init (val, G_TYPE_DOUBLE); - - width = alloc->width; - g_value_set_double (val, width); - g_object_get ( - e_table->canvas_vbox, - "height", &height, - NULL); - height = MAX ((gint) height, alloc->height); - - g_object_set ( - e_table->canvas_vbox, - "width", width, - NULL); - g_object_set_property (G_OBJECT (e_table->header), "width", val); - g_free (val); - if (e_table->reflow_idle_id) - g_source_remove (e_table->reflow_idle_id); - table_canvas_reflow_idle (e_table); - - e_table->size_allocated = TRUE; - - if (e_table->need_rebuild && !e_table->rebuild_idle_id) - e_table->rebuild_idle_id = g_idle_add_full (20, changed_idle, e_table, NULL); -} - -static void -table_canvas_reflow (GnomeCanvas *canvas, - ETable *e_table) -{ - if (!e_table->reflow_idle_id) - e_table->reflow_idle_id = g_idle_add_full ( - 400, (GSourceFunc) table_canvas_reflow_idle, - e_table, NULL); -} - -static void -click_to_add_cursor_change (ETableClickToAdd *etcta, - gint row, - gint col, - ETable *et) -{ - if (et->cursor_loc == E_TABLE_CURSOR_LOC_TABLE) { - e_selection_model_clear (E_SELECTION_MODEL (et->selection)); - } - et->cursor_loc = E_TABLE_CURSOR_LOC_ETCTA; -} - -static void -group_cursor_change (ETableGroup *etg, - gint row, - ETable *et) -{ - ETableCursorLoc old_cursor_loc; - - old_cursor_loc = et->cursor_loc; - - et->cursor_loc = E_TABLE_CURSOR_LOC_TABLE; - g_signal_emit (et, et_signals[CURSOR_CHANGE], 0, row); - - if (old_cursor_loc == E_TABLE_CURSOR_LOC_ETCTA && et->click_to_add) - e_table_click_to_add_commit (E_TABLE_CLICK_TO_ADD (et->click_to_add)); -} - -static void -group_cursor_activated (ETableGroup *etg, - gint row, - ETable *et) -{ - g_signal_emit (et, et_signals[CURSOR_ACTIVATED], 0, row); -} - -static void -group_double_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETable *et) -{ - g_signal_emit (et, et_signals[DOUBLE_CLICK], 0, row, col, event); -} - -static gboolean -group_right_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETable *et) -{ - gboolean return_val = FALSE; - - g_signal_emit ( - et, et_signals[RIGHT_CLICK], 0, - row, col, event, &return_val); - - return return_val; -} - -static gboolean -group_click (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETable *et) -{ - gboolean return_val = 0; - - g_signal_emit ( - et, et_signals[CLICK], 0, - row, col, event, &return_val); - - return return_val; -} - -static gboolean -group_key_press (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETable *et) -{ - gboolean return_val = FALSE; - GdkEventKey *key = (GdkEventKey *) event; - gint y, row_local, col_local; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gdouble page_size; - gdouble upper; - gdouble value; - - scrollable = GTK_SCROLLABLE (et->table_canvas); - adjustment = gtk_scrollable_get_vadjustment (scrollable); - - switch (key->keyval) { - case GDK_KEY_Page_Down: - case GDK_KEY_KP_Page_Down: - page_size = gtk_adjustment_get_page_size (adjustment); - upper = gtk_adjustment_get_value (adjustment); - value = gtk_adjustment_get_value (adjustment); - - y = CLAMP (value + (2 * page_size - 50), 0, upper); - y -= value; - e_table_get_cell_at (et, 30, y, &row_local, &col_local); - - if (row_local == -1) - row_local = e_table_model_row_count (et->model) - 1; - - row_local = e_table_view_to_model_row (et, row_local); - col_local = e_selection_model_cursor_col (E_SELECTION_MODEL (et->selection)); - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->selection), - row_local, col_local, key->state); - return_val = 1; - break; - case GDK_KEY_Page_Up: - case GDK_KEY_KP_Page_Up: - page_size = gtk_adjustment_get_page_size (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - value = gtk_adjustment_get_value (adjustment); - - y = CLAMP (value - (page_size - 50), 0, upper); - y -= value; - e_table_get_cell_at (et, 30, y, &row_local, &col_local); - - if (row_local == -1) - row_local = 0; - - row_local = e_table_view_to_model_row (et, row_local); - col_local = e_selection_model_cursor_col (E_SELECTION_MODEL (et->selection)); - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->selection), - row_local, col_local, key->state); - return_val = 1; - break; - case GDK_KEY_BackSpace: - init_search (et); - if (e_table_search_backspace (et->search)) - return TRUE; - /* Fall through */ - default: - init_search (et); - if ((key->state & ~(GDK_SHIFT_MASK | GDK_LOCK_MASK | - GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | - GDK_MOD4_MASK | GDK_MOD5_MASK)) == 0 - && ((key->keyval >= GDK_KEY_a && key->keyval <= GDK_KEY_z) || - (key->keyval >= GDK_KEY_A && key->keyval <= GDK_KEY_Z) || - (key->keyval >= GDK_KEY_0 && key->keyval <= GDK_KEY_9))) - e_table_search_input_character (et->search, key->keyval); - g_signal_emit ( - et, et_signals[KEY_PRESS], 0, - row, col, event, &return_val); - break; - } - return return_val; -} - -static gboolean -group_start_drag (ETableGroup *etg, - gint row, - gint col, - GdkEvent *event, - ETable *et) -{ - gboolean return_val = TRUE; - - g_signal_emit ( - et, et_signals[START_DRAG], 0, - row, col, event, &return_val); - - return return_val; -} - -static void -et_table_model_changed (ETableModel *model, - ETable *et) -{ - et->need_rebuild = TRUE; - if (!et->rebuild_idle_id) { - g_object_run_dispose (G_OBJECT (et->group)); - et->group = NULL; - et->rebuild_idle_id = g_idle_add_full (20, changed_idle, et, NULL); - } -} - -static void -et_table_row_changed (ETableModel *table_model, - gint row, - ETable *et) -{ - if (!et->need_rebuild) { - if (e_table_group_remove (et->group, row)) - e_table_group_add (et->group, row); - CHECK_HORIZONTAL (et); - } -} - -static void -et_table_cell_changed (ETableModel *table_model, - gint view_col, - gint row, - ETable *et) -{ - et_table_row_changed (table_model, row, et); -} - -static void -et_table_rows_inserted (ETableModel *table_model, - gint row, - gint count, - ETable *et) -{ - /* This number has already been decremented. */ - gint row_count = e_table_model_row_count (table_model); - if (!et->need_rebuild) { - gint i; - if (row != row_count - count) - e_table_group_increment (et->group, row, count); - for (i = 0; i < count; i++) - e_table_group_add (et->group, row + i); - CHECK_HORIZONTAL (et); - } -} - -static void -et_table_rows_deleted (ETableModel *table_model, - gint row, - gint count, - ETable *et) -{ - gint row_count = e_table_model_row_count (table_model); - if (!et->need_rebuild) { - gint i; - for (i = 0; i < count; i++) - e_table_group_remove (et->group, row + i); - if (row != row_count) - e_table_group_decrement (et->group, row, count); - CHECK_HORIZONTAL (et); - } -} - -static void -et_build_groups (ETable *et) -{ - gboolean was_grouped = et->is_grouped; - - et->is_grouped = e_table_sort_info_grouping_get_count (et->sort_info) > 0; - - et->group = e_table_group_new ( - GNOME_CANVAS_GROUP (et->canvas_vbox), - et->full_header, - et->header, - et->model, - et->sort_info, - 0); - - if (et->use_click_to_add_end) - e_canvas_vbox_add_item_start ( - E_CANVAS_VBOX (et->canvas_vbox), - GNOME_CANVAS_ITEM (et->group)); - else - e_canvas_vbox_add_item ( - E_CANVAS_VBOX (et->canvas_vbox), - GNOME_CANVAS_ITEM (et->group)); - - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (et->group), - "alternating_row_colors", et->alternating_row_colors, - "horizontal_draw_grid", et->horizontal_draw_grid, - "vertical_draw_grid", et->vertical_draw_grid, - "drawfocus", et->draw_focus, - "cursor_mode", et->cursor_mode, - "length_threshold", et->length_threshold, - "uniform_row_height", et->uniform_row_height, - "selection_model", et->selection, - NULL); - - g_signal_connect ( - et->group, "cursor_change", - G_CALLBACK (group_cursor_change), et); - g_signal_connect ( - et->group, "cursor_activated", - G_CALLBACK (group_cursor_activated), et); - g_signal_connect ( - et->group, "double_click", - G_CALLBACK (group_double_click), et); - g_signal_connect ( - et->group, "right_click", - G_CALLBACK (group_right_click), et); - g_signal_connect ( - et->group, "click", - G_CALLBACK (group_click), et); - g_signal_connect ( - et->group, "key_press", - G_CALLBACK (group_key_press), et); - g_signal_connect ( - et->group, "start_drag", - G_CALLBACK (group_start_drag), et); - - if (!(et->is_grouped) && was_grouped) - et_disconnect_model (et); - - if (et->is_grouped && (!was_grouped)) { - et->table_model_change_id = g_signal_connect ( - et->model, "model_changed", - G_CALLBACK (et_table_model_changed), et); - - et->table_row_change_id = g_signal_connect ( - et->model, "model_row_changed", - G_CALLBACK (et_table_row_changed), et); - - et->table_cell_change_id = g_signal_connect ( - et->model, "model_cell_changed", - G_CALLBACK (et_table_cell_changed), et); - - et->table_rows_inserted_id = g_signal_connect ( - et->model, "model_rows_inserted", - G_CALLBACK (et_table_rows_inserted), et); - - et->table_rows_deleted_id = g_signal_connect ( - et->model, "model_rows_deleted", - G_CALLBACK (et_table_rows_deleted), et); - - } - - if (et->is_grouped) - e_table_fill_table (et, et->model); -} - -static gboolean -changed_idle (gpointer data) -{ - ETable *et = E_TABLE (data); - - /* Wait until we have a valid size allocation. */ - if (et->need_rebuild && et->size_allocated) { - GtkWidget *widget; - GtkAllocation allocation; - - if (et->group) - g_object_run_dispose (G_OBJECT (et->group)); - et_build_groups (et); - - widget = GTK_WIDGET (et->table_canvas); - gtk_widget_get_allocation (widget, &allocation); - - g_object_set ( - et->canvas_vbox, - "width", (gdouble) allocation.width, - NULL); - - table_canvas_size_allocate (widget, &allocation, et); - - et->need_rebuild = 0; - } - - et->rebuild_idle_id = 0; - - CHECK_HORIZONTAL (et); - - return FALSE; -} - -static void -et_canvas_realize (GtkWidget *canvas, - ETable *e_table) -{ - GtkWidget *widget; - GtkStyle *style; - - widget = GTK_WIDGET (e_table->table_canvas); - style = gtk_widget_get_style (widget); - - gnome_canvas_item_set ( - e_table->white_item, - "fill_color_gdk", &style->base[GTK_STATE_NORMAL], - NULL); - - CHECK_HORIZONTAL (e_table); - set_header_width (e_table); -} - -static gboolean -white_item_event (GnomeCanvasItem *white_item, - GdkEvent *event, - ETable *e_table) -{ - gboolean return_val = 0; - - g_signal_emit ( - e_table, et_signals[WHITE_SPACE_EVENT], 0, - event, &return_val); - - return return_val; -} - -static void -et_eti_leave_edit (ETable *et) -{ - GnomeCanvas *canvas = et->table_canvas; - - if (gtk_widget_has_focus (GTK_WIDGET (canvas))) { - GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item; - - if (E_IS_TABLE_ITEM (item)) { - e_table_item_leave_edit_(E_TABLE_ITEM (item)); - } - } -} - -static gint -et_canvas_root_event (GnomeCanvasItem *root, - GdkEvent *event, - ETable *e_table) -{ - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - if (event->button.button != 4 && event->button.button != 5) { - et_eti_leave_edit (e_table); - return TRUE; - } - break; - default: - break; - } - - return FALSE; -} - -/* Finds the first descendant of the group that is an ETableItem and focuses it */ -static void -focus_first_etable_item (ETableGroup *group) -{ - GnomeCanvasGroup *cgroup; - GList *l; - - cgroup = GNOME_CANVAS_GROUP (group); - - for (l = cgroup->item_list; l; l = l->next) { - GnomeCanvasItem *i; - - i = GNOME_CANVAS_ITEM (l->data); - - if (E_IS_TABLE_GROUP (i)) - focus_first_etable_item (E_TABLE_GROUP (i)); - else if (E_IS_TABLE_ITEM (i)) { - e_table_item_set_cursor (E_TABLE_ITEM (i), 0, 0); - gnome_canvas_item_grab_focus (i); - } - } -} - -/* Handler for focus events in the table_canvas; we have to repaint ourselves - * always, and also give the focus to some ETableItem if we get focused. - */ -static gint -table_canvas_focus_event_cb (GtkWidget *widget, - GdkEventFocus *event, - gpointer data) -{ - GnomeCanvas *canvas; - ECanvas *ecanvas; - ETable *etable; - - gtk_widget_queue_draw (widget); - canvas = GNOME_CANVAS (widget); - ecanvas = E_CANVAS (widget); - - if (!event->in) { - gtk_im_context_focus_out (ecanvas->im_context); - return FALSE; - } else { - gtk_im_context_focus_in (ecanvas->im_context); - } - - etable = E_TABLE (data); - - if (e_table_model_row_count (etable->model) < 1 - && (etable->click_to_add) - && !(E_TABLE_CLICK_TO_ADD (etable->click_to_add)->row)) { - gnome_canvas_item_grab_focus (etable->canvas_vbox); - gnome_canvas_item_grab_focus (etable->click_to_add); - } else if (!canvas->focused_item && etable->group) { - focus_first_etable_item (etable->group); - } else if (canvas->focused_item) { - ESelectionModel *selection = (ESelectionModel *) etable->selection; - - /* check whether click_to_add already got the focus */ - if (etable->click_to_add) { - GnomeCanvasItem *row = E_TABLE_CLICK_TO_ADD (etable->click_to_add)->row; - if (canvas->focused_item == row) - return TRUE; - } - - if (e_selection_model_cursor_row (selection) == -1) - focus_first_etable_item (etable->group); - } - - return FALSE; -} - -static gboolean -canvas_vbox_event (ECanvasVbox *vbox, - GdkEventKey *key, - ETable *etable) -{ - if (key->type != GDK_KEY_PRESS && - key->type != GDK_KEY_RELEASE) { - return FALSE; - } - switch (key->keyval) { - case GDK_KEY_Tab: - case GDK_KEY_KP_Tab: - case GDK_KEY_ISO_Left_Tab: - if ((key->state & GDK_CONTROL_MASK) && etable->click_to_add) { - gnome_canvas_item_grab_focus (etable->click_to_add); - break; - } - default: - return FALSE; - } - - return TRUE; -} - -static gboolean -click_to_add_event (ETableClickToAdd *etcta, - GdkEventKey *key, - ETable *etable) -{ - if (key->type != GDK_KEY_PRESS && - key->type != GDK_KEY_RELEASE) { - return FALSE; - } - switch (key->keyval) { - case GDK_KEY_Tab: - case GDK_KEY_KP_Tab: - case GDK_KEY_ISO_Left_Tab: - if (key->state & GDK_CONTROL_MASK) { - if (etable->group) { - if (e_table_model_row_count (etable->model) > 0) - focus_first_etable_item (etable->group); - else - gtk_widget_child_focus ( - gtk_widget_get_toplevel ( - GTK_WIDGET (etable->table_canvas)), - GTK_DIR_TAB_FORWARD); - break; - } - } - default: - return FALSE; - } - - return FALSE; -} - -static void -e_table_setup_table (ETable *e_table, - ETableHeader *full_header, - ETableHeader *header, - ETableModel *model) -{ - GtkWidget *widget; - GtkStyle *style; - - e_table->table_canvas = GNOME_CANVAS (e_canvas_new ()); - g_signal_connect ( - e_table->table_canvas, "size_allocate", - G_CALLBACK (table_canvas_size_allocate), e_table); - g_signal_connect ( - e_table->table_canvas, "focus_in_event", - G_CALLBACK (table_canvas_focus_event_cb), e_table); - g_signal_connect ( - e_table->table_canvas, "focus_out_event", - G_CALLBACK (table_canvas_focus_event_cb), e_table); - - g_signal_connect ( - e_table, "drag_begin", - G_CALLBACK (et_drag_begin), e_table); - g_signal_connect ( - e_table, "drag_end", - G_CALLBACK (et_drag_end), e_table); - g_signal_connect ( - e_table, "drag_data_get", - G_CALLBACK (et_drag_data_get), e_table); - g_signal_connect ( - e_table, "drag_data_delete", - G_CALLBACK (et_drag_data_delete), e_table); - g_signal_connect ( - e_table, "drag_motion", - G_CALLBACK (et_drag_motion), e_table); - g_signal_connect ( - e_table, "drag_leave", - G_CALLBACK (et_drag_leave), e_table); - g_signal_connect ( - e_table, "drag_drop", - G_CALLBACK (et_drag_drop), e_table); - g_signal_connect ( - e_table, "drag_data_received", - G_CALLBACK (et_drag_data_received), e_table); - - g_signal_connect ( - e_table->table_canvas, "reflow", - G_CALLBACK (table_canvas_reflow), e_table); - - widget = GTK_WIDGET (e_table->table_canvas); - style = gtk_widget_get_style (widget); - - gtk_widget_show (widget); - - e_table->white_item = gnome_canvas_item_new ( - gnome_canvas_root (e_table->table_canvas), - e_canvas_background_get_type (), - "fill_color_gdk", &style->base[GTK_STATE_NORMAL], - NULL); - - g_signal_connect ( - e_table->white_item, "event", - G_CALLBACK (white_item_event), e_table); - - g_signal_connect ( - e_table->table_canvas, "realize", - G_CALLBACK (et_canvas_realize), e_table); - - g_signal_connect ( - gnome_canvas_root (e_table->table_canvas), "event", - G_CALLBACK (et_canvas_root_event), e_table); - - e_table->canvas_vbox = gnome_canvas_item_new ( - gnome_canvas_root (e_table->table_canvas), - e_canvas_vbox_get_type (), - "spacing", 10.0, - NULL); - - g_signal_connect ( - e_table->canvas_vbox, "event", - G_CALLBACK (canvas_vbox_event), e_table); - - et_build_groups (e_table); - - if (e_table->use_click_to_add) { - e_table->click_to_add = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (e_table->canvas_vbox), - e_table_click_to_add_get_type (), - "header", e_table->header, - "model", e_table->model, - "message", e_table->click_to_add_message, - NULL); - - if (e_table->use_click_to_add_end) - e_canvas_vbox_add_item ( - E_CANVAS_VBOX (e_table->canvas_vbox), - e_table->click_to_add); - else - e_canvas_vbox_add_item_start ( - E_CANVAS_VBOX (e_table->canvas_vbox), - e_table->click_to_add); - - g_signal_connect ( - e_table->click_to_add, "event", - G_CALLBACK (click_to_add_event), e_table); - g_signal_connect ( - e_table->click_to_add, "cursor_change", - G_CALLBACK (click_to_add_cursor_change), e_table); - } -} - -static void -e_table_fill_table (ETable *e_table, - ETableModel *model) -{ - e_table_group_add_all (e_table->group); -} - -/** - * e_table_set_state_object: - * @e_table: The #ETable object to modify - * @state: The #ETableState to use - * - * This routine sets the state of the #ETable from the given - * #ETableState. - * - **/ -void -e_table_set_state_object (ETable *e_table, - ETableState *state) -{ - GValue *val; - GtkWidget *widget; - GtkAllocation allocation; - - val = g_new0 (GValue, 1); - g_value_init (val, G_TYPE_DOUBLE); - - connect_header (e_table, state); - - widget = GTK_WIDGET (e_table->table_canvas); - gtk_widget_get_allocation (widget, &allocation); - - g_value_set_double (val, (gdouble) allocation.width); - g_object_set_property (G_OBJECT (e_table->header), "width", val); - g_free (val); - - if (e_table->sort_info) { - if (e_table->group_info_change_id) - g_signal_handler_disconnect ( - e_table->sort_info, - e_table->group_info_change_id); - if (e_table->sort_info_change_id) - g_signal_handler_disconnect ( - e_table->sort_info, - e_table->sort_info_change_id); - g_object_unref (e_table->sort_info); - } - if (state->sort_info) { - e_table->sort_info = e_table_sort_info_duplicate (state->sort_info); - e_table_sort_info_set_can_group ( - e_table->sort_info, e_table->allow_grouping); - e_table->group_info_change_id = g_signal_connect ( - e_table->sort_info, "group_info_changed", - G_CALLBACK (group_info_changed), e_table); - - e_table->sort_info_change_id = g_signal_connect ( - e_table->sort_info, "sort_info_changed", - G_CALLBACK (sort_info_changed), e_table); - } - else - e_table->sort_info = NULL; - - if (e_table->sorter) - g_object_set ( - e_table->sorter, - "sort_info", e_table->sort_info, - NULL); - if (e_table->header_item) - g_object_set ( - e_table->header_item, - "ETableHeader", e_table->header, - "sort_info", e_table->sort_info, - NULL); - if (e_table->click_to_add) - g_object_set ( - e_table->click_to_add, - "header", e_table->header, - NULL); - - e_table->need_rebuild = TRUE; - if (!e_table->rebuild_idle_id) - e_table->rebuild_idle_id = g_idle_add_full (20, changed_idle, e_table, NULL); - - e_table_state_change (e_table); -} - -/** - * e_table_set_state: - * @e_table: The #ETable object to modify - * @state_str: a string representing an #ETableState - * - * This routine sets the state of the #ETable from a string. - * - **/ -void -e_table_set_state (ETable *e_table, - const gchar *state_str) -{ - ETableState *state; - - g_return_if_fail (E_IS_TABLE (e_table)); - g_return_if_fail (state_str != NULL); - - state = e_table_state_new (); - e_table_state_load_from_string (state, state_str); - - if (state->col_count > 0) - e_table_set_state_object (e_table, state); - - g_object_unref (state); -} - -/** - * e_table_load_state: - * @e_table: The #ETable object to modify - * @filename: name of the file to use - * - * This routine sets the state of the #ETable from a file. - * - **/ -void -e_table_load_state (ETable *e_table, - const gchar *filename) -{ - ETableState *state; - - g_return_if_fail (E_IS_TABLE (e_table)); - g_return_if_fail (filename != NULL); - - state = e_table_state_new (); - e_table_state_load_from_file (state, filename); - - if (state->col_count > 0) - e_table_set_state_object (e_table, state); - - g_object_unref (state); -} - -/** - * e_table_get_state_object: - * @e_table: #ETable object to act on - * - * Builds an #ETableState corresponding to the current state of the - * #ETable. - * - * Return value: - * The %ETableState object generated. - **/ -ETableState * -e_table_get_state_object (ETable *e_table) -{ - ETableState *state; - gint full_col_count; - gint i, j; - - state = e_table_state_new (); - if (state->sort_info) - g_object_unref (state->sort_info); - state->sort_info = e_table->sort_info; - g_object_ref (state->sort_info); - - state->col_count = e_table_header_count (e_table->header); - full_col_count = e_table_header_count (e_table->full_header); - state->columns = g_new (int, state->col_count); - state->expansions = g_new (double, state->col_count); - for (i = 0; i < state->col_count; i++) { - ETableCol *col = e_table_header_get_column (e_table->header, i); - state->columns[i] = -1; - for (j = 0; j < full_col_count; j++) { - if (col->col_idx == e_table_header_index (e_table->full_header, j)) { - state->columns[i] = j; - break; - } - } - state->expansions[i] = col->expansion; - } - - return state; -} - -/** - * e_table_get_state: - * @e_table: The #ETable to act on. - * - * Builds a state object based on the current state and returns the - * string corresponding to that state. - * - * Return value: - * A string describing the current state of the #ETable. - **/ -gchar *e_table_get_state (ETable *e_table) -{ - ETableState *state; - gchar *string; - - state = e_table_get_state_object (e_table); - string = e_table_state_save_to_string (state); - g_object_unref (state); - return string; -} - -/** - * e_table_save_state: - * @e_table: The #ETable to act on - * @filename: name of the file to save to - * - * Saves the state of the @e_table object into the file pointed by - * @filename. - * - **/ -void -e_table_save_state (ETable *e_table, - const gchar *filename) -{ - ETableState *state; - - state = e_table_get_state_object (e_table); - e_table_state_save_to_file (state, filename); - g_object_unref (state); -} - -static void -et_selection_model_selection_changed (ETableGroup *etg, - ETable *et) -{ - g_signal_emit (et, et_signals[SELECTION_CHANGE], 0); -} - -static void -et_selection_model_selection_row_changed (ETableGroup *etg, - gint row, - ETable *et) -{ - g_signal_emit (et, et_signals[SELECTION_CHANGE], 0); -} - -static ETable * -et_real_construct (ETable *e_table, - ETableModel *etm, - ETableExtras *ete, - ETableSpecification *specification, - ETableState *state) -{ - gint row = 0; - gint col_count, i; - GValue *val; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - - val = g_new0 (GValue, 1); - g_value_init (val, G_TYPE_OBJECT); - - if (ete) - g_object_ref (ete); - else { - ete = e_table_extras_new (); - } - - e_table->domain = g_strdup (specification->domain); - - e_table->use_click_to_add = specification->click_to_add; - e_table->use_click_to_add_end = specification->click_to_add_end; - e_table->click_to_add_message = specification->click_to_add_message ? - g_strdup ( - dgettext (e_table->domain, - specification->click_to_add_message)) : NULL; - e_table->alternating_row_colors = specification->alternating_row_colors; - e_table->horizontal_draw_grid = specification->horizontal_draw_grid; - e_table->vertical_draw_grid = specification->vertical_draw_grid; - e_table->draw_focus = specification->draw_focus; - e_table->cursor_mode = specification->cursor_mode; - e_table->full_header = e_table_spec_to_full_header (specification, ete); - - col_count = e_table_header_count (e_table->full_header); - for (i = 0; i < col_count; i++) { - ETableCol *col = e_table_header_get_column (e_table->full_header, i); - if (col && col->search) { - e_table->current_search_col = col; - e_table->search_col_set = TRUE; - break; - } - } - - e_table->model = etm; - g_object_ref (etm); - - connect_header (e_table, state); - e_table->horizontal_scrolling = specification->horizontal_scrolling; - e_table->horizontal_resize = specification->horizontal_resize; - e_table->allow_grouping = specification->allow_grouping; - - e_table->sort_info = g_object_ref (state->sort_info); - - e_table_sort_info_set_can_group ( - e_table->sort_info, e_table->allow_grouping); - - e_table->group_info_change_id = g_signal_connect ( - e_table->sort_info, "group_info_changed", - G_CALLBACK (group_info_changed), e_table); - - e_table->sort_info_change_id = g_signal_connect ( - e_table->sort_info, "sort_info_changed", - G_CALLBACK (sort_info_changed), e_table); - - g_value_set_object (val, e_table->sort_info); - g_object_set_property (G_OBJECT (e_table->header), "sort_info", val); - g_free (val); - - e_table->sorter = e_table_sorter_new ( - etm, e_table->full_header, e_table->sort_info); - - g_object_set ( - e_table->selection, - "model", etm, - "selection_mode", specification->selection_mode, - "cursor_mode", specification->cursor_mode, - "sorter", e_table->sorter, - "header", e_table->header, - NULL); - - g_signal_connect ( - e_table->selection, "selection_changed", - G_CALLBACK (et_selection_model_selection_changed), e_table); - g_signal_connect ( - e_table->selection, "selection_row_changed", - G_CALLBACK (et_selection_model_selection_row_changed), e_table); - - if (!specification->no_headers) - e_table_setup_header (e_table); - - e_table_setup_table ( - e_table, e_table->full_header, e_table->header, etm); - e_table_fill_table (e_table, etm); - - scrollable = GTK_SCROLLABLE (e_table->table_canvas); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - gtk_adjustment_set_step_increment (adjustment, 20); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - gtk_adjustment_set_step_increment (adjustment, 20); - - if (!specification->no_headers) { - /* The header */ - gtk_table_attach ( - GTK_TABLE (e_table), GTK_WIDGET (e_table->header_canvas), - 0, 1, 0 + row, 1 + row, - GTK_FILL | GTK_EXPAND, - GTK_FILL, 0, 0); - row++; - } - gtk_table_attach ( - GTK_TABLE (e_table), GTK_WIDGET (e_table->table_canvas), - 0, 1, 0 + row, 1 + row, - GTK_FILL | GTK_EXPAND, - GTK_FILL | GTK_EXPAND, - 0, 0); - - g_object_unref (ete); - - return e_table; -} - -/** - * e_table_construct: - * @e_table: The newly created #ETable object. - * @etm: The model for this table. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec_str: The spec. - * @state_str: An optional state. (%NULL is valid.) - * - * This is the internal implementation of e_table_new() for use by - * subclasses or language bindings. See e_table_new() for details. - * - * Return value: - * The passed in value @e_table or %NULL if there's an error. - **/ -ETable * -e_table_construct (ETable *e_table, - ETableModel *etm, - ETableExtras *ete, - const gchar *spec_str, - const gchar *state_str) -{ - ETableSpecification *specification; - ETableState *state; - - g_return_val_if_fail (E_IS_TABLE (e_table), NULL); - g_return_val_if_fail (E_IS_TABLE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec_str != NULL, NULL); - - g_object_ref (etm); - - specification = e_table_specification_new (); - g_object_ref (specification); - if (!e_table_specification_load_from_string (specification, spec_str)) { - g_object_unref (specification); - return NULL; - } - - if (state_str) { - state = e_table_state_new (); - g_object_ref (state); - e_table_state_load_from_string (state, state_str); - if (state->col_count <= 0) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - } else { - state = specification->state; - g_object_ref (state); - } - - e_table = et_real_construct (e_table, etm, ete, specification, state); - - e_table->spec = specification; - g_object_unref (state); - - return e_table; -} - -/** - * e_table_construct_from_spec_file: - * @e_table: The newly created #ETable object. - * @etm: The model for this table. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec_fn: The filename of the spec. - * @state_fn: An optional state file. (%NULL is valid.) - * - * This is the internal implementation of e_table_new_from_spec_file() - * for use by subclasses or language bindings. See - * e_table_new_from_spec_file() for details. - * - * Return value: - * The passed in value @e_table or %NULL if there's an error. - **/ -ETable * -e_table_construct_from_spec_file (ETable *e_table, - ETableModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn) -{ - ETableSpecification *specification; - ETableState *state; - - g_return_val_if_fail (E_IS_TABLE (e_table), NULL); - g_return_val_if_fail (E_IS_TABLE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec_fn != NULL, NULL); - - specification = e_table_specification_new (); - if (!e_table_specification_load_from_file (specification, spec_fn)) { - g_object_unref (specification); - return NULL; - } - - if (state_fn) { - state = e_table_state_new (); - if (!e_table_state_load_from_file (state, state_fn)) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - if (state->col_count <= 0) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - } else { - state = specification->state; - g_object_ref (state); - } - - e_table = et_real_construct (e_table, etm, ete, specification, state); - - e_table->spec = specification; - g_object_unref (state); - - return e_table; -} - -/** - * e_table_new: - * @etm: The model for this table. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec: The spec. - * @state: An optional state. (%NULL is valid.) - * - * This function creates an #ETable from the given parameters. The - * #ETableModel is a table model to be represented. The #ETableExtras - * is an optional set of pixbufs, cells, and sorting functions to be - * used when interpreting the spec. If you pass in %NULL it uses the - * default #ETableExtras. (See e_table_extras_new()). - * - * @spec is the specification of the set of viewable columns and the - * default sorting state and such. @state is an optional string - * specifying the current sorting state and such. If @state is NULL, - * then the default state from the spec will be used. - * - * Return value: - * The newly created #ETable or %NULL if there's an error. - **/ -GtkWidget * -e_table_new (ETableModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state) -{ - ETable *e_table; - - g_return_val_if_fail (E_IS_TABLE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec != NULL, NULL); - - e_table = g_object_new (E_TYPE_TABLE, NULL); - - e_table = e_table_construct (e_table, etm, ete, spec, state); - - return GTK_WIDGET (e_table); -} - -/** - * e_table_new_from_spec_file: - * @etm: The model for this table. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec_fn: The filename of the spec. - * @state_fn: An optional state file. (%NULL is valid.) - * - * This is very similar to e_table_new(), except instead of passing in - * strings you pass in the file names of the spec and state to load. - * - * @spec_fn is the filename of the spec to load. If this file doesn't - * exist, e_table_new_from_spec_file will return %NULL. - * - * @state_fn is the filename of the initial state to load. If this is - * %NULL or if the specified file doesn't exist, the default state - * from the spec file is used. - * - * Return value: - * The newly created #ETable or %NULL if there's an error. - **/ -GtkWidget * -e_table_new_from_spec_file (ETableModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn) -{ - ETable *e_table; - - g_return_val_if_fail (E_IS_TABLE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec_fn != NULL, NULL); - - e_table = g_object_new (E_TYPE_TABLE, NULL); - - e_table = e_table_construct_from_spec_file (e_table, etm, ete, spec_fn, state_fn); - - return GTK_WIDGET (e_table); -} - -/** - * e_table_set_cursor_row: - * @e_table: The #ETable to set the cursor row of - * @row: The row number - * - * Sets the cursor row and the selection to the given row number. - **/ -void -e_table_set_cursor_row (ETable *e_table, - gint row) -{ - g_return_if_fail (E_IS_TABLE (e_table)); - g_return_if_fail (row >= 0); - - g_object_set ( - e_table->selection, - "cursor_row", row, - NULL); -} - -/** - * e_table_get_cursor_row: - * @e_table: The #ETable to query - * - * Calculates the cursor row. -1 means that we don't have a cursor. - * - * Return value: - * Cursor row - **/ -gint -e_table_get_cursor_row (ETable *e_table) -{ - gint row; - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - g_object_get ( - e_table->selection, - "cursor_row", &row, - NULL); - return row; -} - -/** - * e_table_selected_row_foreach: - * @e_table: The #ETable to act on - * @callback: The callback function to call - * @closure: The value passed to the callback's closure argument - * - * Calls the given @callback function once for every selected row. - * - * If you change the selection or delete or add rows to the table - * during these callbacks, problems can occur. A standard thing to do - * is to create a list of rows or objects the function is called upon - * and then act upon that list. (In inverse order if it's rows.) - **/ -void -e_table_selected_row_foreach (ETable *e_table, - EForeachFunc callback, - gpointer closure) -{ - g_return_if_fail (E_IS_TABLE (e_table)); - - e_selection_model_foreach (E_SELECTION_MODEL (e_table->selection), - callback, - closure); -} - -/** - * e_table_selected_count: - * @e_table: The #ETable to query - * - * Counts the number of selected rows. - * - * Return value: - * The number of rows selected. - **/ -gint -e_table_selected_count (ETable *e_table) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - return e_selection_model_selected_count (E_SELECTION_MODEL (e_table->selection)); -} - -/** - * e_table_select_all: - * @table: The #ETable to modify - * - * Selects all the rows in @table. - **/ -void -e_table_select_all (ETable *table) -{ - g_return_if_fail (E_IS_TABLE (table)); - - e_selection_model_select_all (E_SELECTION_MODEL (table->selection)); -} - -/** - * e_table_invert_selection: - * @table: The #ETable to modify - * - * Inverts the selection in @table. - **/ -void -e_table_invert_selection (ETable *table) -{ - g_return_if_fail (E_IS_TABLE (table)); - - e_selection_model_invert_selection (E_SELECTION_MODEL (table->selection)); -} - -/** - * e_table_get_printable: - * @e_table: #ETable to query - * - * Used for printing your #ETable. - * - * Return value: - * The #EPrintable to print. - **/ -EPrintable * -e_table_get_printable (ETable *e_table) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), NULL); - - return e_table_group_get_printable (e_table->group); -} - -/** - * e_table_right_click_up: - * @table: The #ETable to modify. - * - * Call this function when you're done handling the right click if you - * return TRUE from the "right_click" signal. - **/ -void -e_table_right_click_up (ETable *table) -{ - e_selection_model_right_click_up (E_SELECTION_MODEL (table->selection)); -} - -/** - * e_table_commit_click_to_add: - * @table: The #ETable to modify - * - * Commits the current values in the click to add to the table. - **/ -void -e_table_commit_click_to_add (ETable *table) -{ - et_eti_leave_edit (table); - if (table->click_to_add) - e_table_click_to_add_commit ( - E_TABLE_CLICK_TO_ADD (table->click_to_add)); -} - -static void -et_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETable *etable = E_TABLE (object); - - switch (property_id) { - case PROP_MODEL: - g_value_set_object (value, etable->model); - break; - case PROP_UNIFORM_ROW_HEIGHT: - g_value_set_boolean (value, etable->uniform_row_height); - break; - case PROP_ALWAYS_SEARCH: - g_value_set_boolean (value, etable->always_search); - break; - case PROP_USE_CLICK_TO_ADD: - g_value_set_boolean (value, etable->use_click_to_add); - break; - case PROP_HADJUSTMENT: - if (etable->table_canvas) - g_object_get_property ( - G_OBJECT (etable->table_canvas), - "hadjustment", value); - else - g_value_set_object (value, NULL); - break; - case PROP_VADJUSTMENT: - if (etable->table_canvas) - g_object_get_property ( - G_OBJECT (etable->table_canvas), - "vadjustment", value); - else - g_value_set_object (value, NULL); - break; - case PROP_HSCROLL_POLICY: - if (etable->table_canvas) - g_object_get_property ( - G_OBJECT (etable->table_canvas), - "hscroll-policy", value); - else - g_value_set_enum (value, 0); - break; - case PROP_VSCROLL_POLICY: - if (etable->table_canvas) - g_object_get_property ( - G_OBJECT (etable->table_canvas), - "vscroll-policy", value); - else - g_value_set_enum (value, 0); - break; - default: - break; - } -} - -typedef struct { - gchar *arg; - gboolean setting; -} bool_closure; - -static void -et_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETable *etable = E_TABLE (object); - - switch (property_id) { - case PROP_LENGTH_THRESHOLD: - etable->length_threshold = g_value_get_int (value); - if (etable->group) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etable->group), - "length_threshold", - etable->length_threshold, - NULL); - } - break; - case PROP_UNIFORM_ROW_HEIGHT: - etable->uniform_row_height = g_value_get_boolean (value); - if (etable->group) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etable->group), - "uniform_row_height", - etable->uniform_row_height, - NULL); - } - break; - case PROP_ALWAYS_SEARCH: - if (etable->always_search == g_value_get_boolean (value)) - return; - - etable->always_search = g_value_get_boolean (value); - clear_current_search_col (etable); - break; - case PROP_USE_CLICK_TO_ADD: - if (etable->use_click_to_add == g_value_get_boolean (value)) - return; - - etable->use_click_to_add = g_value_get_boolean (value); - clear_current_search_col (etable); - - if (etable->use_click_to_add) { - etable->click_to_add = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etable->canvas_vbox), - e_table_click_to_add_get_type (), - "header", etable->header, - "model", etable->model, - "message", etable->click_to_add_message, - NULL); - - if (etable->use_click_to_add_end) - e_canvas_vbox_add_item ( - E_CANVAS_VBOX (etable->canvas_vbox), - etable->click_to_add); - else - e_canvas_vbox_add_item_start ( - E_CANVAS_VBOX (etable->canvas_vbox), - etable->click_to_add); - - g_signal_connect ( - etable->click_to_add, "cursor_change", - G_CALLBACK (click_to_add_cursor_change), - etable); - } else { - g_object_run_dispose (G_OBJECT (etable->click_to_add)); - etable->click_to_add = NULL; - } - break; - case PROP_HADJUSTMENT: - if (etable->table_canvas) - g_object_set_property ( - G_OBJECT (etable->table_canvas), - "hadjustment", value); - break; - case PROP_VADJUSTMENT: - if (etable->table_canvas) - g_object_set_property ( - G_OBJECT (etable->table_canvas), - "vadjustment", value); - break; - case PROP_HSCROLL_POLICY: - if (etable->table_canvas) - g_object_set_property ( - G_OBJECT (etable->table_canvas), - "hscroll-policy", value); - break; - case PROP_VSCROLL_POLICY: - if (etable->table_canvas) - g_object_set_property ( - G_OBJECT (etable->table_canvas), - "vscroll-policy", value); - break; - } -} - -/** - * e_table_get_next_row: - * @e_table: The #ETable to query - * @model_row: The model row to go from - * - * This function is used when your table is sorted, but you're using - * model row numbers. It returns the next row in sorted order as a model row. - * - * Return value: - * The model row number. - **/ -gint -e_table_get_next_row (ETable *e_table, - gint model_row) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - if (e_table->sorter) { - gint i; - i = e_sorter_model_to_sorted (E_SORTER (e_table->sorter), model_row); - i++; - if (i < e_table_model_row_count (e_table->model)) { - return e_sorter_sorted_to_model (E_SORTER (e_table->sorter), i); - } else - return -1; - } else - if (model_row < e_table_model_row_count (e_table->model) - 1) - return model_row + 1; - else - return -1; -} - -/** - * e_table_get_prev_row: - * @e_table: The #ETable to query - * @model_row: The model row to go from - * - * This function is used when your table is sorted, but you're using - * model row numbers. It returns the previous row in sorted order as - * a model row. - * - * Return value: - * The model row number. - **/ -gint -e_table_get_prev_row (ETable *e_table, - gint model_row) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - if (e_table->sorter) { - gint i; - i = e_sorter_model_to_sorted (E_SORTER (e_table->sorter), model_row); - i--; - if (i >= 0) - return e_sorter_sorted_to_model (E_SORTER (e_table->sorter), i); - else - return -1; - } else - return model_row - 1; -} - -/** - * e_table_model_to_view_row: - * @e_table: The #ETable to query - * @model_row: The model row number - * - * Turns a model row into a view row. - * - * Return value: - * The view row number. - **/ -gint -e_table_model_to_view_row (ETable *e_table, - gint model_row) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - if (e_table->sorter) - return e_sorter_model_to_sorted (E_SORTER (e_table->sorter), model_row); - else - return model_row; -} - -/** - * e_table_view_to_model_row: - * @e_table: The #ETable to query - * @view_row: The view row number - * - * Turns a view row into a model row. - * - * Return value: - * The model row number. - **/ -gint -e_table_view_to_model_row (ETable *e_table, - gint view_row) -{ - g_return_val_if_fail (E_IS_TABLE (e_table), -1); - - if (e_table->sorter) - return e_sorter_sorted_to_model (E_SORTER (e_table->sorter), view_row); - else - return view_row; -} - -/** - * e_table_get_cell_at: - * @table: An #ETable widget - * @x: X coordinate for the pixel - * @y: Y coordinate for the pixel - * @row_return: Pointer to return the row value - * @col_return: Pointer to return the column value - * - * Return the row and column for the cell in which the pixel at (@x, @y) is - * contained. - **/ -void -e_table_get_cell_at (ETable *table, - gint x, - gint y, - gint *row_return, - gint *col_return) -{ - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - - g_return_if_fail (E_IS_TABLE (table)); - g_return_if_fail (row_return != NULL); - g_return_if_fail (col_return != NULL); - - /* FIXME it would be nice if it could handle a NULL row_return or - * col_return gracefully. */ - - scrollable = GTK_SCROLLABLE (table->table_canvas); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - x += gtk_adjustment_get_value (adjustment); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - y += gtk_adjustment_get_value (adjustment); - - e_table_group_compute_location ( - table->group, &x, &y, row_return, col_return); -} - -/** - * e_table_get_cell_geometry: - * @table: The #ETable. - * @row: The row to get the geometry of. - * @col: The col to get the geometry of. - * @x_return: Returns the x coordinate of the upper left hand corner - * of the cell with respect to the widget. - * @y_return: Returns the y coordinate of the upper left hand corner - * of the cell with respect to the widget. - * @width_return: Returns the width of the cell. - * @height_return: Returns the height of the cell. - * - * Returns the x, y, width, and height of the given cell. These can - * all be #NULL and they just won't be set. - **/ -void -e_table_get_cell_geometry (ETable *table, - gint row, - gint col, - gint *x_return, - gint *y_return, - gint *width_return, - gint *height_return) -{ - GtkAllocation allocation; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - - g_return_if_fail (E_IS_TABLE (table)); - - scrollable = GTK_SCROLLABLE (table->table_canvas); - - e_table_group_get_cell_geometry ( - table->group, &row, &col, x_return, y_return, - width_return, height_return); - - if (x_return && table->table_canvas) { - adjustment = gtk_scrollable_get_hadjustment (scrollable); - (*x_return) -= gtk_adjustment_get_value (adjustment); - } - - if (y_return) { - if (table->table_canvas) { - adjustment = gtk_scrollable_get_vadjustment (scrollable); - (*y_return) -= gtk_adjustment_get_value (adjustment); - } - - if (table->header_canvas) { - gtk_widget_get_allocation ( - GTK_WIDGET (table->header_canvas), - &allocation); - (*y_return) += allocation.height; - } - } -} - -/** - * e_table_get_mouse_over_cell: - * - * Similar to e_table_get_cell_at, only here we check - * based on the mouse motion information in the group. - **/ -void -e_table_get_mouse_over_cell (ETable *table, - gint *row, - gint *col) -{ - g_return_if_fail (E_IS_TABLE (table)); - - if (!table->group) - return; - - e_table_group_get_mouse_over (table->group, row, col); -} - -/** - * e_table_get_selection_model: - * @table: The #ETable to query - * - * Returns the table's #ESelectionModel in case you want to access it - * directly. - * - * Return value: - * The #ESelectionModel. - **/ -ESelectionModel * -e_table_get_selection_model (ETable *table) -{ - g_return_val_if_fail (E_IS_TABLE (table), NULL); - - return E_SELECTION_MODEL (table->selection); -} - -struct _ETableDragSourceSite -{ - GdkModifierType start_button_mask; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction actions; /* Possible actions */ - GdkPixbuf *pixbuf; /* Icon for drag data */ - - /* Stored button press information to detect drag beginning */ - gint state; - gint x, y; - gint row, col; -}; - -typedef enum -{ - GTK_DRAG_STATUS_DRAG, - GTK_DRAG_STATUS_WAIT, - GTK_DRAG_STATUS_DROP -} GtkDragStatus; - -typedef struct _GtkDragDestInfo GtkDragDestInfo; -typedef struct _GtkDragSourceInfo GtkDragSourceInfo; - -struct _GtkDragDestInfo -{ - GtkWidget *widget; /* Widget in which drag is in */ - GdkDragContext *context; /* Drag context */ - GtkDragSourceInfo *proxy_source; /* Set if this is a proxy drag */ - GtkSelectionData *proxy_data; /* Set while retrieving proxied data */ - guint dropped : 1; /* Set after we receive a drop */ - guint32 proxy_drop_time; /* Timestamp for proxied drop */ - guint proxy_drop_wait : 1; /* Set if we are waiting for a - * status reply before sending - * a proxied drop on. - */ - gint drop_x, drop_y; /* Position of drop */ -}; - -struct _GtkDragSourceInfo -{ - GtkWidget *widget; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction possible_actions; /* Actions allowed by source */ - GdkDragContext *context; /* drag context */ - GtkWidget *icon_window; /* Window for drag */ - GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ - GdkCursor *cursor; /* Cursor for drag */ - gint hot_x, hot_y; /* Hot spot for drag */ - gint button; /* mouse button starting drag */ - - GtkDragStatus status; /* drag status */ - GdkEvent *last_event; /* motion event waiting for response */ - - gint start_x, start_y; /* Initial position */ - gint cur_x, cur_y; /* Current Position */ - - GList *selections; /* selections we've claimed */ - - GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ - - guint drop_timeout; /* Timeout for aborting drop */ - guint destroy_icon : 1; /* If true, destroy icon_window - */ -}; - -/* Drag & drop stuff. */ -/* Target */ - -/** - * e_table_drag_get_data: - * @table: - * @row: - * @col: - * @context: - * @target: - * @time: - * - * - **/ -void -e_table_drag_get_data (ETable *table, - gint row, - gint col, - GdkDragContext *context, - GdkAtom target, - guint32 time) -{ - g_return_if_fail (E_IS_TABLE (table)); - - gtk_drag_get_data ( - GTK_WIDGET (table), - context, - target, - time); -} - -/** - * e_table_drag_highlight: - * @table: The #ETable to highlight - * @row: The row number of the cell to highlight - * @col: The column number of the cell to highlight - * - * Set col to -1 to highlight the entire row. If row is -1, this is - * identical to e_table_drag_unhighlight(). - **/ -void -e_table_drag_highlight (ETable *table, - gint row, - gint col) -{ - GtkAllocation allocation; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - GtkStyle *style; - - g_return_if_fail (E_IS_TABLE (table)); - - scrollable = GTK_SCROLLABLE (table->table_canvas); - style = gtk_widget_get_style (GTK_WIDGET (table)); - gtk_widget_get_allocation (GTK_WIDGET (scrollable), &allocation); - - if (row != -1) { - gint x, y, width, height; - if (col == -1) { - e_table_get_cell_geometry (table, row, 0, &x, &y, &width, &height); - x = 0; - width = allocation.width; - } else { - e_table_get_cell_geometry (table, row, col, &x, &y, &width, &height); - adjustment = gtk_scrollable_get_hadjustment (scrollable); - x += gtk_adjustment_get_value (adjustment); - } - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - y += gtk_adjustment_get_value (adjustment); - - if (table->drop_highlight == NULL) { - table->drop_highlight = gnome_canvas_item_new ( - gnome_canvas_root (table->table_canvas), - gnome_canvas_rect_get_type (), - "fill_color", NULL, - "outline_color_gdk", &style->fg[GTK_STATE_NORMAL], - NULL); - } - gnome_canvas_item_set ( - table->drop_highlight, - "x1", (gdouble) x, - "x2", (gdouble) x + width - 1, - "y1", (gdouble) y, - "y2", (gdouble) y + height - 1, - NULL); - } else { - if (table->drop_highlight) { - g_object_run_dispose (G_OBJECT (table->drop_highlight)); - table->drop_highlight = NULL; - } - } -} - -/** - * e_table_drag_unhighlight: - * @table: The #ETable to unhighlight - * - * Removes the highlight from an #ETable. - **/ -void -e_table_drag_unhighlight (ETable *table) -{ - g_return_if_fail (E_IS_TABLE (table)); - - if (table->drop_highlight) { - g_object_run_dispose (G_OBJECT (table->drop_highlight)); - table->drop_highlight = NULL; - } -} - -void -e_table_drag_dest_set (ETable *table, - GtkDestDefaults flags, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - g_return_if_fail (E_IS_TABLE (table)); - - gtk_drag_dest_set ( - GTK_WIDGET (table), flags, targets, n_targets, actions); -} - -void -e_table_drag_dest_set_proxy (ETable *table, - GdkWindow *proxy_window, - GdkDragProtocol protocol, - gboolean use_coordinates) -{ - g_return_if_fail (E_IS_TABLE (table)); - - gtk_drag_dest_set_proxy ( - GTK_WIDGET (table), proxy_window, protocol, use_coordinates); -} - -/* - * There probably should be functions for setting the targets - * as a GtkTargetList - */ - -void -e_table_drag_dest_unset (GtkWidget *widget) -{ - g_return_if_fail (E_IS_TABLE (widget)); - - gtk_drag_dest_unset (widget); -} - -/* Source side */ - -static gint -et_real_start_drag (ETable *table, - gint row, - gint col, - GdkEvent *event) -{ - GtkDragSourceInfo *info; - GdkDragContext *context; - ETableDragSourceSite *site; - - if (table->do_drag) { - site = table->site; - - site->state = 0; - context = e_table_drag_begin ( - table, row, col, - site->target_list, - site->actions, - 1, event); - - if (context) { - info = g_dataset_get_data (context, "gtk-info"); - - if (info && !info->icon_window) { - if (site->pixbuf) - gtk_drag_set_icon_pixbuf ( - context, - site->pixbuf, - -2, -2); - else - gtk_drag_set_icon_default (context); - } - } - return TRUE; - } - return FALSE; -} - -/** - * e_table_drag_source_set: - * @table: The #ETable to set up as a drag site - * @start_button_mask: Mask of allowed buttons to start drag - * @targets: Table of targets for this source - * @n_targets: Number of targets in @targets - * @actions: Actions allowed for this source - * - * Registers this table as a drag site, and possibly adds default behaviors. - **/ -void -e_table_drag_source_set (ETable *table, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - ETableDragSourceSite *site; - GtkWidget *canvas; - - g_return_if_fail (E_IS_TABLE (table)); - - canvas = GTK_WIDGET (table->table_canvas); - site = table->site; - - gtk_widget_add_events ( - canvas, - gtk_widget_get_events (canvas) | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_MOTION_MASK | GDK_STRUCTURE_MASK); - - table->do_drag = TRUE; - - if (site) { - if (site->target_list) - gtk_target_list_unref (site->target_list); - } else { - site = g_new0 (ETableDragSourceSite, 1); - table->site = site; - } - - site->start_button_mask = start_button_mask; - - if (targets) - site->target_list = gtk_target_list_new (targets, n_targets); - else - site->target_list = NULL; - - site->actions = actions; -} - -/** - * e_table_drag_source_unset: - * @table: The #ETable to un set up as a drag site - * - * Unregisters this #ETable as a drag site. - **/ -void -e_table_drag_source_unset (ETable *table) -{ - ETableDragSourceSite *site; - - g_return_if_fail (E_IS_TABLE (table)); - - site = table->site; - - if (site) { - if (site->target_list) - gtk_target_list_unref (site->target_list); - g_free (site); - table->site = NULL; - } - table->do_drag = FALSE; -} - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ - -/** - * e_table_drag_begin: - * @table: The #ETable to drag from - * @row: The row number of the cell - * @col: The col number of the cell - * @targets: The list of targets supported by the drag - * @actions: The available actions supported by the drag - * @button: The button held down for the drag - * @event: The event that initiated the drag - * - * Start a drag from this cell. - * - * Return value: - * The drag context. - **/ -GdkDragContext * -e_table_drag_begin (ETable *table, - gint row, - gint col, - GtkTargetList *targets, - GdkDragAction actions, - gint button, - GdkEvent *event) -{ - g_return_val_if_fail (E_IS_TABLE (table), NULL); - - table->drag_row = row; - table->drag_col = col; - - return gtk_drag_begin ( - GTK_WIDGET (table), targets, actions, button, event); -} - -static void -et_drag_begin (GtkWidget *widget, - GdkDragContext *context, - ETable *et) -{ - g_signal_emit ( - et, et_signals[TABLE_DRAG_BEGIN], 0, - et->drag_row, et->drag_col, context); -} - -static void -et_drag_end (GtkWidget *widget, - GdkDragContext *context, - ETable *et) -{ - g_signal_emit ( - et, et_signals[TABLE_DRAG_END], 0, - et->drag_row, et->drag_col, context); -} - -static void -et_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETable *et) -{ - g_signal_emit ( - et, et_signals[TABLE_DRAG_DATA_GET], 0, - et->drag_row, et->drag_col, context, selection_data, - info, time); -} - -static void -et_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - ETable *et) -{ - g_signal_emit ( - et, et_signals[TABLE_DRAG_DATA_DELETE], 0, - et->drag_row, et->drag_col, context); -} - -static gboolean -do_drag_motion (ETable *et, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - gboolean ret_val; - gint row = -1, col = -1; - - e_table_get_cell_at (et, x, y, &row, &col); - - if (row != et->drop_row && col != et->drop_row) { - g_signal_emit ( - et, et_signals[TABLE_DRAG_LEAVE], 0, - et->drop_row, et->drop_col, context, time); - } - - et->drop_row = row; - et->drop_col = col; - - g_signal_emit ( - et, et_signals[TABLE_DRAG_MOTION], 0, - et->drop_row, et->drop_col, context, x, y, time, &ret_val); - - return ret_val; -} - -static gboolean -scroll_timeout (gpointer data) -{ - ETable *et = data; - gint dx = 0, dy = 0; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gdouble old_h_value; - gdouble new_h_value; - gdouble old_v_value; - gdouble new_v_value; - gdouble page_size; - gdouble lower; - gdouble upper; - - if (et->scroll_direction & ET_SCROLL_DOWN) - dy += 20; - if (et->scroll_direction & ET_SCROLL_UP) - dy -= 20; - - if (et->scroll_direction & ET_SCROLL_RIGHT) - dx += 20; - if (et->scroll_direction & ET_SCROLL_LEFT) - dx -= 20; - - scrollable = GTK_SCROLLABLE (et->table_canvas); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - page_size = gtk_adjustment_get_page_size (adjustment); - - old_h_value = gtk_adjustment_get_value (adjustment); - new_h_value = CLAMP (old_h_value + dx, lower, upper - page_size); - - gtk_adjustment_set_value (adjustment, new_h_value); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - page_size = gtk_adjustment_get_page_size (adjustment); - - old_v_value = gtk_adjustment_get_value (adjustment); - new_v_value = CLAMP (old_v_value + dy, lower, upper - page_size); - - gtk_adjustment_set_value (adjustment, new_v_value); - - if (new_h_value != old_h_value || new_v_value != old_v_value) - do_drag_motion ( - et, - et->last_drop_context, - et->last_drop_x, - et->last_drop_y, - et->last_drop_time); - - return TRUE; -} - -static void -scroll_on (ETable *et, - guint scroll_direction) -{ - if (et->scroll_idle_id == 0 || scroll_direction != et->scroll_direction) { - if (et->scroll_idle_id != 0) - g_source_remove (et->scroll_idle_id); - et->scroll_direction = scroll_direction; - et->scroll_idle_id = g_timeout_add (100, scroll_timeout, et); - } -} - -static void -scroll_off (ETable *et) -{ - if (et->scroll_idle_id) { - g_source_remove (et->scroll_idle_id); - et->scroll_idle_id = 0; - } -} - -static void -context_destroyed (gpointer data) -{ - ETable *et = data; - /* if (!G_OBJECT_DESTROYED (et)) */ -/* FIXME: */ - { - et->last_drop_x = 0; - et->last_drop_y = 0; - et->last_drop_time = 0; - et->last_drop_context = NULL; - scroll_off (et); - } - g_object_unref (et); -} - -static void -context_connect (ETable *et, - GdkDragContext *context) -{ - if (g_dataset_get_data (context, "e-table") == NULL) { - g_object_ref (et); - g_dataset_set_data_full (context, "e-table", et, context_destroyed); - } -} - -static void -et_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - ETable *et) -{ - g_signal_emit ( - et, et_signals[TABLE_DRAG_LEAVE], 0, - et->drop_row, et->drop_col, context, time); - - et->drop_row = -1; - et->drop_col = -1; - - scroll_off (et); -} - -static gboolean -et_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETable *et) -{ - GtkAllocation allocation; - gboolean ret_val; - guint direction = 0; - - gtk_widget_get_allocation (widget, &allocation); - - et->last_drop_x = x; - et->last_drop_y = y; - et->last_drop_time = time; - et->last_drop_context = context; - context_connect (et, context); - - ret_val = do_drag_motion (et, context, x, y, time); - - if (y < 20) - direction |= ET_SCROLL_UP; - if (y > allocation.height - 20) - direction |= ET_SCROLL_DOWN; - if (x < 20) - direction |= ET_SCROLL_LEFT; - if (x > allocation.width - 20) - direction |= ET_SCROLL_RIGHT; - - if (direction != 0) - scroll_on (et, direction); - else - scroll_off (et); - - return ret_val; -} - -static gboolean -et_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETable *et) -{ - gboolean ret_val; - gint row, col; - - e_table_get_cell_at (et, x, y, &row, &col); - - if (row != et->drop_row && col != et->drop_row) { - g_signal_emit ( - et, et_signals[TABLE_DRAG_LEAVE], 0, - et->drop_row, et->drop_col, context, time); - g_signal_emit ( - et, et_signals[TABLE_DRAG_MOTION], 0, - row, col, context, x, y, time, &ret_val); - } - et->drop_row = row; - et->drop_col = col; - g_signal_emit ( - et, et_signals[TABLE_DRAG_DROP], 0, - et->drop_row, et->drop_col, context, x, y, time, &ret_val); - et->drop_row = -1; - et->drop_col = -1; - - scroll_off (et); - - return ret_val; -} - -static void -et_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - ETable *et) -{ - gint row, col; - - e_table_get_cell_at (et, x, y, &row, &col); - - g_signal_emit ( - et, et_signals[TABLE_DRAG_DATA_RECEIVED], 0, - row, col, context, x, y, selection_data, info, time); -} - -static void -e_table_class_init (ETableClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - object_class->dispose = et_dispose; - object_class->finalize = et_finalize; - object_class->set_property = et_set_property; - object_class->get_property = et_get_property; - - widget_class->grab_focus = et_grab_focus; - widget_class->unrealize = et_unrealize; - widget_class->get_preferred_width = et_get_preferred_width; - widget_class->get_preferred_height = et_get_preferred_height; - - widget_class->focus = et_focus; - - class->cursor_change = NULL; - class->cursor_activated = NULL; - class->selection_change = NULL; - class->double_click = NULL; - class->right_click = NULL; - class->click = NULL; - class->key_press = NULL; - class->start_drag = et_real_start_drag; - class->state_change = NULL; - class->white_space_event = NULL; - - class->table_drag_begin = NULL; - class->table_drag_end = NULL; - class->table_drag_data_get = NULL; - class->table_drag_data_delete = NULL; - - class->table_drag_leave = NULL; - class->table_drag_motion = NULL; - class->table_drag_drop = NULL; - class->table_drag_data_received = NULL; - - et_signals[CURSOR_CHANGE] = g_signal_new ( - "cursor_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, cursor_change), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - et_signals[CURSOR_ACTIVATED] = g_signal_new ( - "cursor_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, cursor_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - et_signals[SELECTION_CHANGE] = g_signal_new ( - "selection_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, selection_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - et_signals[DOUBLE_CLICK] = g_signal_new ( - "double_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, double_click), - NULL, NULL, - e_marshal_NONE__INT_INT_BOXED, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[RIGHT_CLICK] = g_signal_new ( - "right_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, right_click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[CLICK] = g_signal_new ( - "click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[KEY_PRESS] = g_signal_new ( - "key_press", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, key_press), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[START_DRAG] = g_signal_new ( - "start_drag", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, start_drag), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_INT_BOXED, - G_TYPE_BOOLEAN, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[STATE_CHANGE] = g_signal_new ( - "state_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, state_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - et_signals[WHITE_SPACE_EVENT] = g_signal_new ( - "white_space_event", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, white_space_event), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[TABLE_DRAG_BEGIN] = g_signal_new ( - "table_drag_begin", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_begin), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TABLE_DRAG_END] = g_signal_new ( - "table_drag_end", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_end), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TABLE_DRAG_DATA_GET] = g_signal_new ( - "table_drag_data_get", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_data_get), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT_BOXED_UINT_UINT, - G_TYPE_NONE, 6, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_UINT, - G_TYPE_UINT); - - et_signals[TABLE_DRAG_DATA_DELETE] = g_signal_new ( - "table_drag_data_delete", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_data_delete), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT, - G_TYPE_NONE, 3, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TABLE_DRAG_LEAVE] = g_signal_new ( - "table_drag_leave", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_leave), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT_UINT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_UINT); - - et_signals[TABLE_DRAG_MOTION] = g_signal_new ( - "table_drag_motion", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_motion), - NULL, NULL, - e_marshal_BOOLEAN__INT_INT_OBJECT_INT_INT_UINT, - G_TYPE_BOOLEAN, 6, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_UINT); - - et_signals[TABLE_DRAG_DROP] = g_signal_new ( - "table_drag_drop", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_drop), - NULL, NULL, - e_marshal_BOOLEAN__INT_INT_OBJECT_INT_INT_UINT, - G_TYPE_BOOLEAN, 6, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_UINT); - - et_signals[TABLE_DRAG_DATA_RECEIVED] = g_signal_new ( - "table_drag_data_received", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETableClass, table_drag_data_received), - NULL, NULL, - e_marshal_NONE__INT_INT_OBJECT_INT_INT_BOXED_UINT_UINT, - G_TYPE_NONE, 8, - G_TYPE_INT, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_UINT, - G_TYPE_UINT); - - g_object_class_install_property ( - object_class, - PROP_LENGTH_THRESHOLD, - g_param_spec_int ( - "length_threshold", - "Length Threshold", - NULL, - 0, G_MAXINT, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_UNIFORM_ROW_HEIGHT, - g_param_spec_boolean ( - "uniform_row_height", - "Uniform row height", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ALWAYS_SEARCH, - g_param_spec_boolean ( - "always_search", - "Always search", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_USE_CLICK_TO_ADD, - g_param_spec_boolean ( - "use_click_to_add", - "Use click to add", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Model", - NULL, - E_TYPE_TABLE_MODEL, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property ( - widget_class, - g_param_spec_int ( - "vertical-spacing", - "Vertical Row Spacing", - "Vertical space between rows. " - "It is added to top and to bottom of a row", - 0, G_MAXINT, 3, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /* Scrollable interface */ - g_object_class_override_property ( - object_class, PROP_HADJUSTMENT, "hadjustment"); - g_object_class_override_property ( - object_class, PROP_VADJUSTMENT, "vadjustment"); - g_object_class_override_property ( - object_class, PROP_HSCROLL_POLICY, "hscroll-policy"); - g_object_class_override_property ( - object_class, PROP_VSCROLL_POLICY, "vscroll-policy"); - - gal_a11y_e_table_init (); -} - -void -e_table_freeze_state_change (ETable *table) -{ - g_return_if_fail (table != NULL); - - table->state_change_freeze++; - if (table->state_change_freeze == 1) - table->state_changed = FALSE; - - g_return_if_fail (table->state_change_freeze != 0); -} - -void -e_table_thaw_state_change (ETable *table) -{ - g_return_if_fail (table != NULL); - g_return_if_fail (table->state_change_freeze != 0); - - table->state_change_freeze--; - if (table->state_change_freeze == 0 && table->state_changed) { - table->state_changed = FALSE; - e_table_state_change (table); - } -} diff --git a/widgets/table/e-table.dia b/widgets/table/e-table.dia Binary files differdeleted file mode 100644 index 5aeb01228c..0000000000 --- a/widgets/table/e-table.dia +++ /dev/null diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h deleted file mode 100644 index 6c2908811c..0000000000 --- a/widgets/table/e-table.h +++ /dev/null @@ -1,398 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TABLE_H_ -#define _E_TABLE_H_ - -#include <libgnomecanvas/libgnomecanvas.h> -#include <gtk/gtk.h> -#include <libxml/tree.h> -#include <table/e-table-model.h> -#include <table/e-table-header.h> -#include <table/e-table-group.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-item.h> -#include <table/e-table-selection-model.h> -#include <table/e-table-extras.h> -#include <table/e-table-specification.h> -#include <misc/e-printable.h> -#include <table/e-table-state.h> -#include <table/e-table-sorter.h> -#include <table/e-table-search.h> - -/* Standard GObject macros */ -#define E_TYPE_TABLE \ - (e_table_get_type ()) -#define E_TABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TABLE, ETable)) -#define E_TABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TABLE, ETableClass)) -#define E_IS_TABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TABLE)) -#define E_IS_TABLE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TABLE)) -#define E_TABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TABLE, ETableClass)) - -G_BEGIN_DECLS - -typedef struct _ETable ETable; -typedef struct _ETableClass ETableClass; - -typedef struct _ETableDragSourceSite ETableDragSourceSite; - -typedef enum { - E_TABLE_CURSOR_LOC_NONE = 0, - E_TABLE_CURSOR_LOC_ETCTA = 1 << 0, - E_TABLE_CURSOR_LOC_TABLE = 1 << 1 -} ETableCursorLoc; - -struct _ETable { - GtkTable parent; - - ETableModel *model; - - ETableHeader *full_header, *header; - - GnomeCanvasItem *canvas_vbox; - ETableGroup *group; - - ETableSortInfo *sort_info; - ETableSorter *sorter; - - ETableSelectionModel *selection; - ETableCursorLoc cursor_loc; - ETableSpecification *spec; - - ETableSearch *search; - - ETableCol *current_search_col; - - guint search_search_id; - guint search_accept_id; - - gint table_model_change_id; - gint table_row_change_id; - gint table_cell_change_id; - gint table_rows_inserted_id; - gint table_rows_deleted_id; - - gint group_info_change_id; - gint sort_info_change_id; - - gint structure_change_id; - gint expansion_change_id; - gint dimension_change_id; - - gint reflow_idle_id; - gint scroll_idle_id; - - GnomeCanvas *header_canvas, *table_canvas; - - GnomeCanvasItem *header_item, *root; - - GnomeCanvasItem *white_item; - - gint length_threshold; - - gint rebuild_idle_id; - guint need_rebuild : 1; - guint size_allocated : 1; - - /* - * Configuration settings - */ - guint alternating_row_colors : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint row_selection_active : 1; - - guint horizontal_scrolling : 1; - guint horizontal_resize : 1; - - guint is_grouped : 1; - - guint scroll_direction : 4; - - guint do_drag : 1; - - guint uniform_row_height : 1; - guint allow_grouping : 1; - - guint always_search : 1; - guint search_col_set : 1; - - gchar *click_to_add_message; - GnomeCanvasItem *click_to_add; - gboolean use_click_to_add; - gboolean use_click_to_add_end; - - ECursorMode cursor_mode; - - gint drop_row; - gint drop_col; - GnomeCanvasItem *drop_highlight; - gint last_drop_x; - gint last_drop_y; - gint last_drop_time; - GdkDragContext *last_drop_context; - - gint drag_row; - gint drag_col; - ETableDragSourceSite *site; - - gint header_width; - - gchar *domain; - - gboolean state_changed; - guint state_change_freeze; -}; - -struct _ETableClass { - GtkTableClass parent_class; - - void (*cursor_change) (ETable *et, - gint row); - void (*cursor_activated) (ETable *et, - gint row); - void (*selection_change) (ETable *et); - void (*double_click) (ETable *et, - gint row, - gint col, - GdkEvent *event); - gboolean (*right_click) (ETable *et, - gint row, - gint col, - GdkEvent *event); - gboolean (*click) (ETable *et, - gint row, - gint col, - GdkEvent *event); - gboolean (*key_press) (ETable *et, - gint row, - gint col, - GdkEvent *event); - gboolean (*start_drag) (ETable *et, - gint row, - gint col, - GdkEvent *event); - void (*state_change) (ETable *et); - gboolean (*white_space_event) (ETable *et, - GdkEvent *event); - - /* Source side drag signals */ - void (*table_drag_begin) (ETable *table, - gint row, - gint col, - GdkDragContext *context); - void (*table_drag_end) (ETable *table, - gint row, - gint col, - GdkDragContext *context); - void (*table_drag_data_get) (ETable *table, - gint row, - gint col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); - void (*table_drag_data_delete) - (ETable *table, - gint row, - gint col, - GdkDragContext *context); - - /* Target side drag signals */ - void (*table_drag_leave) (ETable *table, - gint row, - gint col, - GdkDragContext *context, - guint time); - gboolean (*table_drag_motion) (ETable *table, - gint row, - gint col, - GdkDragContext *context, - gint x, - gint y, - guint time); - gboolean (*table_drag_drop) (ETable *table, - gint row, - gint col, - GdkDragContext *context, - gint x, - gint y, - guint time); - void (*table_drag_data_received) - (ETable *table, - gint row, - gint col, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); -}; - -GType e_table_get_type (void) G_GNUC_CONST; -ETable * e_table_construct (ETable *e_table, - ETableModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state); -GtkWidget * e_table_new (ETableModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state); - -/* Create an ETable using files. */ -ETable * e_table_construct_from_spec_file - (ETable *e_table, - ETableModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn); -GtkWidget * e_table_new_from_spec_file (ETableModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn); - -/* To save the state */ -gchar * e_table_get_state (ETable *e_table); -void e_table_save_state (ETable *e_table, - const gchar *filename); -ETableState *e_table_get_state_object (ETable *e_table); - -/* note that it is more efficient to provide the state at creation time */ -void e_table_set_state (ETable *e_table, - const gchar *state); -void e_table_set_state_object (ETable *e_table, - ETableState *state); -void e_table_load_state (ETable *e_table, - const gchar *filename); -void e_table_set_cursor_row (ETable *e_table, - gint row); - -/* -1 means we don't have the cursor. This is in model rows. */ -gint e_table_get_cursor_row (ETable *e_table); -void e_table_selected_row_foreach (ETable *e_table, - EForeachFunc callback, - gpointer closure); -gint e_table_selected_count (ETable *e_table); -EPrintable * e_table_get_printable (ETable *e_table); -gint e_table_get_next_row (ETable *e_table, - gint model_row); -gint e_table_get_prev_row (ETable *e_table, - gint model_row); -gint e_table_model_to_view_row (ETable *e_table, - gint model_row); -gint e_table_view_to_model_row (ETable *e_table, - gint view_row); -void e_table_get_cell_at (ETable *table, - gint x, - gint y, - gint *row_return, - gint *col_return); -void e_table_get_mouse_over_cell (ETable *table, - gint *row, - gint *col); -void e_table_get_cell_geometry (ETable *table, - gint row, - gint col, - gint *x_return, - gint *y_return, - gint *width_return, - gint *height_return); - -/* Useful accessor functions. */ -ESelectionModel *e_table_get_selection_model (ETable *table); - -/* Drag & drop stuff. */ -/* Target */ -void e_table_drag_get_data (ETable *table, - gint row, - gint col, - GdkDragContext *context, - GdkAtom target, - guint32 time); -void e_table_drag_highlight (ETable *table, - gint row, - gint col); /* col == -1 to highlight entire row. */ -void e_table_drag_unhighlight (ETable *table); -void e_table_drag_dest_set (ETable *table, - GtkDestDefaults flags, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); -void e_table_drag_dest_set_proxy (ETable *table, - GdkWindow *proxy_window, - GdkDragProtocol protocol, - gboolean use_coordinates); - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ -void e_table_drag_dest_unset (GtkWidget *widget); - -/* Source side */ -void e_table_drag_source_set (ETable *table, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); -void e_table_drag_source_unset (ETable *table); - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ -GdkDragContext *e_table_drag_begin (ETable *table, - gint row, - gint col, - GtkTargetList *targets, - GdkDragAction actions, - gint button, - GdkEvent *event); - -/* selection stuff */ -void e_table_select_all (ETable *table); -void e_table_invert_selection (ETable *table); - -/* This function is only needed in single_selection_mode. */ -void e_table_right_click_up (ETable *table); - -void e_table_commit_click_to_add (ETable *table); - -void e_table_freeze_state_change (ETable *table); -void e_table_thaw_state_change (ETable *table); - -G_END_DECLS - -#endif /* _E_TABLE_H_ */ - diff --git a/widgets/table/e-tree-memory-callbacks.c b/widgets/table/e-tree-memory-callbacks.c deleted file mode 100644 index 9f8d7d468a..0000000000 --- a/widgets/table/e-tree-memory-callbacks.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-tree-memory-callbacks.h" - -G_DEFINE_TYPE (ETreeMemoryCallbacks, e_tree_memory_callbacks, E_TYPE_TREE_MEMORY) - -static GdkPixbuf * -etmc_icon_at (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - return etmc->icon_at (etm, node, etmc->model_data); -} - -static gint -etmc_column_count (ETreeModel *etm) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->column_count) - return etmc->column_count (etm, etmc->model_data); - else - return 0; -} - -static gboolean -etmc_has_save_id (ETreeModel *etm) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->has_save_id) - return etmc->has_save_id (etm, etmc->model_data); - else - return FALSE; -} - -static gchar * -etmc_get_save_id (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->get_save_id) - return etmc->get_save_id (etm, node, etmc->model_data); - else - return NULL; -} - -static gboolean -etmc_has_get_node_by_id (ETreeModel *etm) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->has_get_node_by_id) - return etmc->has_get_node_by_id (etm, etmc->model_data); - else - return FALSE; -} - -static ETreePath -etmc_get_node_by_id (ETreeModel *etm, - const gchar *save_id) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->get_node_by_id) - return etmc->get_node_by_id (etm, save_id, etmc->model_data); - else - return NULL; -} - -static gpointer -etmc_sort_value_at (ETreeModel *etm, - ETreePath node, - gint col) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->sort_value_at) - return etmc->sort_value_at (etm, node, col, etmc->model_data); - else - return etmc->value_at (etm, node, col, etmc->model_data); -} - -static gpointer -etmc_value_at (ETreeModel *etm, - ETreePath node, - gint col) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - return etmc->value_at (etm, node, col, etmc->model_data); -} - -static void -etmc_set_value_at (ETreeModel *etm, - ETreePath node, - gint col, - gconstpointer val) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - etmc->set_value_at (etm, node, col, val, etmc->model_data); -} - -static gboolean -etmc_is_editable (ETreeModel *etm, - ETreePath node, - gint col) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - return etmc->is_editable (etm, node, col, etmc->model_data); -} - -/* The default for etmc_duplicate_value is to return the raw value. */ -static gpointer -etmc_duplicate_value (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->duplicate_value) - return etmc->duplicate_value (etm, col, value, etmc->model_data); - else - return (gpointer) value; -} - -static void -etmc_free_value (ETreeModel *etm, - gint col, - gpointer value) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->free_value) - etmc->free_value (etm, col, value, etmc->model_data); -} - -static gpointer -etmc_initialize_value (ETreeModel *etm, - gint col) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->initialize_value) - return etmc->initialize_value (etm, col, etmc->model_data); - else - return NULL; -} - -static gboolean -etmc_value_is_empty (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->value_is_empty) - return etmc->value_is_empty (etm, col, value, etmc->model_data); - else - return FALSE; -} - -static gchar * -etmc_value_to_string (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeMemoryCallbacks *etmc = E_TREE_MEMORY_CALLBACKS (etm); - - if (etmc->value_to_string) - return etmc->value_to_string (etm, col, value, etmc->model_data); - else - return g_strdup (""); -} - -static void -e_tree_memory_callbacks_class_init (ETreeMemoryCallbacksClass *class) -{ - ETreeModelClass *model_class = E_TREE_MODEL_CLASS (class); - - model_class->icon_at = etmc_icon_at; - - model_class->column_count = etmc_column_count; - - model_class->has_save_id = etmc_has_save_id; - model_class->get_save_id = etmc_get_save_id; - - model_class->has_get_node_by_id = etmc_has_get_node_by_id; - model_class->get_node_by_id = etmc_get_node_by_id; - - model_class->sort_value_at = etmc_sort_value_at; - model_class->value_at = etmc_value_at; - model_class->set_value_at = etmc_set_value_at; - model_class->is_editable = etmc_is_editable; - - model_class->duplicate_value = etmc_duplicate_value; - model_class->free_value = etmc_free_value; - model_class->initialize_value = etmc_initialize_value; - model_class->value_is_empty = etmc_value_is_empty; - model_class->value_to_string = etmc_value_to_string; -} - -static void -e_tree_memory_callbacks_init (ETreeMemoryCallbacks *etmc) -{ - /* nothing to do */ -} - -/** - * e_tree_memory_callbacks_new: - * - * This initializes a new ETreeMemoryCallbacksModel object. - * ETreeMemoryCallbacksModel is an implementaiton of the somewhat - * abstract class ETreeMemory. The ETreeMemoryCallbacksModel is - * designed to allow people to easily create ETreeMemorys without - * having to create a new GType derived from ETreeMemory every time - * they need one. - * - * Instead, ETreeMemoryCallbacksModel uses a setup based in callback functions, every - * callback function signature mimics the signature of each ETreeModel method - * and passes the extra @data pointer to each one of the method to provide them - * with any context they might want to use. - * - * ETreeMemoryCallbacks is to ETreeMemory as ETableSimple is to ETableModel. - * - * Return value: An ETreeMemoryCallbacks object (which is also an - * ETreeMemory and thus an ETreeModel object). - * - */ -ETreeModel * -e_tree_memory_callbacks_new (ETreeMemoryCallbacksIconAtFn icon_at, - - ETreeMemoryCallbacksColumnCountFn column_count, - - ETreeMemoryCallbacksHasSaveIdFn has_save_id, - ETreeMemoryCallbacksGetSaveIdFn get_save_id, - - ETreeMemoryCallbacksHasGetNodeByIdFn has_get_node_by_id, - ETreeMemoryCallbacksGetNodeByIdFn get_node_by_id, - - ETreeMemoryCallbacksValueAtFn sort_value_at, - ETreeMemoryCallbacksValueAtFn value_at, - ETreeMemoryCallbacksSetValueAtFn set_value_at, - ETreeMemoryCallbacksIsEditableFn is_editable, - - ETreeMemoryCallbacksDuplicateValueFn duplicate_value, - ETreeMemoryCallbacksFreeValueFn free_value, - ETreeMemoryCallbacksInitializeValueFn initialize_value, - ETreeMemoryCallbacksValueIsEmptyFn value_is_empty, - ETreeMemoryCallbacksValueToStringFn value_to_string, - - gpointer model_data) -{ - ETreeMemoryCallbacks *etmc; - - etmc = g_object_new (E_TYPE_TREE_MEMORY_CALLBACKS, NULL); - - etmc->icon_at = icon_at; - - etmc->column_count = column_count; - - etmc->has_save_id = has_save_id; - etmc->get_save_id = get_save_id; - - etmc->has_get_node_by_id = has_get_node_by_id; - etmc->get_node_by_id = get_node_by_id; - - etmc->sort_value_at = sort_value_at; - etmc->value_at = value_at; - etmc->set_value_at = set_value_at; - etmc->is_editable = is_editable; - - etmc->duplicate_value = duplicate_value; - etmc->free_value = free_value; - etmc->initialize_value = initialize_value; - etmc->value_is_empty = value_is_empty; - etmc->value_to_string = value_to_string; - - etmc->model_data = model_data; - - return (ETreeModel *) etmc; -} - diff --git a/widgets/table/e-tree-memory-callbacks.h b/widgets/table/e-tree-memory-callbacks.h deleted file mode 100644 index f2e202bec3..0000000000 --- a/widgets/table/e-tree-memory-callbacks.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_MEMORY_CALLBACKS_H_ -#define _E_TREE_MEMORY_CALLBACKS_H_ - -#include <table/e-tree-memory.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_MEMORY_CALLBACKS \ - (e_tree_memory_callbacks_get_type ()) -#define E_TREE_MEMORY_CALLBACKS(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_MEMORY_CALLBACKS, ETreeMemoryCallbacks)) -#define E_TREE_MEMORY_CALLBACKS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_MEMORY_CALLBACKS, ETreeMemoryCallbacksClass)) -#define E_IS_TREE_MEMORY_CALLBACKS(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_MEMORY_CALLBACKS)) -#define E_IS_TREE_MEMORY_CALLBACKS_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_MEMORY_CALLBACKS)) -#define E_TREE_MEMORY_CALLBACKS_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_MEMORY_CALLBACKS, ETreeMemoryCallbacksClass)) - -G_BEGIN_DECLS - -typedef struct _ETreeMemoryCallbacks ETreeMemoryCallbacks; -typedef struct _ETreeMemoryCallbacksClass ETreeMemoryCallbacksClass; - -typedef GdkPixbuf * (*ETreeMemoryCallbacksIconAtFn) - (ETreeModel *etree, - ETreePath path, - gpointer model_data); - -typedef gint (*ETreeMemoryCallbacksColumnCountFn) - (ETreeModel *etree, - gpointer model_data); - -typedef gboolean (*ETreeMemoryCallbacksHasSaveIdFn) - (ETreeModel *etree, - gpointer model_data); -typedef gchar * (*ETreeMemoryCallbacksGetSaveIdFn) - (ETreeModel *etree, - ETreePath path, - gpointer model_data); - -typedef gboolean (*ETreeMemoryCallbacksHasGetNodeByIdFn) - (ETreeModel *etree, - gpointer model_data); -typedef ETreePath (*ETreeMemoryCallbacksGetNodeByIdFn) - (ETreeModel *etree, - const gchar *save_id, - gpointer model_data); - -typedef gpointer (*ETreeMemoryCallbacksValueAtFn) - (ETreeModel *etree, - ETreePath path, - gint col, - gpointer model_data); -typedef void (*ETreeMemoryCallbacksSetValueAtFn) - (ETreeModel *etree, - ETreePath path, - gint col, - gconstpointer val, - gpointer model_data); -typedef gboolean (*ETreeMemoryCallbacksIsEditableFn) - (ETreeModel *etree, - ETreePath path, - gint col, - gpointer model_data); - -typedef gpointer (*ETreeMemoryCallbacksDuplicateValueFn) - (ETreeModel *etm, - gint col, - gconstpointer val, - gpointer data); -typedef void (*ETreeMemoryCallbacksFreeValueFn) - (ETreeModel *etm, - gint col, - gpointer val, - gpointer data); -typedef gpointer (*ETreeMemoryCallbacksInitializeValueFn) - (ETreeModel *etm, - gint col, - gpointer data); -typedef gboolean (*ETreeMemoryCallbacksValueIsEmptyFn) - (ETreeModel *etm, - gint col, - gconstpointer val, - gpointer data); -typedef gchar * (*ETreeMemoryCallbacksValueToStringFn) - (ETreeModel *etm, - gint col, - gconstpointer val, - gpointer data); - -struct _ETreeMemoryCallbacks { - ETreeMemory parent; - - ETreeMemoryCallbacksIconAtFn icon_at; - - ETreeMemoryCallbacksColumnCountFn column_count; - - ETreeMemoryCallbacksHasSaveIdFn has_save_id; - ETreeMemoryCallbacksGetSaveIdFn get_save_id; - - ETreeMemoryCallbacksHasGetNodeByIdFn has_get_node_by_id; - ETreeMemoryCallbacksGetNodeByIdFn get_node_by_id; - - ETreeMemoryCallbacksValueAtFn sort_value_at; - ETreeMemoryCallbacksValueAtFn value_at; - ETreeMemoryCallbacksSetValueAtFn set_value_at; - ETreeMemoryCallbacksIsEditableFn is_editable; - - ETreeMemoryCallbacksDuplicateValueFn duplicate_value; - ETreeMemoryCallbacksFreeValueFn free_value; - ETreeMemoryCallbacksInitializeValueFn initialize_value; - ETreeMemoryCallbacksValueIsEmptyFn value_is_empty; - ETreeMemoryCallbacksValueToStringFn value_to_string; - - gpointer model_data; -}; - -struct _ETreeMemoryCallbacksClass { - ETreeMemoryClass parent_class; -}; - -GType e_tree_memory_callbacks_get_type - (void) G_GNUC_CONST; -ETreeModel * e_tree_memory_callbacks_new - (ETreeMemoryCallbacksIconAtFn icon_at, - - ETreeMemoryCallbacksColumnCountFn column_count, - - ETreeMemoryCallbacksHasSaveIdFn has_save_id, - ETreeMemoryCallbacksGetSaveIdFn get_save_id, - - ETreeMemoryCallbacksHasGetNodeByIdFn has_get_node_by_id, - ETreeMemoryCallbacksGetNodeByIdFn get_node_by_id, - - ETreeMemoryCallbacksValueAtFn sort_value_at, - ETreeMemoryCallbacksValueAtFn value_at, - ETreeMemoryCallbacksSetValueAtFn set_value_at, - ETreeMemoryCallbacksIsEditableFn is_editable, - - ETreeMemoryCallbacksDuplicateValueFn duplicate_value, - ETreeMemoryCallbacksFreeValueFn free_value, - ETreeMemoryCallbacksInitializeValueFn initialize_value, - ETreeMemoryCallbacksValueIsEmptyFn value_is_empty, - ETreeMemoryCallbacksValueToStringFn value_to_string, - - gpointer model_data); - -G_END_DECLS - -#endif /* _E_TREE_MEMORY_CALLBACKS_H_ */ diff --git a/widgets/table/e-tree-memory.c b/widgets/table/e-tree-memory.c deleted file mode 100644 index f779405d0e..0000000000 --- a/widgets/table/e-tree-memory.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> - -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-tree-memory.h" - -#define E_TREE_MEMORY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TREE_MEMORY, ETreeMemoryPrivate)) - -G_DEFINE_TYPE (ETreeMemory, e_tree_memory, E_TYPE_TREE_MODEL) - -enum { - FILL_IN_CHILDREN, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -typedef struct ETreeMemoryPath ETreeMemoryPath; - -struct ETreeMemoryPath { - gpointer node_data; - - guint children_computed : 1; - - /* parent/child/sibling pointers */ - ETreeMemoryPath *parent; - ETreeMemoryPath *next_sibling; - ETreeMemoryPath *prev_sibling; - ETreeMemoryPath *first_child; - ETreeMemoryPath *last_child; - - gint num_children; -}; - -struct _ETreeMemoryPrivate { - ETreeMemoryPath *root; - - /* whether nodes are created expanded - * or collapsed by default */ - gboolean expanded_default; - - gint frozen; - GFunc destroy_func; - gpointer destroy_user_data; -}; - -/* ETreeMemoryPath functions */ - -static inline void -check_children (ETreeMemory *memory, - ETreePath node) -{ - ETreeMemoryPath *path = node; - if (!path->children_computed) { - g_signal_emit (memory, signals[FILL_IN_CHILDREN], 0, node); - path->children_computed = TRUE; - } -} - -static gint -e_tree_memory_path_depth (ETreeMemoryPath *path) -{ - gint depth = 0; - - g_return_val_if_fail (path != NULL, -1); - - for (path = path->parent; path; path = path->parent) - depth++; - return depth; -} - -static void -e_tree_memory_path_insert (ETreeMemoryPath *parent, - gint position, - ETreeMemoryPath *child) -{ - g_return_if_fail (position <= parent->num_children && position >= -1); - - child->parent = parent; - - if (parent->first_child == NULL) - parent->first_child = child; - - if (position == -1 || position == parent->num_children) { - child->prev_sibling = parent->last_child; - if (parent->last_child) - parent->last_child->next_sibling = child; - parent->last_child = child; - } else { - ETreeMemoryPath *c; - for (c = parent->first_child; c; c = c->next_sibling) { - if (position == 0) { - child->next_sibling = c; - child->prev_sibling = c->prev_sibling; - - if (child->next_sibling) - child->next_sibling->prev_sibling = child; - if (child->prev_sibling) - child->prev_sibling->next_sibling = child; - - if (parent->first_child == c) - parent->first_child = child; - break; - } - position--; - } - } - - parent->num_children++; -} - -static void -e_tree_path_unlink (ETreeMemoryPath *path) -{ - ETreeMemoryPath *parent = path->parent; - - /* unlink first/last child if applicable */ - if (parent) { - if (path == parent->first_child) - parent->first_child = path->next_sibling; - if (path == parent->last_child) - parent->last_child = path->prev_sibling; - - parent->num_children--; - } - - /* unlink prev/next sibling links */ - if (path->next_sibling) - path->next_sibling->prev_sibling = path->prev_sibling; - if (path->prev_sibling) - path->prev_sibling->next_sibling = path->next_sibling; - - path->parent = NULL; - path->next_sibling = NULL; - path->prev_sibling = NULL; -} - -/** - * e_tree_memory_freeze: - * @etmm: the ETreeModel to freeze. - * - * This function prepares an ETreeModel for a period of much change. - * All signals regarding changes to the tree are deferred until we - * thaw the tree. - * - **/ -void -e_tree_memory_freeze (ETreeMemory *etmm) -{ - ETreeMemoryPrivate *priv = etmm->priv; - - if (priv->frozen == 0) - e_tree_model_pre_change (E_TREE_MODEL (etmm)); - - priv->frozen++; -} - -/** - * e_tree_memory_thaw: - * @etmm: the ETreeMemory to thaw. - * - * This function thaws an ETreeMemory. All the defered signals can add - * up to a lot, we don't know - so we just emit a model_changed - * signal. - * - **/ -void -e_tree_memory_thaw (ETreeMemory *etmm) -{ - ETreeMemoryPrivate *priv = etmm->priv; - - if (priv->frozen > 0) - priv->frozen--; - if (priv->frozen == 0) { - e_tree_model_node_changed (E_TREE_MODEL (etmm), priv->root); - } -} - -/* virtual methods */ - -static void -etmm_dispose (GObject *object) -{ - ETreeMemoryPrivate *priv; - - priv = E_TREE_MEMORY_GET_PRIVATE (object); - - if (priv->root) - e_tree_memory_node_remove ( - E_TREE_MEMORY (object), priv->root); - - G_OBJECT_CLASS (e_tree_memory_parent_class)->dispose (object); -} - -static ETreePath -etmm_get_root (ETreeModel *etm) -{ - ETreeMemoryPrivate *priv = E_TREE_MEMORY (etm)->priv; - return priv->root; -} - -static ETreePath -etmm_get_parent (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - return path->parent; -} - -static ETreePath -etmm_get_first_child (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - - check_children (E_TREE_MEMORY (etm), node); - return path->first_child; -} - -static ETreePath -etmm_get_last_child (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - - check_children (E_TREE_MEMORY (etm), node); - return path->last_child; -} - -static ETreePath -etmm_get_next (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - return path->next_sibling; -} - -static ETreePath -etmm_get_prev (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - return path->prev_sibling; -} - -static gboolean -etmm_is_root (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - return e_tree_memory_path_depth (path) == 0; -} - -static gboolean -etmm_is_expandable (ETreeModel *etm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - - check_children (E_TREE_MEMORY (etm), node); - return path->first_child != NULL; -} - -static guint -etmm_get_children (ETreeModel *etm, - ETreePath node, - ETreePath **nodes) -{ - ETreeMemoryPath *path = node; - guint n_children; - - check_children (E_TREE_MEMORY (etm), node); - - n_children = path->num_children; - - if (nodes) { - ETreeMemoryPath *p; - gint i = 0; - - (*nodes) = g_new (ETreePath, n_children); - for (p = path->first_child; p; p = p->next_sibling) { - (*nodes)[i++] = p; - } - } - - return n_children; -} - -static guint -etmm_depth (ETreeModel *etm, - ETreePath path) -{ - return e_tree_memory_path_depth (path); -} - -static gboolean -etmm_get_expanded_default (ETreeModel *etm) -{ - ETreeMemory *etmm = E_TREE_MEMORY (etm); - ETreeMemoryPrivate *priv = etmm->priv; - - return priv->expanded_default; -} - -static void -etmm_clear_children_computed (ETreeMemoryPath *path) -{ - for (path = path->first_child; path; path = path->next_sibling) { - path->children_computed = FALSE; - etmm_clear_children_computed (path); - } -} - -static void -etmm_node_request_collapse (ETreeModel *etm, - ETreePath node) -{ - ETreeModelClass *parent_class; - - if (node) - etmm_clear_children_computed (node); - - parent_class = E_TREE_MODEL_CLASS (e_tree_memory_parent_class); - - if (parent_class->node_request_collapse != NULL) - parent_class->node_request_collapse (etm, node); -} - -static void -e_tree_memory_class_init (ETreeMemoryClass *class) -{ - GObjectClass *object_class; - ETreeModelClass *tree_model_class; - - g_type_class_add_private (class, sizeof (ETreeMemoryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = etmm_dispose; - - tree_model_class = E_TREE_MODEL_CLASS (class); - tree_model_class->get_root = etmm_get_root; - tree_model_class->get_prev = etmm_get_prev; - tree_model_class->get_next = etmm_get_next; - tree_model_class->get_first_child = etmm_get_first_child; - tree_model_class->get_last_child = etmm_get_last_child; - tree_model_class->get_parent = etmm_get_parent; - - tree_model_class->is_root = etmm_is_root; - tree_model_class->is_expandable = etmm_is_expandable; - tree_model_class->get_children = etmm_get_children; - tree_model_class->depth = etmm_depth; - tree_model_class->get_expanded_default = etmm_get_expanded_default; - - tree_model_class->node_request_collapse = etmm_node_request_collapse; - - class->fill_in_children = NULL; - - signals[FILL_IN_CHILDREN] = g_signal_new ( - "fill_in_children", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeMemoryClass, fill_in_children), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); -} - -static void -e_tree_memory_init (ETreeMemory *etmm) -{ - etmm->priv = E_TREE_MEMORY_GET_PRIVATE (etmm); -} - -/** - * e_tree_memory_construct: - * @etree: - * - * - **/ -void -e_tree_memory_construct (ETreeMemory *etmm) -{ -} - -/** - * e_tree_memory_new - * - * XXX docs here. - * - * return values: a newly constructed ETreeMemory. - */ -ETreeMemory * -e_tree_memory_new (void) -{ - return g_object_new (E_TYPE_TREE_MEMORY, NULL); -} - -/** - * e_tree_memory_set_expanded_default - * - * Sets the state of nodes to be append to a thread. - * They will either be expanded or collapsed, according to - * the value of @expanded. - */ -void -e_tree_memory_set_expanded_default (ETreeMemory *etree, - gboolean expanded) -{ - g_return_if_fail (etree != NULL); - - etree->priv->expanded_default = expanded; -} - -/** - * e_tree_memory_node_get_data: - * @etmm: - * @node: - * - * - * - * Return value: - **/ -gpointer -e_tree_memory_node_get_data (ETreeMemory *etmm, - ETreePath node) -{ - ETreeMemoryPath *path = node; - - g_return_val_if_fail (path, NULL); - - return path->node_data; -} - -/** - * e_tree_memory_node_set_data: - * @etmm: - * @node: - * @node_data: - * - * - **/ -void -e_tree_memory_node_set_data (ETreeMemory *etmm, - ETreePath node, - gpointer node_data) -{ - ETreeMemoryPath *path = node; - - g_return_if_fail (path); - - path->node_data = node_data; -} - -/** - * e_tree_memory_node_insert: - * @tree_model: - * @parent_path: - * @position: - * @node_data: - * - * - * - * Return value: - **/ -ETreePath -e_tree_memory_node_insert (ETreeMemory *tree_model, - ETreePath parent_node, - gint position, - gpointer node_data) -{ - ETreeMemoryPrivate *priv; - ETreeMemoryPath *new_path; - ETreeMemoryPath *parent_path = parent_node; - - g_return_val_if_fail (tree_model != NULL, NULL); - - priv = tree_model->priv; - - g_return_val_if_fail (parent_path != NULL || priv->root == NULL, NULL); - - priv = tree_model->priv; - - if (!tree_model->priv->frozen) - e_tree_model_pre_change (E_TREE_MODEL (tree_model)); - - new_path = g_slice_new0 (ETreeMemoryPath); - - new_path->node_data = node_data; - new_path->children_computed = FALSE; - - if (parent_path != NULL) { - e_tree_memory_path_insert (parent_path, position, new_path); - if (!tree_model->priv->frozen) - e_tree_model_node_inserted ( - E_TREE_MODEL (tree_model), - parent_path, new_path); - } else { - priv->root = new_path; - if (!tree_model->priv->frozen) - e_tree_model_node_changed ( - E_TREE_MODEL (tree_model), new_path); - } - - return new_path; -} - -ETreePath -e_tree_memory_node_insert_id (ETreeMemory *etree, - ETreePath parent, - gint position, - gpointer node_data, - gchar *id) -{ - return e_tree_memory_node_insert (etree, parent, position, node_data); -} - -/** - * e_tree_memory_node_insert_before: - * @etree: - * @parent: - * @sibling: - * @node_data: - * - * - * - * Return value: - **/ -ETreePath -e_tree_memory_node_insert_before (ETreeMemory *etree, - ETreePath parent, - ETreePath sibling, - gpointer node_data) -{ - ETreeMemoryPath *child; - ETreeMemoryPath *parent_path = parent; - ETreeMemoryPath *sibling_path = sibling; - gint position = 0; - - g_return_val_if_fail (etree != NULL, NULL); - - if (sibling != NULL) { - for (child = parent_path->first_child; child; child = child->next_sibling) { - if (child == sibling_path) - break; - position++; - } - } else - position = parent_path->num_children; - return e_tree_memory_node_insert (etree, parent, position, node_data); -} - -/* just blows away child data, doesn't take into account unlinking/etc */ -static void -child_free (ETreeMemory *etree, - ETreeMemoryPath *node) -{ - ETreeMemoryPath *child, *next; - - child = node->first_child; - while (child) { - next = child->next_sibling; - child_free (etree, child); - child = next; - } - - if (etree->priv->destroy_func) { - etree->priv->destroy_func (node->node_data, etree->priv->destroy_user_data); - } - - g_slice_free (ETreeMemoryPath, node); -} - -/** - * e_tree_memory_node_remove: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gpointer -e_tree_memory_node_remove (ETreeMemory *etree, - ETreePath node) -{ - ETreeMemoryPath *path = node; - ETreeMemoryPath *parent = path->parent; - ETreeMemoryPath *sibling; - gpointer ret = path->node_data; - gint old_position = 0; - - g_return_val_if_fail (etree != NULL, NULL); - - if (!etree->priv->frozen) { - e_tree_model_pre_change (E_TREE_MODEL (etree)); - for (old_position = 0, sibling = path; - sibling; - old_position++, sibling = sibling->prev_sibling) - /* Empty intentionally*/; - old_position--; - } - - /* unlink this node - we only have to unlink the root node being removed, - * since the others are only references from this node */ - e_tree_path_unlink (path); - - /*printf("removing %d nodes from position %d\n", visible, base);*/ - if (!etree->priv->frozen) - e_tree_model_node_removed (E_TREE_MODEL (etree), parent, path, old_position); - - child_free (etree, path); - - if (path == etree->priv->root) - etree->priv->root = NULL; - - if (!etree->priv->frozen) - e_tree_model_node_deleted (E_TREE_MODEL (etree), path); - - return ret; -} - -typedef struct { - ETreeMemory *memory; - gpointer closure; - ETreeMemorySortCallback callback; -} MemoryAndClosure; - -static gint -sort_callback (gconstpointer data1, - gconstpointer data2, - gpointer user_data) -{ - ETreePath path1 = *(ETreePath *) data1; - ETreePath path2 = *(ETreePath *) data2; - MemoryAndClosure *mac = user_data; - return (*mac->callback) (mac->memory, path1, path2, mac->closure); -} - -void -e_tree_memory_sort_node (ETreeMemory *etmm, - ETreePath node, - ETreeMemorySortCallback callback, - gpointer user_data) -{ - ETreeMemoryPath **children; - ETreeMemoryPath *child; - gint count; - gint i; - ETreeMemoryPath *path = node; - MemoryAndClosure mac; - ETreeMemoryPath *last; - - e_tree_model_pre_change (E_TREE_MODEL (etmm)); - - i = 0; - for (child = path->first_child; child; child = child->next_sibling) - i++; - - children = g_new (ETreeMemoryPath *, i); - - count = i; - - for (child = path->first_child, i = 0; - child; - child = child->next_sibling, i++) { - children[i] = child; - } - - mac.memory = etmm; - mac.closure = user_data; - mac.callback = callback; - - g_qsort_with_data ( - children, count, sizeof (ETreeMemoryPath *), - sort_callback, &mac); - - path->first_child = NULL; - last = NULL; - for (i = 0; - i < count; - i++) { - children[i]->prev_sibling = last; - if (last) - last->next_sibling = children[i]; - else - path->first_child = children[i]; - last = children[i]; - } - if (last) - last->next_sibling = NULL; - - path->last_child = last; - - g_free (children); - - e_tree_model_node_changed (E_TREE_MODEL (etmm), node); -} - -void -e_tree_memory_set_node_destroy_func (ETreeMemory *etmm, - GFunc destroy_func, - gpointer user_data) -{ - etmm->priv->destroy_func = destroy_func; - etmm->priv->destroy_user_data = user_data; -} diff --git a/widgets/table/e-tree-memory.h b/widgets/table/e-tree-memory.h deleted file mode 100644 index cff4811256..0000000000 --- a/widgets/table/e-tree-memory.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_MEMORY_H_ -#define _E_TREE_MEMORY_H_ - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <table/e-tree-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_MEMORY \ - (e_tree_memory_get_type ()) -#define E_TREE_MEMORY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_MEMORY, ETreeMemory)) -#define E_TREE_MEMORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_MEMORY, ETreeMemoryClass)) -#define E_IS_TREE_MEMORY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_MEMORY)) -#define E_IS_TREE_MEMORY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_MEMORY)) -#define E_TREE_MEMORY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_MEMORY, ETreeMemoryClass)) - -G_BEGIN_DECLS - -typedef struct _ETreeMemory ETreeMemory; -typedef struct _ETreeMemoryClass ETreeMemoryClass; -typedef struct _ETreeMemoryPrivate ETreeMemoryPrivate; - -typedef gint (*ETreeMemorySortCallback) (ETreeMemory *etmm, - ETreePath path1, - ETreePath path2, - gpointer closure); - -struct _ETreeMemory { - ETreeModel parent; - ETreeMemoryPrivate *priv; -}; - -struct _ETreeMemoryClass { - ETreeModelClass parent_class; - - /* Signals */ - void (*fill_in_children) (ETreeMemory *model, - ETreePath node); -}; - -GType e_tree_memory_get_type (void) G_GNUC_CONST; -void e_tree_memory_construct (ETreeMemory *etree); -ETreeMemory * e_tree_memory_new (void); - -/* node operations */ -ETreePath e_tree_memory_node_insert (ETreeMemory *etree, - ETreePath parent, - gint position, - gpointer node_data); -ETreePath e_tree_memory_node_insert_id (ETreeMemory *etree, - ETreePath parent, - gint position, - gpointer node_data, - gchar *id); -ETreePath e_tree_memory_node_insert_before - (ETreeMemory *etree, - ETreePath parent, - ETreePath sibling, - gpointer node_data); -gpointer e_tree_memory_node_remove (ETreeMemory *etree, - ETreePath path); - -/* Freeze and thaw */ -void e_tree_memory_freeze (ETreeMemory *etree); -void e_tree_memory_thaw (ETreeMemory *etree); -void e_tree_memory_set_expanded_default - (ETreeMemory *etree, - gboolean expanded); -gpointer e_tree_memory_node_get_data (ETreeMemory *etm, - ETreePath node); -void e_tree_memory_node_set_data (ETreeMemory *etm, - ETreePath node, - gpointer node_data); -void e_tree_memory_sort_node (ETreeMemory *etm, - ETreePath node, - ETreeMemorySortCallback callback, - gpointer user_data); -void e_tree_memory_set_node_destroy_func - (ETreeMemory *etmm, - GFunc destroy_func, - gpointer user_data); - -G_END_DECLS - -#endif /* _E_TREE_MEMORY_H */ - diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c deleted file mode 100644 index 944572dfb4..0000000000 --- a/widgets/table/e-tree-model.c +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> - -#include <gtk/gtk.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-tree-model.h" - -#define ETM_CLASS(e) (E_TREE_MODEL_GET_CLASS(e)) - -#define d(x) - -G_DEFINE_TYPE (ETreeModel, e_tree_model, G_TYPE_OBJECT) - -enum { - PRE_CHANGE, - NO_CHANGE, - NODE_CHANGED, - NODE_DATA_CHANGED, - NODE_COL_CHANGED, - NODE_INSERTED, - NODE_REMOVED, - NODE_DELETED, - NODE_REQUEST_COLLAPSE, - REBUILT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0, }; - -static void -e_tree_model_class_init (ETreeModelClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - signals[PRE_CHANGE] = g_signal_new ( - "pre_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, pre_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[NO_CHANGE] = g_signal_new ( - "no_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, no_change), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[REBUILT] = g_signal_new ( - "rebuilt", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, rebuilt), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[NODE_CHANGED] = g_signal_new ( - "node_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - signals[NODE_DATA_CHANGED] = g_signal_new ( - "node_data_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_data_changed), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - signals[NODE_COL_CHANGED] = g_signal_new ( - "node_col_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_col_changed), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__POINTER_INT, - G_TYPE_NONE, 2, - G_TYPE_POINTER, - G_TYPE_INT); - - signals[NODE_INSERTED] = g_signal_new ( - "node_inserted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_inserted), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, - G_TYPE_POINTER, - G_TYPE_POINTER); - - signals[NODE_REMOVED] = g_signal_new ( - "node_removed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_removed), - (GSignalAccumulator) NULL, NULL, - e_marshal_VOID__POINTER_POINTER_INT, - G_TYPE_NONE, 3, - G_TYPE_POINTER, - G_TYPE_POINTER, - G_TYPE_INT); - - signals[NODE_DELETED] = g_signal_new ( - "node_deleted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_deleted), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - signals[NODE_REQUEST_COLLAPSE] = g_signal_new ( - "node_request_collapse", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeModelClass, node_request_collapse), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - class->get_root = NULL; - - class->get_parent = NULL; - class->get_first_child = NULL; - class->get_last_child = NULL; - class->get_next = NULL; - class->get_prev = NULL; - - class->is_root = NULL; - class->is_expandable = NULL; - class->get_children = NULL; - class->depth = NULL; - - class->icon_at = NULL; - - class->get_expanded_default = NULL; - class->column_count = NULL; - - class->has_save_id = NULL; - class->get_save_id = NULL; - class->has_get_node_by_id = NULL; - class->get_node_by_id = NULL; - - class->has_change_pending = NULL; - - class->sort_value_at = NULL; - class->value_at = NULL; - class->set_value_at = NULL; - class->is_editable = NULL; - - class->duplicate_value = NULL; - class->free_value = NULL; - class->initialize_value = NULL; - class->value_is_empty = NULL; - class->value_to_string = NULL; - - class->pre_change = NULL; - class->no_change = NULL; - class->rebuilt = NULL; - class->node_changed = NULL; - class->node_data_changed = NULL; - class->node_col_changed = NULL; - class->node_inserted = NULL; - class->node_removed = NULL; - class->node_deleted = NULL; - class->node_request_collapse = NULL; -} - -static void -e_tree_model_init (ETreeModel *tree_model) -{ - /* nothing to do */ -} - -/* signals */ - -/** - * e_tree_model_node_changed: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_pre_change (ETreeModel *tree_model) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[PRE_CHANGE], 0); -} - -/** - * e_tree_model_node_changed: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_no_change (ETreeModel *tree_model) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NO_CHANGE], 0); -} - -/** - * e_tree_model_rebuilt: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_rebuilt (ETreeModel *tree_model) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[REBUILT], 0); -} -/** - * e_tree_model_node_changed: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_node_changed (ETreeModel *tree_model, - ETreePath node) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NODE_CHANGED], 0, node); -} - -/** - * e_tree_model_node_data_changed: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_node_data_changed (ETreeModel *tree_model, - ETreePath node) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NODE_DATA_CHANGED], 0, node); -} - -/** - * e_tree_model_node_col_changed: - * @tree_model: - * @node: - * - * - * - * Return value: - **/ -void -e_tree_model_node_col_changed (ETreeModel *tree_model, - ETreePath node, - gint col) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NODE_COL_CHANGED], 0, node, col); -} - -/** - * e_tree_model_node_inserted: - * @tree_model: - * @parent_node: - * @inserted_node: - * - * - **/ -void -e_tree_model_node_inserted (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath inserted_node) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit ( - tree_model, signals[NODE_INSERTED], 0, - parent_node, inserted_node); -} - -/** - * e_tree_model_node_removed: - * @tree_model: - * @parent_node: - * @removed_node: - * - * - **/ -void -e_tree_model_node_removed (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath removed_node, - gint old_position) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit ( - tree_model, signals[NODE_REMOVED], 0, - parent_node, removed_node, old_position); -} - -/** - * e_tree_model_node_deleted: - * @tree_model: - * @deleted_node: - * - * - **/ -void -e_tree_model_node_deleted (ETreeModel *tree_model, - ETreePath deleted_node) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NODE_DELETED], 0, deleted_node); -} - -/** - * e_tree_model_node_request_collapse: - * @tree_model: - * @collapsed_node: - * - * - **/ -void -e_tree_model_node_request_collapse (ETreeModel *tree_model, - ETreePath collapsed_node) -{ - g_return_if_fail (E_IS_TREE_MODEL (tree_model)); - - g_signal_emit (tree_model, signals[NODE_REQUEST_COLLAPSE], 0, collapsed_node); -} - -/** - * e_tree_model_new - * - * XXX docs here. - * - * return values: a newly constructed ETreeModel. - */ -ETreeModel * -e_tree_model_new (void) -{ - return g_object_new (E_TYPE_TREE_MODEL, NULL); -} - -/** - * e_tree_model_get_root - * @etree: the ETreeModel of which we want the root node. - * - * Accessor for the root node of @etree. - * - * return values: the ETreePath corresponding to the root node. - */ -ETreePath -e_tree_model_get_root (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_root) - return ETM_CLASS (etree)->get_root (etree); - else - return NULL; -} - -/** - * e_tree_model_node_get_parent: - * @etree: - * @path: - * - * - * - * Return value: - **/ -ETreePath -e_tree_model_node_get_parent (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_parent) - return ETM_CLASS (etree)->get_parent (etree, node); - else - return NULL; -} - -/** - * e_tree_model_node_get_first_child: - * @etree: - * @node: - * - * - * - * Return value: - **/ -ETreePath -e_tree_model_node_get_first_child (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_first_child) - return ETM_CLASS (etree)->get_first_child (etree, node); - else - return NULL; -} - -/** - * e_tree_model_node_get_last_child: - * @etree: - * @node: - * - * - * - * Return value: - **/ -ETreePath -e_tree_model_node_get_last_child (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_last_child) - return ETM_CLASS (etree)->get_last_child (etree, node); - else - return NULL; -} - -/** - * e_tree_model_node_get_next: - * @etree: - * @node: - * - * - * - * Return value: - **/ -ETreePath -e_tree_model_node_get_next (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_next) - return ETM_CLASS (etree)->get_next (etree, node); - else - return NULL; -} - -/** - * e_tree_model_node_get_prev: - * @etree: - * @node: - * - * - * - * Return value: - **/ -ETreePath -e_tree_model_node_get_prev (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_prev) - return ETM_CLASS (etree)->get_prev (etree, node); - else - return NULL; -} - -/** - * e_tree_model_node_is_root: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gboolean -e_tree_model_node_is_root (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (etree != NULL, FALSE); - - if (ETM_CLASS (etree)->is_root) - return ETM_CLASS (etree)->is_root (etree, node); - else - return FALSE; -} - -/** - * e_tree_model_node_is_expandable: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gboolean -e_tree_model_node_is_expandable (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (etree != NULL, FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - if (ETM_CLASS (etree)->is_expandable) - return ETM_CLASS (etree)->is_expandable (etree, node); - else - return FALSE; -} - -guint -e_tree_model_node_get_children (ETreeModel *etree, - ETreePath node, - ETreePath **nodes) -{ - g_return_val_if_fail (etree != NULL, 0); - if (ETM_CLASS (etree)->get_children) - return ETM_CLASS (etree)->get_children (etree, node, nodes); - else - return 0; -} - -/** - * e_tree_model_node_depth: - * @etree: - * @path: - * - * - * - * Return value: - **/ -guint -e_tree_model_node_depth (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0); - - if (ETM_CLASS (etree)->depth) - return ETM_CLASS (etree)->depth (etree, node); - else - return 0; -} - -/** - * e_tree_model_icon_at - * @etree: The ETreeModel. - * @path: The ETreePath to the node we're getting the icon of. - * - * XXX docs here. - * - * return values: the GdkPixbuf associated with this node. - */ -GdkPixbuf * -e_tree_model_icon_at (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->icon_at) - return ETM_CLASS (etree)->icon_at (etree, node); - else - return NULL; -} - -/** - * e_tree_model_get_expanded_default - * @etree: The ETreeModel. - * - * XXX docs here. - * - * return values: Whether nodes should be expanded by default. - */ -gboolean -e_tree_model_get_expanded_default (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE); - - if (ETM_CLASS (etree)->get_expanded_default) - return ETM_CLASS (etree)->get_expanded_default (etree); - else - return FALSE; -} - -/** - * e_tree_model_column_count - * @etree: The ETreeModel. - * - * XXX docs here. - * - * return values: The number of columns - */ -gint -e_tree_model_column_count (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0); - - if (ETM_CLASS (etree)->column_count) - return ETM_CLASS (etree)->column_count (etree); - else - return 0; -} - -/** - * e_tree_model_has_save_id - * @etree: The ETreeModel. - * - * XXX docs here. - * - * return values: Whether this tree has valid save id data. - */ -gboolean -e_tree_model_has_save_id (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE); - - if (ETM_CLASS (etree)->has_save_id) - return ETM_CLASS (etree)->has_save_id (etree); - else - return FALSE; -} - -/** - * e_tree_model_get_save_id - * @etree: The ETreeModel. - * @node: The ETreePath. - * - * XXX docs here. - * - * return values: The save id for this path. - */ -gchar * -e_tree_model_get_save_id (ETreeModel *etree, - ETreePath node) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_save_id) - return ETM_CLASS (etree)->get_save_id (etree, node); - else - return NULL; -} - -/** - * e_tree_model_has_get_node_by_id - * @etree: The ETreeModel. - * - * XXX docs here. - * - * return values: Whether this tree can quickly get a node from its save id. - */ -gboolean -e_tree_model_has_get_node_by_id (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE); - - if (ETM_CLASS (etree)->has_get_node_by_id) - return ETM_CLASS (etree)->has_get_node_by_id (etree); - else - return FALSE; -} - -/** - * e_tree_model_get_node_by_id - * @etree: The ETreeModel. - * @node: The ETreePath. - * - * get_node_by_id(get_save_id(node)) should be the original node. - * Likewise if get_node_by_id is not NULL, then - * get_save_id(get_node_by_id(string)) should be a copy of the - * original string. - * - * return values: The path for this save id. - */ -ETreePath -e_tree_model_get_node_by_id (ETreeModel *etree, - const gchar *save_id) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->get_node_by_id) - return ETM_CLASS (etree)->get_node_by_id (etree, save_id); - else - return NULL; -} - -/** - * e_tree_model_has_change_pending - * @etree: The ETreeModel. - * - * XXX docs here. - * - * return values: Whether this tree has valid save id data. - */ -gboolean -e_tree_model_has_change_pending (ETreeModel *etree) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE); - - if (ETM_CLASS (etree)->has_change_pending) - return ETM_CLASS (etree)->has_change_pending (etree); - else - return FALSE; -} - -/** - * e_tree_model_sort_value_at: - * @etree: The ETreeModel. - * @node: The ETreePath to the node we're getting the data from. - * @col: the column to retrieve data from - * - * Return value: This function returns the value that is stored by the - * @etree in column @col and node @node. The data returned can be a - * pointer or any data value that can be stored inside a pointer. - * - * The data returned is typically used by an sort renderer if it wants - * to proxy the data of cell value_at at a better sorting order. - * - * The data returned must be valid until the model sends a signal that - * affect that piece of data. node_changed and node_deleted affect - * all data in tha t node and all nodes under that node. - * node_data_changed affects the data in that node. node_col_changed - * affects the data in that node for that column. node_inserted, - * node_removed, and no_change don't affect any data in this way. - **/ -gpointer -e_tree_model_sort_value_at (ETreeModel *etree, - ETreePath node, - gint col) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->sort_value_at) - return ETM_CLASS (etree)->sort_value_at (etree, node, col); - else - return NULL; -} - -/** - * e_tree_model_value_at: - * @etree: The ETreeModel. - * @node: The ETreePath to the node we're getting the data from. - * @col: the column to retrieve data from - * - * Return value: This function returns the value that is stored by the - * @etree in column @col and node @node. The data returned can be a - * pointer or any data value that can be stored inside a pointer. - * - * The data returned is typically used by an ECell renderer. - * - * The data returned must be valid until the model sends a signal that - * affect that piece of data. node_changed and node_deleted affect - * all data in tha t node and all nodes under that node. - * node_data_changed affects the data in that node. node_col_changed - * affects the data in that node for that column. node_inserted, - * node_removed, and no_change don't affect any data in this way. - **/ -gpointer -e_tree_model_value_at (ETreeModel *etree, - ETreePath node, - gint col) -{ - g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL); - - if (ETM_CLASS (etree)->value_at) - return ETM_CLASS (etree)->value_at (etree, node, col); - else - return NULL; -} - -void -e_tree_model_set_value_at (ETreeModel *etree, - ETreePath node, - gint col, - gconstpointer val) -{ - g_return_if_fail (E_IS_TREE_MODEL (etree)); - - if (ETM_CLASS (etree)->set_value_at) - ETM_CLASS (etree)->set_value_at (etree, node, col, val); -} - -/** - * e_tree_model_node_is_editable: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gboolean -e_tree_model_node_is_editable (ETreeModel *etree, - ETreePath node, - gint col) -{ - g_return_val_if_fail (etree != NULL, FALSE); - - if (ETM_CLASS (etree)->is_editable) - return ETM_CLASS (etree)->is_editable (etree, node, col); - else - return FALSE; -} - -/** - * e_tree_model_duplicate_value: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gpointer -e_tree_model_duplicate_value (ETreeModel *etree, - gint col, - gconstpointer value) -{ - g_return_val_if_fail (etree != NULL, NULL); - - if (ETM_CLASS (etree)->duplicate_value) - return ETM_CLASS (etree)->duplicate_value (etree, col, value); - else - return NULL; -} - -/** - * e_tree_model_free_value: - * @etree: - * @path: - * - * - * - * Return value: - **/ -void -e_tree_model_free_value (ETreeModel *etree, - gint col, - gpointer value) -{ - g_return_if_fail (etree != NULL); - - if (ETM_CLASS (etree)->free_value) - ETM_CLASS (etree)->free_value (etree, col, value); -} - -/** - * e_tree_model_initialize_value: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gpointer -e_tree_model_initialize_value (ETreeModel *etree, - gint col) -{ - g_return_val_if_fail (etree != NULL, NULL); - - if (ETM_CLASS (etree)->initialize_value) - return ETM_CLASS (etree)->initialize_value (etree, col); - else - return NULL; -} - -/** - * e_tree_model_value_is_empty: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gboolean -e_tree_model_value_is_empty (ETreeModel *etree, - gint col, - gconstpointer value) -{ - g_return_val_if_fail (etree != NULL, TRUE); - - if (ETM_CLASS (etree)->value_is_empty) - return ETM_CLASS (etree)->value_is_empty (etree, col, value); - else - return TRUE; -} - -/** - * e_tree_model_value_to_string: - * @etree: - * @path: - * - * - * - * Return value: - **/ -gchar * -e_tree_model_value_to_string (ETreeModel *etree, - gint col, - gconstpointer value) -{ - g_return_val_if_fail (etree != NULL, g_strdup ("")); - - if (ETM_CLASS (etree)->value_to_string) - return ETM_CLASS (etree)->value_to_string (etree, col, value); - else - return g_strdup (""); -} - -/** - * e_tree_model_node_traverse: - * @model: - * @path: - * @func: - * @data: - * - * - **/ -void -e_tree_model_node_traverse (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data) -{ - ETreePath child; - - g_return_if_fail (E_IS_TREE_MODEL (model)); - g_return_if_fail (path != NULL); - - child = e_tree_model_node_get_first_child (model, path); - - while (child) { - ETreePath next_child; - - next_child = e_tree_model_node_get_next (model, child); - e_tree_model_node_traverse (model, child, func, data); - if (func (model, child, data)) - return; - - child = next_child; - } -} - -/** - * e_tree_model_node_traverse_preorder: - * @model: - * @path: - * @func: - * @data: - * - * - **/ -void -e_tree_model_node_traverse_preorder (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data) -{ - ETreePath child; - - g_return_if_fail (E_IS_TREE_MODEL (model)); - g_return_if_fail (path != NULL); - - child = e_tree_model_node_get_first_child (model, path); - - while (child) { - ETreePath next_child; - - if (func (model, child, data)) - return; - - next_child = e_tree_model_node_get_next (model, child); - e_tree_model_node_traverse_preorder (model, child, func, data); - - child = next_child; - } -} - -/** - * e_tree_model_node_traverse_preorder: - * @model: - * @path: - * @func: - * @data: - * - * - **/ -static ETreePath -e_tree_model_node_real_traverse (ETreeModel *model, - ETreePath path, - ETreePath end_path, - gboolean forward_direction, - ETreePathFunc func, - gpointer data) -{ - ETreePath child; - - g_return_val_if_fail (E_IS_TREE_MODEL (model), NULL); - g_return_val_if_fail (path != NULL, NULL); - - if (forward_direction) - child = e_tree_model_node_get_first_child (model, path); - else - child = e_tree_model_node_get_last_child (model, path); - - while (child) { - ETreePath result; - - if (forward_direction && (child == end_path || func (model, child, data))) - return child; - - if ((result = e_tree_model_node_real_traverse ( - model, child, end_path, - forward_direction, func, data))) - return result; - - if (!forward_direction && (child == end_path || func (model, child, data))) - return child; - - if (forward_direction) - child = e_tree_model_node_get_next (model, child); - else - child = e_tree_model_node_get_prev (model, child); - } - return NULL; -} - -/** - * e_tree_model_node_traverse_preorder: - * @model: - * @path: - * @func: - * @data: - * - * - **/ -ETreePath -e_tree_model_node_find (ETreeModel *model, - ETreePath path, - ETreePath end_path, - gboolean forward_direction, - ETreePathFunc func, - gpointer data) -{ - ETreePath result; - ETreePath next; - - g_return_val_if_fail (E_IS_TREE_MODEL (model), NULL); - - /* Just search the whole tree in this case. */ - if (path == NULL) { - ETreePath root; - root = e_tree_model_get_root (model); - - if (forward_direction && (end_path == root || func (model, root, data))) - return root; - - result = e_tree_model_node_real_traverse ( - model, root, end_path, forward_direction, func, data); - if (result) - return result; - - if (!forward_direction && (end_path == root || func (model, root, data))) - return root; - - return NULL; - } - - while (1) { - - if (forward_direction) { - if ((result = e_tree_model_node_real_traverse ( - model, path, end_path, - forward_direction, func, data))) - return result; - next = e_tree_model_node_get_next (model, path); - } else { - next = e_tree_model_node_get_prev (model, path); - if (next && (result = e_tree_model_node_real_traverse ( - model, next, end_path, - forward_direction, func, data))) - return result; - } - - while (next == NULL) { - path = e_tree_model_node_get_parent (model, path); - - if (path == NULL) - return NULL; - - if (forward_direction) - next = e_tree_model_node_get_next (model, path); - else - next = path; - } - - if (end_path == next || func (model, next, data)) - return next; - - path = next; - } -} - diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h deleted file mode 100644 index f857e52a49..0000000000 --- a/widgets/table/e-tree-model.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_MODEL_H_ -#define _E_TREE_MODEL_H_ - -#include <gdk-pixbuf/gdk-pixbuf.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_MODEL \ - (e_tree_model_get_type ()) -#define E_TREE_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_MODEL, ETreeModel)) -#define E_TREE_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_MODEL, ETreeModelClass)) -#define E_IS_TREE_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_MODEL)) -#define E_IS_TREE_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_MODEL)) -#define E_TREE_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_MODEL, ETreeModelClass)) - -G_BEGIN_DECLS - -typedef gpointer ETreePath; - -typedef struct _ETreeModel ETreeModel; -typedef struct _ETreeModelClass ETreeModelClass; - -typedef gint (*ETreePathCompareFunc) (ETreeModel *model, - ETreePath path1, - ETreePath path2); -typedef gboolean (*ETreePathFunc) (ETreeModel *model, - ETreePath path, - gpointer data); - -struct _ETreeModel { - GObject parent; -}; - -struct _ETreeModelClass { - GObjectClass parent_class; - - /* - * Virtual methods - */ - ETreePath (*get_root) (ETreeModel *etm); - - ETreePath (*get_parent) (ETreeModel *etm, - ETreePath node); - ETreePath (*get_first_child) (ETreeModel *etm, - ETreePath node); - ETreePath (*get_last_child) (ETreeModel *etm, - ETreePath node); - ETreePath (*get_next) (ETreeModel *etm, - ETreePath node); - ETreePath (*get_prev) (ETreeModel *etm, - ETreePath node); - - gboolean (*is_root) (ETreeModel *etm, - ETreePath node); - gboolean (*is_expandable) (ETreeModel *etm, - ETreePath node); - guint (*get_children) (ETreeModel *etm, - ETreePath node, - ETreePath **paths); - guint (*depth) (ETreeModel *etm, - ETreePath node); - - GdkPixbuf * (*icon_at) (ETreeModel *etm, - ETreePath node); - - gboolean (*get_expanded_default) (ETreeModel *etm); - gint (*column_count) (ETreeModel *etm); - - gboolean (*has_save_id) (ETreeModel *etm); - gchar * (*get_save_id) (ETreeModel *etm, - ETreePath node); - - gboolean (*has_get_node_by_id) (ETreeModel *etm); - ETreePath (*get_node_by_id) (ETreeModel *etm, - const gchar *save_id); - - gboolean (*has_change_pending) (ETreeModel *etm); - - /* - * ETable analogs - */ - gpointer (*sort_value_at) (ETreeModel *etm, - ETreePath node, - gint col); - gpointer (*value_at) (ETreeModel *etm, - ETreePath node, - gint col); - void (*set_value_at) (ETreeModel *etm, - ETreePath node, - gint col, - gconstpointer val); - gboolean (*is_editable) (ETreeModel *etm, - ETreePath node, - gint col); - - gpointer (*duplicate_value) (ETreeModel *etm, - gint col, - gconstpointer value); - void (*free_value) (ETreeModel *etm, - gint col, - gpointer value); - gpointer (*initialize_value) (ETreeModel *etm, - gint col); - gboolean (*value_is_empty) (ETreeModel *etm, - gint col, - gconstpointer value); - gchar * (*value_to_string) (ETreeModel *etm, - gint col, - gconstpointer value); - - /* - * Signals - */ - - /* During node_remove, the ETreePath of the child is removed - * from the tree but is still a valid ETreePath. At - * node_deleted, the ETreePath is no longer valid. - */ - - void (*pre_change) (ETreeModel *etm); - void (*no_change) (ETreeModel *etm); - void (*node_changed) (ETreeModel *etm, - ETreePath node); - void (*node_data_changed) (ETreeModel *etm, - ETreePath node); - void (*node_col_changed) (ETreeModel *etm, - ETreePath node, - gint col); - void (*node_inserted) (ETreeModel *etm, - ETreePath parent, - ETreePath inserted_node); - void (*node_removed) (ETreeModel *etm, - ETreePath parent, - ETreePath removed_node, - gint old_position); - void (*node_deleted) (ETreeModel *etm, - ETreePath deleted_node); - void (*rebuilt) (ETreeModel *etm); - - /* This signal requests that any viewers of the tree that - * collapse and expand nodes collapse this node. - */ - void (*node_request_collapse) - (ETreeModel *etm, - ETreePath node); -}; - -GType e_tree_model_get_type (void) G_GNUC_CONST; -ETreeModel * e_tree_model_new (void); - -/* tree traversal operations */ -ETreePath e_tree_model_get_root (ETreeModel *etree); -ETreePath e_tree_model_node_get_parent (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_first_child - (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_last_child - (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_next (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_prev (ETreeModel *etree, - ETreePath path); - -/* node accessors */ -gboolean e_tree_model_node_is_root (ETreeModel *etree, - ETreePath path); -gboolean e_tree_model_node_is_expandable (ETreeModel *etree, - ETreePath path); -guint e_tree_model_node_get_children (ETreeModel *etree, - ETreePath path, - ETreePath **paths); -guint e_tree_model_node_depth (ETreeModel *etree, - ETreePath path); -GdkPixbuf * e_tree_model_icon_at (ETreeModel *etree, - ETreePath path); -gboolean e_tree_model_get_expanded_default - (ETreeModel *model); -gint e_tree_model_column_count (ETreeModel *model); -gboolean e_tree_model_has_save_id (ETreeModel *model); -gchar * e_tree_model_get_save_id (ETreeModel *model, - ETreePath node); -gboolean e_tree_model_has_get_node_by_id (ETreeModel *model); -ETreePath e_tree_model_get_node_by_id (ETreeModel *model, - const gchar *save_id); -gboolean e_tree_model_has_change_pending (ETreeModel *model); -void *e_tree_model_sort_value_at (ETreeModel *etree, - ETreePath node, - gint col); -void *e_tree_model_value_at (ETreeModel *etree, - ETreePath node, - gint col); -void e_tree_model_set_value_at (ETreeModel *etree, - ETreePath node, - gint col, - gconstpointer val); -gboolean e_tree_model_node_is_editable (ETreeModel *etree, - ETreePath node, - gint col); -void *e_tree_model_duplicate_value (ETreeModel *etree, - gint col, - gconstpointer value); -void e_tree_model_free_value (ETreeModel *etree, - gint col, - gpointer value); -void *e_tree_model_initialize_value (ETreeModel *etree, - gint col); -gboolean e_tree_model_value_is_empty (ETreeModel *etree, - gint col, - gconstpointer value); -gchar * e_tree_model_value_to_string (ETreeModel *etree, - gint col, - gconstpointer value); - -/* depth first traversal of path's descendents, calling func on each one */ -void e_tree_model_node_traverse (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data); -void e_tree_model_node_traverse_preorder - (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data); -ETreePath e_tree_model_node_find (ETreeModel *model, - ETreePath path, - ETreePath end_path, - gboolean forward_direction, - ETreePathFunc func, - gpointer data); - -/* -** Routines for emitting signals on the ETreeModel -*/ -void e_tree_model_pre_change (ETreeModel *tree_model); -void e_tree_model_no_change (ETreeModel *tree_model); -void e_tree_model_rebuilt (ETreeModel *tree_model); -void e_tree_model_node_changed (ETreeModel *tree_model, - ETreePath node); -void e_tree_model_node_data_changed (ETreeModel *tree_model, - ETreePath node); -void e_tree_model_node_col_changed (ETreeModel *tree_model, - ETreePath node, - gint col); -void e_tree_model_node_inserted (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath inserted_node); -void e_tree_model_node_removed (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath removed_node, - gint old_position); -void e_tree_model_node_deleted (ETreeModel *tree_model, - ETreePath deleted_node); -void e_tree_model_node_request_collapse - (ETreeModel *tree_model, - ETreePath deleted_node); - -G_END_DECLS - -#endif /* _E_TREE_MODEL_H */ diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c deleted file mode 100644 index 33e4ab0780..0000000000 --- a/widgets/table/e-tree-selection-model.c +++ /dev/null @@ -1,939 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "table/e-tree-table-adapter.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" - -#include "e-tree-selection-model.h" - -#define E_TREE_SELECTION_MODEL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TREE_SELECTION_MODEL, ETreeSelectionModelPrivate)) - -G_DEFINE_TYPE ( - ETreeSelectionModel, e_tree_selection_model, E_TYPE_SELECTION_MODEL) - -enum { - PROP_0, - PROP_CURSOR_ROW, - PROP_CURSOR_COL, - PROP_MODEL, - PROP_ETTA -}; - -struct _ETreeSelectionModelPrivate { - ETreeTableAdapter *etta; - ETreeModel *model; - - GHashTable *paths; - ETreePath cursor_path; - ETreePath start_path; - gint cursor_col; - gchar *cursor_save_id; - - gint tree_model_pre_change_id; - gint tree_model_no_change_id; - gint tree_model_node_changed_id; - gint tree_model_node_data_changed_id; - gint tree_model_node_col_changed_id; - gint tree_model_node_inserted_id; - gint tree_model_node_removed_id; - gint tree_model_node_deleted_id; -}; - -static gint -get_cursor_row (ETreeSelectionModel *etsm) -{ - if (etsm->priv->cursor_path) - return e_tree_table_adapter_row_of_node ( - etsm->priv->etta, etsm->priv->cursor_path); - - return -1; -} - -static void -clear_selection (ETreeSelectionModel *etsm) -{ - g_hash_table_destroy (etsm->priv->paths); - etsm->priv->paths = g_hash_table_new (NULL, NULL); -} - -static void -change_one_path (ETreeSelectionModel *etsm, - ETreePath path, - gboolean grow) -{ - if (!path) - return; - - if (grow) - g_hash_table_insert (etsm->priv->paths, path, path); - else if (g_hash_table_lookup (etsm->priv->paths, path)) - g_hash_table_remove (etsm->priv->paths, path); -} - -static void -select_single_path (ETreeSelectionModel *etsm, - ETreePath path) -{ - clear_selection (etsm); - change_one_path (etsm, path, TRUE); - etsm->priv->cursor_path = path; - etsm->priv->start_path = NULL; -} - -static void -select_range (ETreeSelectionModel *etsm, - gint start, - gint end) -{ - gint i; - - if (start > end) { - i = start; - start = end; - end = i; - } - - for (i = start; i <= end; i++) { - ETreePath path = e_tree_table_adapter_node_at_row (etsm->priv->etta, i); - if (path) - g_hash_table_insert (etsm->priv->paths, path, path); - } -} - -static void -free_id (ETreeSelectionModel *etsm) -{ - g_free (etsm->priv->cursor_save_id); - etsm->priv->cursor_save_id = NULL; -} - -static void -restore_cursor (ETreeSelectionModel *etsm, - ETreeModel *etm) -{ - clear_selection (etsm); - etsm->priv->cursor_path = NULL; - - if (etsm->priv->cursor_save_id) { - etsm->priv->cursor_path = e_tree_model_get_node_by_id ( - etm, etsm->priv->cursor_save_id); - if (etsm->priv->cursor_path != NULL && etsm->priv->cursor_col == -1) - etsm->priv->cursor_col = 0; - - select_single_path (etsm, etsm->priv->cursor_path); - } - - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - - if (etsm->priv->cursor_path) { - gint cursor_row = get_cursor_row (etsm); - e_selection_model_cursor_changed ( - E_SELECTION_MODEL (etsm), - cursor_row, etsm->priv->cursor_col); - } else { - e_selection_model_cursor_changed ( - E_SELECTION_MODEL (etsm), -1, -1); - e_selection_model_cursor_activated ( - E_SELECTION_MODEL (etsm), -1, -1); - - } - - free_id (etsm); -} - -static void -etsm_pre_change (ETreeModel *etm, - ETreeSelectionModel *etsm) -{ - g_free (etsm->priv->cursor_save_id); - etsm->priv->cursor_save_id = NULL; - - if (e_tree_model_has_get_node_by_id (etm) && - e_tree_model_has_save_id (etm) && - etsm->priv->cursor_path) { - etsm->priv->cursor_save_id = e_tree_model_get_save_id ( - etm, etsm->priv->cursor_path); - } -} - -static void -etsm_no_change (ETreeModel *etm, - ETreeSelectionModel *etsm) -{ - free_id (etsm); -} - -static void -etsm_node_changed (ETreeModel *etm, - ETreePath node, - ETreeSelectionModel *etsm) -{ - restore_cursor (etsm, etm); -} - -static void -etsm_node_data_changed (ETreeModel *etm, - ETreePath node, - ETreeSelectionModel *etsm) -{ - free_id (etsm); -} - -static void -etsm_node_col_changed (ETreeModel *etm, - ETreePath node, - gint col, - ETreeSelectionModel *etsm) -{ - free_id (etsm); -} - -static void -etsm_node_inserted (ETreeModel *etm, - ETreePath parent, - ETreePath child, - ETreeSelectionModel *etsm) -{ - restore_cursor (etsm, etm); -} - -static void -etsm_node_removed (ETreeModel *etm, - ETreePath parent, - ETreePath child, - gint old_position, - ETreeSelectionModel *etsm) -{ - restore_cursor (etsm, etm); -} - -static void -etsm_node_deleted (ETreeModel *etm, - ETreePath child, - ETreeSelectionModel *etsm) -{ - restore_cursor (etsm, etm); -} - -static void -add_model (ETreeSelectionModel *etsm, - ETreeModel *model) -{ - ETreeSelectionModelPrivate *priv = etsm->priv; - - priv->model = model; - - if (!priv->model) - return; - - g_object_ref (priv->model); - - priv->tree_model_pre_change_id = g_signal_connect_after ( - priv->model, "pre_change", - G_CALLBACK (etsm_pre_change), etsm); - - priv->tree_model_no_change_id = g_signal_connect_after ( - priv->model, "no_change", - G_CALLBACK (etsm_no_change), etsm); - - priv->tree_model_node_changed_id = g_signal_connect_after ( - priv->model, "node_changed", - G_CALLBACK (etsm_node_changed), etsm); - - priv->tree_model_node_data_changed_id = g_signal_connect_after ( - priv->model, "node_data_changed", - G_CALLBACK (etsm_node_data_changed), etsm); - - priv->tree_model_node_col_changed_id = g_signal_connect_after ( - priv->model, "node_col_changed", - G_CALLBACK (etsm_node_col_changed), etsm); - - priv->tree_model_node_inserted_id = g_signal_connect_after ( - priv->model, "node_inserted", - G_CALLBACK (etsm_node_inserted), etsm); - - priv->tree_model_node_removed_id = g_signal_connect_after ( - priv->model, "node_removed", - G_CALLBACK (etsm_node_removed), etsm); - - priv->tree_model_node_deleted_id = g_signal_connect_after ( - priv->model, "node_deleted", - G_CALLBACK (etsm_node_deleted), etsm); -} - -static void -drop_model (ETreeSelectionModel *etsm) -{ - ETreeSelectionModelPrivate *priv = etsm->priv; - - if (!priv->model) - return; - - g_signal_handler_disconnect ( - priv->model, priv->tree_model_pre_change_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_no_change_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_changed_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_data_changed_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_col_changed_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_inserted_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_removed_id); - g_signal_handler_disconnect ( - priv->model, priv->tree_model_node_deleted_id); - - g_object_unref (priv->model); - priv->model = NULL; - - priv->tree_model_pre_change_id = 0; - priv->tree_model_no_change_id = 0; - priv->tree_model_node_changed_id = 0; - priv->tree_model_node_data_changed_id = 0; - priv->tree_model_node_col_changed_id = 0; - priv->tree_model_node_inserted_id = 0; - priv->tree_model_node_removed_id = 0; - priv->tree_model_node_deleted_id = 0; -} - -static void -etsm_dispose (GObject *object) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (object); - - drop_model (etsm); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_tree_selection_model_parent_class)->dispose (object); -} - -static void -etsm_finalize (GObject *object) -{ - ETreeSelectionModelPrivate *priv; - - priv = E_TREE_SELECTION_MODEL_GET_PRIVATE (object); - - clear_selection (E_TREE_SELECTION_MODEL (object)); - g_hash_table_destroy (priv->paths); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_tree_selection_model_parent_class)->finalize (object); -} - -static void -etsm_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_CURSOR_ROW: - g_value_set_int (value, get_cursor_row (etsm)); - break; - - case PROP_CURSOR_COL: - g_value_set_int (value, etsm->priv->cursor_col); - break; - - case PROP_MODEL: - g_value_set_object (value, etsm->priv->model); - break; - - case PROP_ETTA: - g_value_set_object (value, etsm->priv->etta); - break; - } -} - -static void -etsm_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ESelectionModel *esm = E_SELECTION_MODEL (object); - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (object); - - switch (property_id) { - case PROP_CURSOR_ROW: - e_selection_model_do_something ( - esm, g_value_get_int (value), - etsm->priv->cursor_col, 0); - break; - - case PROP_CURSOR_COL: - e_selection_model_do_something ( - esm, get_cursor_row (etsm), - g_value_get_int (value), 0); - break; - - case PROP_MODEL: - drop_model (etsm); - add_model (etsm, E_TREE_MODEL (g_value_get_object (value))); - break; - - case PROP_ETTA: - etsm->priv->etta = - E_TREE_TABLE_ADAPTER (g_value_get_object (value)); - break; - } -} - -static gboolean -etsm_is_path_selected (ETreeSelectionModel *etsm, - ETreePath path) -{ - if (path && g_hash_table_lookup (etsm->priv->paths, path)) - return TRUE; - - return FALSE; -} - -/** - * e_selection_model_is_row_selected - * @selection: #ESelectionModel to check - * @n: The row to check - * - * This routine calculates whether the given row is selected. - * - * Returns: %TRUE if the given row is selected - */ -static gboolean -etsm_is_row_selected (ESelectionModel *selection, - gint row) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ETreePath path; - - g_return_val_if_fail ( - row < e_table_model_row_count ( - E_TABLE_MODEL (etsm->priv->etta)), FALSE); - g_return_val_if_fail (row >= 0, FALSE); - g_return_val_if_fail (etsm != NULL, FALSE); - - path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); - return etsm_is_path_selected (etsm, path); -} - -typedef struct { - ETreeSelectionModel *etsm; - EForeachFunc callback; - gpointer closure; -} ModelAndCallback; - -static void -etsm_row_foreach_cb (gpointer key, - gpointer value, - gpointer user_data) -{ - ETreePath path = key; - ModelAndCallback *mac = user_data; - gint row = e_tree_table_adapter_row_of_node ( - mac->etsm->priv->etta, path); - if (row >= 0) - mac->callback (row, mac->closure); -} - -/** - * e_selection_model_foreach - * @selection: #ESelectionModel to traverse - * @callback: The callback function to call back. - * @closure: The closure - * - * This routine calls the given callback function once for each - * selected row, passing closure as the closure. - */ -static void -etsm_foreach (ESelectionModel *selection, - EForeachFunc callback, - gpointer closure) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ModelAndCallback mac; - - mac.etsm = etsm; - mac.callback = callback; - mac.closure = closure; - - g_hash_table_foreach (etsm->priv->paths, etsm_row_foreach_cb, &mac); -} - -/** - * e_selection_model_clear - * @selection: #ESelectionModel to clear - * - * This routine clears the selection to no rows selected. - */ -static void -etsm_clear (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - - clear_selection (etsm); - - etsm->priv->cursor_path = NULL; - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (etsm), -1, -1); -} - -/** - * e_selection_model_selected_count - * @selection: #ESelectionModel to count - * - * This routine calculates the number of rows selected. - * - * Returns: The number of rows selected in the given model. - */ -static gint -etsm_selected_count (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - - return g_hash_table_size (etsm->priv->paths); -} - -static gint -etsm_row_count (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - return e_table_model_row_count (E_TABLE_MODEL (etsm->priv->etta)); -} - -/** - * e_selection_model_select_all - * @selection: #ESelectionModel to select all - * - * This routine selects all the rows in the given - * #ESelectionModel. - */ -static void -etsm_select_all (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ETreePath root; - - root = e_tree_model_get_root (etsm->priv->model); - if (root == NULL) - return; - - clear_selection (etsm); - select_range (etsm, 0, etsm_row_count (selection) - 1); - - if (etsm->priv->cursor_path == NULL) - etsm->priv->cursor_path = e_tree_table_adapter_node_at_row ( - etsm->priv->etta, 0); - - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - - e_selection_model_cursor_changed ( - E_SELECTION_MODEL (etsm), - get_cursor_row (etsm), etsm->priv->cursor_col); -} - -/** - * e_selection_model_invert_selection - * @selection: #ESelectionModel to invert - * - * This routine inverts all the rows in the given - * #ESelectionModel. - */ -static void -etsm_invert_selection (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - gint count = etsm_row_count (selection); - gint i; - - for (i = 0; i < count; i++) { - ETreePath path; - - path = e_tree_table_adapter_node_at_row (etsm->priv->etta, i); - if (!path) - continue; - if (g_hash_table_lookup (etsm->priv->paths, path)) - g_hash_table_remove (etsm->priv->paths, path); - else - g_hash_table_insert (etsm->priv->paths, path, path); - } - - etsm->priv->cursor_col = -1; - etsm->priv->cursor_path = NULL; - etsm->priv->start_path = NULL; - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - e_selection_model_cursor_changed (E_SELECTION_MODEL (etsm), -1, -1); -} - -static void -etsm_change_one_row (ESelectionModel *selection, - gint row, - gboolean grow) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ETreePath path; - - g_return_if_fail ( - row < e_table_model_row_count ( - E_TABLE_MODEL (etsm->priv->etta))); - g_return_if_fail (row >= 0); - g_return_if_fail (selection != NULL); - - path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); - - if (!path) - return; - - change_one_path (etsm, path, grow); -} - -static void -etsm_change_cursor (ESelectionModel *selection, - gint row, - gint col) -{ - ETreeSelectionModel *etsm; - - g_return_if_fail (selection != NULL); - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - etsm = E_TREE_SELECTION_MODEL (selection); - - if (row == -1) { - etsm->priv->cursor_path = NULL; - } else { - etsm->priv->cursor_path = - e_tree_table_adapter_node_at_row ( - etsm->priv->etta, row); - } - etsm->priv->cursor_col = col; -} - -static gint -etsm_cursor_row (ESelectionModel *selection) -{ - return get_cursor_row (E_TREE_SELECTION_MODEL (selection)); -} - -static gint -etsm_cursor_col (ESelectionModel *selection) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - return etsm->priv->cursor_col; -} - -static void -etsm_get_rows (gint row, - gpointer d) -{ - gint **rowp = d; - - **rowp = row; - (*rowp)++; -} - -static void -etsm_select_single_row (ESelectionModel *selection, - gint row) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ETreePath path; - gint rows[5], *rowp = NULL, size; - - path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); - g_return_if_fail (path != NULL); - - /* we really only care about the size=1 case (cursor changed), - * but this doesn't cost much */ - size = g_hash_table_size (etsm->priv->paths); - if (size > 0 && size <= 5) { - rowp = rows; - etsm_foreach (selection, etsm_get_rows, &rowp); - } - - select_single_path (etsm, path); - - if (size > 5) { - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); - } else { - if (rowp) { - gint *p = rows; - - while (p < rowp) - e_selection_model_selection_row_changed ( - (ESelectionModel *) etsm, *p++); - } - e_selection_model_selection_row_changed ( - (ESelectionModel *) etsm, row); - } -} - -static void -etsm_toggle_single_row (ESelectionModel *selection, - gint row) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - ETreePath path; - - path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); - g_return_if_fail (path); - - if (g_hash_table_lookup (etsm->priv->paths, path)) - g_hash_table_remove (etsm->priv->paths, path); - else - g_hash_table_insert (etsm->priv->paths, path, path); - - etsm->priv->start_path = NULL; - - e_selection_model_selection_row_changed ((ESelectionModel *) etsm, row); -} - -static void -etsm_real_move_selection_end (ETreeSelectionModel *etsm, - gint row) -{ - ETreePath end_path; - gint start; - - end_path = e_tree_table_adapter_node_at_row (etsm->priv->etta, row); - g_return_if_fail (end_path); - - start = e_tree_table_adapter_row_of_node ( - etsm->priv->etta, etsm->priv->start_path); - clear_selection (etsm); - select_range (etsm, start, row); -} - -static void -etsm_move_selection_end (ESelectionModel *selection, - gint row) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - - g_return_if_fail (etsm->priv->cursor_path); - - etsm_real_move_selection_end (etsm, row); - e_selection_model_selection_changed (E_SELECTION_MODEL (selection)); -} - -static void -etsm_set_selection_end (ESelectionModel *selection, - gint row) -{ - ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL (selection); - - g_return_if_fail (etsm->priv->cursor_path); - - if (!etsm->priv->start_path) - etsm->priv->start_path = etsm->priv->cursor_path; - etsm_real_move_selection_end (etsm, row); - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); -} - -struct foreach_path_t { - ETreeForeachFunc callback; - gpointer closure; -}; - -static void -foreach_path (gpointer key, - gpointer value, - gpointer data) -{ - ETreePath path = key; - struct foreach_path_t *c = data; - c->callback (path, c->closure); -} - -void -e_tree_selection_model_foreach (ETreeSelectionModel *etsm, - ETreeForeachFunc callback, - gpointer closure) -{ - if (etsm->priv->paths) { - struct foreach_path_t c; - c.callback = callback; - c.closure = closure; - g_hash_table_foreach (etsm->priv->paths, foreach_path, &c); - return; - } -} - -void -e_tree_selection_model_select_single_path (ETreeSelectionModel *etsm, - ETreePath path) -{ - select_single_path (etsm, path); - - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); -} - -void -e_tree_selection_model_select_paths (ETreeSelectionModel *etsm, - GPtrArray *paths) -{ - ETreePath path; - gint i; - - for (i = 0; i < paths->len; i++) { - path = paths->pdata[i]; - change_one_path (etsm, path, TRUE); - } - - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); -} - -void -e_tree_selection_model_add_to_selection (ETreeSelectionModel *etsm, - ETreePath path) -{ - change_one_path (etsm, path, TRUE); - - e_selection_model_selection_changed (E_SELECTION_MODEL (etsm)); -} - -void -e_tree_selection_model_change_cursor (ETreeSelectionModel *etsm, - ETreePath path) -{ - gint row; - - etsm->priv->cursor_path = path; - - row = get_cursor_row (etsm); - - E_SELECTION_MODEL (etsm)->old_selection = -1; - - e_selection_model_cursor_changed ( - E_SELECTION_MODEL (etsm), row, etsm->priv->cursor_col); - e_selection_model_cursor_activated ( - E_SELECTION_MODEL (etsm), row, etsm->priv->cursor_col); -} - -ETreePath -e_tree_selection_model_get_cursor (ETreeSelectionModel *etsm) -{ - return etsm->priv->cursor_path; -} - -static void -e_tree_selection_model_init (ETreeSelectionModel *etsm) -{ - etsm->priv = E_TREE_SELECTION_MODEL_GET_PRIVATE (etsm); - - etsm->priv->paths = g_hash_table_new (NULL, NULL); - etsm->priv->cursor_col = -1; -} - -static void -e_tree_selection_model_class_init (ETreeSelectionModelClass *class) -{ - GObjectClass *object_class; - ESelectionModelClass *esm_class; - - g_type_class_add_private (class, sizeof (ETreeSelectionModelPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = etsm_dispose; - object_class->finalize = etsm_finalize; - object_class->get_property = etsm_get_property; - object_class->set_property = etsm_set_property; - - esm_class = E_SELECTION_MODEL_CLASS (class); - esm_class->is_row_selected = etsm_is_row_selected; - esm_class->foreach = etsm_foreach; - esm_class->clear = etsm_clear; - esm_class->selected_count = etsm_selected_count; - esm_class->select_all = etsm_select_all; - esm_class->invert_selection = etsm_invert_selection; - esm_class->row_count = etsm_row_count; - - esm_class->change_one_row = etsm_change_one_row; - esm_class->change_cursor = etsm_change_cursor; - esm_class->cursor_row = etsm_cursor_row; - esm_class->cursor_col = etsm_cursor_col; - - esm_class->select_single_row = etsm_select_single_row; - esm_class->toggle_single_row = etsm_toggle_single_row; - esm_class->move_selection_end = etsm_move_selection_end; - esm_class->set_selection_end = etsm_set_selection_end; - - g_object_class_install_property ( - object_class, - PROP_CURSOR_ROW, - g_param_spec_int ( - "cursor_row", - "Cursor Row", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_COL, - g_param_spec_int ( - "cursor_col", - "Cursor Column", - NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Model", - NULL, - E_TYPE_TREE_MODEL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ETTA, - g_param_spec_object ( - "etta", - "ETTA", - NULL, - E_TYPE_TREE_TABLE_ADAPTER, - G_PARAM_READWRITE)); - -} - -ESelectionModel * -e_tree_selection_model_new (void) -{ - return g_object_new (E_TYPE_TREE_SELECTION_MODEL, NULL); -} - diff --git a/widgets/table/e-tree-selection-model.h b/widgets/table/e-tree-selection-model.h deleted file mode 100644 index 1541fcb95a..0000000000 --- a/widgets/table/e-tree-selection-model.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_SELECTION_MODEL_H_ -#define _E_TREE_SELECTION_MODEL_H_ - -#include <e-util/e-sorter.h> -#include <misc/e-selection-model.h> -#include <table/e-tree-model.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_SELECTION_MODEL \ - (e_tree_selection_model_get_type ()) -#define E_TREE_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_SELECTION_MODEL, ETreeSelectionModel)) -#define E_TREE_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_SELECTION_MODEL, ETreeSelectionModelClass)) -#define E_IS_TREE_SELECTION_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_SELECTION_MODEL)) -#define E_IS_TREE_SELECTION_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_SELECTION_MODEL)) -#define E_TREE_SELECTION_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_SELECTION_MODEL, ETreeSelectionModelClass)) - -G_BEGIN_DECLS - -typedef void (*ETreeForeachFunc) (ETreePath path, - gpointer closure); - -typedef struct _ETreeSelectionModel ETreeSelectionModel; -typedef struct _ETreeSelectionModelClass ETreeSelectionModelClass; -typedef struct _ETreeSelectionModelPrivate ETreeSelectionModelPrivate; - -struct _ETreeSelectionModel { - ESelectionModel parent; - ETreeSelectionModelPrivate *priv; -}; - -struct _ETreeSelectionModelClass { - ESelectionModelClass parent_class; -}; - -GType e_tree_selection_model_get_type (void) G_GNUC_CONST; -ESelectionModel * - e_tree_selection_model_new (void); -void e_tree_selection_model_foreach (ETreeSelectionModel *etsm, - ETreeForeachFunc callback, - gpointer closure); -void e_tree_selection_model_select_single_path - (ETreeSelectionModel *etsm, - ETreePath path); -void e_tree_selection_model_select_paths - (ETreeSelectionModel *etsm, - GPtrArray *paths); - -void e_tree_selection_model_add_to_selection - (ETreeSelectionModel *etsm, - ETreePath path); -void e_tree_selection_model_change_cursor - (ETreeSelectionModel *etsm, - ETreePath path); -ETreePath e_tree_selection_model_get_cursor - (ETreeSelectionModel *etsm); - -G_END_DECLS - -#endif /* _E_TREE_SELECTION_MODEL_H_ */ diff --git a/widgets/table/e-tree-sorted.c b/widgets/table/e-tree-sorted.c deleted file mode 100644 index 0b8f1c4447..0000000000 --- a/widgets/table/e-tree-sorted.c +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Adapted from the gtree code and ETableModel. - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* FIXME: Overall e-tree-sorted.c needs to be made more efficient. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> - -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-sorting-utils.h" -#include "e-tree-sorted.h" - -/* maximum insertions between an idle event that we will do without scheduling an idle sort */ -#define ETS_INSERT_MAX (4) - -#define d(x) - -#define E_TREE_SORTED_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TREE_SORTED, ETreeSortedPrivate)) - -G_DEFINE_TYPE (ETreeSorted, e_tree_sorted, E_TYPE_TREE_MODEL) - -enum { - NODE_RESORTED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0, }; - -typedef struct ETreeSortedPath ETreeSortedPath; - -struct ETreeSortedPath { - ETreePath corresponding; - - /* parent/child/sibling pointers */ - ETreeSortedPath *parent; - gint num_children; - ETreeSortedPath **children; - gint position; - gint orig_position; - - guint needs_resort : 1; - guint child_needs_resort : 1; - guint resort_all_children : 1; - guint needs_regen_to_sort : 1; -}; - -struct _ETreeSortedPrivate { - ETreeModel *source; - ETreeSortedPath *root; - - ETableSortInfo *sort_info; - ETableHeader *full_header; - - ETreeSortedPath *last_access; - - gint tree_model_pre_change_id; - gint tree_model_no_change_id; - gint tree_model_node_changed_id; - gint tree_model_node_data_changed_id; - gint tree_model_node_col_changed_id; - gint tree_model_node_inserted_id; - gint tree_model_node_removed_id; - gint tree_model_node_deleted_id; - gint tree_model_node_request_collapse_id; - - gint sort_info_changed_id; - gint sort_idle_id; - gint insert_idle_id; - gint insert_count; - - guint in_resort_idle : 1; - guint nested_resort_idle : 1; -}; - -enum { - ARG_0, - - ARG_SORT_INFO -}; - -static void ets_sort_info_changed (ETableSortInfo *sort_info, ETreeSorted *ets); -static void resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_children, gboolean needs_regen, gboolean send_signals); -static void mark_path_needs_resort (ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_rebuild, gboolean resort_all_children); -static void schedule_resort (ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_regen, gboolean resort_all_children); -static void free_path (ETreeSortedPath *path); -static void generate_children (ETreeSorted *ets, ETreeSortedPath *path); -static void regenerate_children (ETreeSorted *ets, ETreeSortedPath *path); - -/* idle callbacks */ - -static gboolean -ets_sort_idle (gpointer user_data) -{ - ETreeSorted *ets = user_data; - if (ets->priv->in_resort_idle) { - ets->priv->nested_resort_idle = TRUE; - return FALSE; - } - ets->priv->in_resort_idle = TRUE; - if (ets->priv->root) { - do { - ets->priv->nested_resort_idle = FALSE; - resort_node (ets, ets->priv->root, FALSE, FALSE, TRUE); - } while (ets->priv->nested_resort_idle); - } - ets->priv->in_resort_idle = FALSE; - ets->priv->sort_idle_id = 0; - return FALSE; -} - -#define ETS_SORT_IDLE_ACTIVATED(ets) ((ets)->priv->sort_idle_id != 0) - -inline static void -ets_stop_sort_idle (ETreeSorted *ets) -{ - if (ets->priv->sort_idle_id) { - g_source_remove (ets->priv->sort_idle_id); - ets->priv->sort_idle_id = 0; - } -} - -static gboolean -ets_insert_idle (ETreeSorted *ets) -{ - ets->priv->insert_count = 0; - ets->priv->insert_idle_id = 0; - return FALSE; -} - -/* Helper functions */ - -#define CHECK_AROUND_LAST_ACCESS - -static inline ETreeSortedPath * -check_last_access (ETreeSorted *ets, - ETreePath corresponding) -{ -#ifdef CHECK_AROUND_LAST_ACCESS - ETreeSortedPath *parent; -#endif - - if (ets->priv->last_access == NULL) - return NULL; - - if (ets->priv->last_access == corresponding) { - d (g_print ("Found last access %p at %p.", ets->priv->last_access, ets->priv->last_access)); - return ets->priv->last_access; - } - -#ifdef CHECK_AROUND_LAST_ACCESS - parent = ets->priv->last_access->parent; - if (parent && parent->children) { - gint position = ets->priv->last_access->position; - gint end = MIN (parent->num_children, position + 10); - gint start = MAX (0, position - 10); - gint initial = MAX (MIN (position, end), start); - gint i; - - for (i = initial; i < end; i++) { - if (parent->children[i] && parent->children[i]->corresponding == corresponding) { - d (g_print ("Found last access %p at %p.", ets->priv->last_access, parent->children[i])); - return parent->children[i]; - } - } - - for (i = initial - 1; i >= start; i--) { - if (parent->children[i] && parent->children[i]->corresponding == corresponding) { - d (g_print ("Found last access %p at %p.", ets->priv->last_access, parent->children[i])); - return parent->children[i]; - } - } - } -#endif - return NULL; -} - -static ETreeSortedPath * -find_path (ETreeSorted *ets, - ETreePath corresponding) -{ - gint depth; - ETreePath *sequence; - gint i; - ETreeSortedPath *path; - ETreeSortedPath *check_last; - - if (corresponding == NULL) - return NULL; - - check_last = check_last_access (ets, corresponding); - if (check_last) { - d (g_print (" (find_path)\n")); - return check_last; - } - - depth = e_tree_model_node_depth (ets->priv->source, corresponding); - - sequence = g_new (ETreePath, depth + 1); - - sequence[0] = corresponding; - - for (i = 0; i < depth; i++) - sequence[i + 1] = e_tree_model_node_get_parent (ets->priv->source, sequence[i]); - - path = ets->priv->root; - - for (i = depth - 1; i >= 0 && path != NULL; i--) { - gint j; - - if (path->num_children == -1) { - path = NULL; - break; - } - - for (j = 0; j < path->num_children; j++) { - if (path->children[j]->corresponding == sequence[i]) { - break; - } - } - - if (j < path->num_children) { - path = path->children[j]; - } else { - path = NULL; - } - } - g_free (sequence); - - d (g_print ("Didn't find last access %p. Setting to %p. (find_path)\n", ets->priv->last_access, path)); - ets->priv->last_access = path; - - return path; -} - -static ETreeSortedPath * -find_child_path (ETreeSorted *ets, - ETreeSortedPath *parent, - ETreePath corresponding) -{ - gint i; - - if (corresponding == NULL) - return NULL; - - if (parent->num_children == -1) { - return NULL; - } - - for (i = 0; i < parent->num_children; i++) - if (parent->children[i]->corresponding == corresponding) - return parent->children[i]; - - return NULL; -} - -static ETreeSortedPath * -find_or_create_path (ETreeSorted *ets, - ETreePath corresponding) -{ - gint depth; - ETreePath *sequence; - gint i; - ETreeSortedPath *path; - ETreeSortedPath *check_last; - - if (corresponding == NULL) - return NULL; - - check_last = check_last_access (ets, corresponding); - if (check_last) { - d (g_print (" (find_or_create_path)\n")); - return check_last; - } - - depth = e_tree_model_node_depth (ets->priv->source, corresponding); - - sequence = g_new (ETreePath, depth + 1); - - sequence[0] = corresponding; - - for (i = 0; i < depth; i++) - sequence[i + 1] = e_tree_model_node_get_parent (ets->priv->source, sequence[i]); - - path = ets->priv->root; - - for (i = depth - 1; i >= 0 && path != NULL; i--) { - gint j; - - if (path->num_children == -1) { - generate_children (ets, path); - } - - for (j = 0; j < path->num_children; j++) { - if (path->children[j]->corresponding == sequence[i]) { - break; - } - } - - if (j < path->num_children) { - path = path->children[j]; - } else { - path = NULL; - } - } - g_free (sequence); - - d (g_print ("Didn't find last access %p. Setting to %p. (find_or_create_path)\n", ets->priv->last_access, path)); - ets->priv->last_access = path; - - return path; -} - -static void -free_children (ETreeSortedPath *path) -{ - gint i; - - if (path == NULL) - return; - - for (i = 0; i < path->num_children; i++) { - free_path (path->children[i]); - } - - g_free (path->children); - path->children = NULL; - path->num_children = -1; -} - -static void -free_path (ETreeSortedPath *path) -{ - free_children (path); - g_slice_free (ETreeSortedPath, path); -} - -static ETreeSortedPath * -new_path (ETreeSortedPath *parent, - ETreePath corresponding) -{ - ETreeSortedPath *path; - - path = g_slice_new0 (ETreeSortedPath); - - path->corresponding = corresponding; - path->parent = parent; - path->num_children = -1; - path->children = NULL; - path->position = -1; - path->orig_position = -1; - path->child_needs_resort = 0; - path->resort_all_children = 0; - path->needs_resort = 0; - path->needs_regen_to_sort = 0; - - return path; -} - -static gboolean -reposition_path (ETreeSorted *ets, - ETreeSortedPath *path) -{ - gint new_index; - gint old_index = path->position; - ETreeSortedPath *parent = path->parent; - gboolean changed = FALSE; - if (parent) { - if (ets->priv->sort_idle_id == 0) { - if (ets->priv->insert_count > ETS_INSERT_MAX) { - /* schedule a sort, and append instead */ - schedule_resort (ets, parent, TRUE, FALSE); - } else { - /* make sure we have an idle handler to reset the count every now and then */ - if (ets->priv->insert_idle_id == 0) { - ets->priv->insert_idle_id = g_idle_add_full (40, (GSourceFunc) ets_insert_idle, ets, NULL); - } - - new_index = e_table_sorting_utils_tree_check_position - (E_TREE_MODEL (ets), - ets->priv->sort_info, - ets->priv->full_header, - (ETreePath *) parent->children, - parent->num_children, - old_index); - - if (new_index > old_index) { - gint i; - ets->priv->insert_count++; - memmove (parent->children + old_index, parent->children + old_index + 1, sizeof (ETreePath) * (new_index - old_index)); - parent->children[new_index] = path; - for (i = old_index; i <= new_index; i++) - parent->children[i]->position = i; - changed = TRUE; - e_tree_model_node_changed (E_TREE_MODEL (ets), parent); - e_tree_sorted_node_resorted (ets, parent); - } else if (new_index < old_index) { - gint i; - ets->priv->insert_count++; - memmove (parent->children + new_index + 1, parent->children + new_index, sizeof (ETreePath) * (old_index - new_index)); - parent->children[new_index] = path; - for (i = new_index; i <= old_index; i++) - parent->children[i]->position = i; - changed = TRUE; - e_tree_model_node_changed (E_TREE_MODEL (ets), parent); - e_tree_sorted_node_resorted (ets, parent); - } - } - } else - mark_path_needs_resort (ets, parent, TRUE, FALSE); - } - return changed; -} - -static void -regenerate_children (ETreeSorted *ets, - ETreeSortedPath *path) -{ - ETreeSortedPath **children; - gint i; - - children = g_new (ETreeSortedPath *, path->num_children); - for (i = 0; i < path->num_children; i++) - children[path->children[i]->orig_position] = path->children[i]; - g_free (path->children); - path->children = children; -} - -static void -generate_children (ETreeSorted *ets, - ETreeSortedPath *path) -{ - ETreePath child; - gint i; - gint count; - - free_children (path); - - count = 0; - for (child = e_tree_model_node_get_first_child (ets->priv->source, path->corresponding); - child; - child = e_tree_model_node_get_next (ets->priv->source, child)) { - count++; - } - - path->num_children = count; - path->children = g_new (ETreeSortedPath *, count); - for (child = e_tree_model_node_get_first_child (ets->priv->source, path->corresponding), i = 0; - child; - child = e_tree_model_node_get_next (ets->priv->source, child), i++) { - path->children[i] = new_path (path, child); - path->children[i]->position = i; - path->children[i]->orig_position = i; - } - if (path->num_children > 0) - schedule_resort (ets, path, FALSE, TRUE); -} - -static void -resort_node (ETreeSorted *ets, - ETreeSortedPath *path, - gboolean resort_all_children, - gboolean needs_regen, - gboolean send_signals) -{ - gboolean needs_resort; - if (path) { - needs_resort = path->needs_resort || resort_all_children; - needs_regen = path->needs_regen_to_sort || needs_regen; - if (path->num_children > 0) { - if (needs_resort && send_signals) - e_tree_model_pre_change (E_TREE_MODEL (ets)); - if (needs_resort) { - gint i; - d (g_print ("Start sort of node %p\n", path)); - if (needs_regen) - regenerate_children (ets, path); - d (g_print ("Regened sort of node %p\n", path)); - e_table_sorting_utils_tree_sort ( - E_TREE_MODEL (ets), - ets->priv->sort_info, - ets->priv->full_header, - (ETreePath *) path->children, - path->num_children); - d (g_print ("Renumbering sort of node %p\n", path)); - for (i = 0; i < path->num_children; i++) { - path->children[i]->position = i; - } - d (g_print ("End sort of node %p\n", path)); - } - if (path->resort_all_children) - resort_all_children = TRUE; - if ((resort_all_children || path->child_needs_resort) && path->num_children >= 0) { - gint i; - for (i = 0; i < path->num_children; i++) { - resort_node (ets, path->children[i], resort_all_children, needs_regen, send_signals && !needs_resort); - } - path->child_needs_resort = 0; - } - } - path->needs_resort = 0; - path->child_needs_resort = 0; - path->needs_regen_to_sort = 0; - path->resort_all_children = 0; - if (needs_resort && send_signals && path->num_children > 0) { - e_tree_model_node_changed (E_TREE_MODEL (ets), path); - e_tree_sorted_node_resorted (ets, path); - } - } -} - -static void -mark_path_child_needs_resort (ETreeSorted *ets, - ETreeSortedPath *path) -{ - if (path == NULL) - return; - if (!path->child_needs_resort) { - path->child_needs_resort = 1; - mark_path_child_needs_resort (ets, path->parent); - } -} - -static void -mark_path_needs_resort (ETreeSorted *ets, - ETreeSortedPath *path, - gboolean needs_regen, - gboolean resort_all_children) -{ - if (path == NULL) - return; - if (path->num_children == 0) - return; - path->needs_resort = 1; - path->needs_regen_to_sort = needs_regen; - path->resort_all_children = resort_all_children; - mark_path_child_needs_resort (ets, path->parent); -} - -static void -schedule_resort (ETreeSorted *ets, - ETreeSortedPath *path, - gboolean needs_regen, - gboolean resort_all_children) -{ - ets->priv->insert_count = 0; - if (ets->priv->insert_idle_id != 0) { - g_source_remove (ets->priv->insert_idle_id); - ets->priv->insert_idle_id = 0; - } - - if (path == NULL) - return; - if (path->num_children == 0) - return; - - mark_path_needs_resort (ets, path, needs_regen, resort_all_children); - if (ets->priv->sort_idle_id == 0) { - ets->priv->sort_idle_id = g_idle_add_full (50, (GSourceFunc) ets_sort_idle, ets, NULL); - } else if (ets->priv->in_resort_idle) { - ets->priv->nested_resort_idle = TRUE; - } -} - -/* virtual methods */ - -static void -ets_dispose (GObject *object) -{ - ETreeSortedPrivate *priv; - - priv = E_TREE_SORTED_GET_PRIVATE (object); - - if (priv->source) { - g_signal_handler_disconnect ( - priv->source, priv->tree_model_pre_change_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_no_change_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_data_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_col_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_inserted_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_removed_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_deleted_id); - g_signal_handler_disconnect ( - priv->source, priv->tree_model_node_request_collapse_id); - - g_object_unref (priv->source); - priv->source = NULL; - - priv->tree_model_pre_change_id = 0; - priv->tree_model_no_change_id = 0; - priv->tree_model_node_changed_id = 0; - priv->tree_model_node_data_changed_id = 0; - priv->tree_model_node_col_changed_id = 0; - priv->tree_model_node_inserted_id = 0; - priv->tree_model_node_removed_id = 0; - priv->tree_model_node_deleted_id = 0; - priv->tree_model_node_request_collapse_id = 0; - } - - if (priv->sort_info) { - g_signal_handler_disconnect ( - priv->sort_info, priv->sort_info_changed_id); - priv->sort_info_changed_id = 0; - - g_object_unref (priv->sort_info); - priv->sort_info = NULL; - } - - ets_stop_sort_idle (E_TREE_SORTED (object)); - - if (priv->insert_idle_id) { - g_source_remove (priv->insert_idle_id); - priv->insert_idle_id = 0; - } - - if (priv->full_header) { - g_object_unref (priv->full_header); - priv->full_header = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_tree_sorted_parent_class)->dispose (object); -} - -static void -ets_finalize (GObject *object) -{ - ETreeSortedPrivate *priv; - - priv = E_TREE_SORTED_GET_PRIVATE (object); - - if (priv->root) - free_path (priv->root); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_tree_sorted_parent_class)->finalize (object); -} - -static ETreePath -ets_get_root (ETreeModel *etm) -{ - ETreeSortedPrivate *priv = E_TREE_SORTED (etm)->priv; - if (priv->root == NULL) { - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreePath corresponding = e_tree_model_get_root (ets->priv->source); - - if (corresponding) { - priv->root = new_path (NULL, corresponding); - } - } - if (priv->root && priv->root->num_children == -1) { - generate_children (E_TREE_SORTED (etm), priv->root); - } - - return priv->root; -} - -static ETreePath -ets_get_parent (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - return path->parent; -} - -static ETreePath -ets_get_first_child (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - - if (path->num_children == -1) - generate_children (ets, path); - - if (path->num_children > 0) - return path->children[0]; - else - return NULL; -} - -static ETreePath -ets_get_last_child (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - - if (path->num_children == -1) - generate_children (ets, path); - - if (path->num_children > 0) - return path->children[path->num_children - 1]; - else - return NULL; -} - -static ETreePath -ets_get_next (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSortedPath *parent = path->parent; - if (parent) { - if (parent->num_children > path->position + 1) - return parent->children[path->position + 1]; - else - return NULL; - } else - return NULL; -} - -static ETreePath -ets_get_prev (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSortedPath *parent = path->parent; - if (parent) { - if (path->position - 1 >= 0) - return parent->children[path->position - 1]; - else - return NULL; - } else - return NULL; -} - -static gboolean -ets_is_root (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_node_is_root (ets->priv->source, path->corresponding); -} - -static gboolean -ets_is_expandable (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - gboolean expandable = e_tree_model_node_is_expandable (ets->priv->source, path->corresponding); - - if (path->num_children == -1) { - generate_children (ets, node); - } - - return expandable; -} - -static guint -ets_get_children (ETreeModel *etm, - ETreePath node, - ETreePath **nodes) -{ - ETreeSortedPath *path = node; - guint n_children; - - if (path->num_children == -1) { - generate_children (E_TREE_SORTED (etm), node); - } - - n_children = path->num_children; - - if (nodes) { - gint i; - - (*nodes) = g_malloc (sizeof (ETreePath) * n_children); - for (i = 0; i < n_children; i++) { - (*nodes)[i] = path->children[i]; - } - } - - return n_children; -} - -static guint -ets_depth (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_node_depth (ets->priv->source, path->corresponding); -} - -static GdkPixbuf * -ets_icon_at (ETreeModel *etm, - ETreePath node) -{ - ETreeSortedPath *path = node; - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_icon_at (ets->priv->source, path->corresponding); -} - -static gboolean -ets_get_expanded_default (ETreeModel *etm) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_get_expanded_default (ets->priv->source); -} - -static gint -ets_column_count (ETreeModel *etm) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_column_count (ets->priv->source); -} - -static gboolean -ets_has_save_id (ETreeModel *etm) -{ - return TRUE; -} - -static gchar * -ets_get_save_id (ETreeModel *etm, - ETreePath node) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreeSortedPath *path = node; - - if (e_tree_model_has_save_id (ets->priv->source)) - return e_tree_model_get_save_id (ets->priv->source, path->corresponding); - else - return g_strdup_printf ("%p", path->corresponding); -} - -static gboolean -ets_has_get_node_by_id (ETreeModel *etm) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - return e_tree_model_has_get_node_by_id (ets->priv->source); -} - -static ETreePath -ets_get_node_by_id (ETreeModel *etm, - const gchar *save_id) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreePath node; - - node = e_tree_model_get_node_by_id (ets->priv->source, save_id); - - return find_path (ets, node); -} - -static gboolean -ets_has_change_pending (ETreeModel *etm) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return ets->priv->sort_idle_id != 0; -} - -static gpointer -ets_value_at (ETreeModel *etm, - ETreePath node, - gint col) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreeSortedPath *path = node; - - return e_tree_model_value_at (ets->priv->source, path->corresponding, col); -} - -static void -ets_set_value_at (ETreeModel *etm, - ETreePath node, - gint col, - gconstpointer val) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreeSortedPath *path = node; - - e_tree_model_set_value_at (ets->priv->source, path->corresponding, col, val); -} - -static gboolean -ets_is_editable (ETreeModel *etm, - ETreePath node, - gint col) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - ETreeSortedPath *path = node; - - return e_tree_model_node_is_editable (ets->priv->source, path->corresponding, col); -} - -/* The default for ets_duplicate_value is to return the raw value. */ -static gpointer -ets_duplicate_value (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_duplicate_value (ets->priv->source, col, value); -} - -static void -ets_free_value (ETreeModel *etm, - gint col, - gpointer value) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - e_tree_model_free_value (ets->priv->source, col, value); -} - -static gpointer -ets_initialize_value (ETreeModel *etm, - gint col) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_initialize_value (ets->priv->source, col); -} - -static gboolean -ets_value_is_empty (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_value_is_empty (ets->priv->source, col, value); -} - -static gchar * -ets_value_to_string (ETreeModel *etm, - gint col, - gconstpointer value) -{ - ETreeSorted *ets = E_TREE_SORTED (etm); - - return e_tree_model_value_to_string (ets->priv->source, col, value); -} - -/* Proxy functions */ - -static void -ets_proxy_pre_change (ETreeModel *etm, - ETreeSorted *ets) -{ - e_tree_model_pre_change (E_TREE_MODEL (ets)); -} - -static void -ets_proxy_no_change (ETreeModel *etm, - ETreeSorted *ets) -{ - e_tree_model_no_change (E_TREE_MODEL (ets)); -} - -static void -ets_proxy_node_changed (ETreeModel *etm, - ETreePath node, - ETreeSorted *ets) -{ - ets->priv->last_access = NULL; - d (g_print ("Setting last access %p. (ets_proxy_node_changed)\n", ets->priv->last_access)); - - if (e_tree_model_node_is_root (ets->priv->source, node)) { - ets_stop_sort_idle (ets); - - if (ets->priv->root) { - free_path (ets->priv->root); - } - ets->priv->root = new_path (NULL, node); - e_tree_model_node_changed (E_TREE_MODEL (ets), ets->priv->root); - return; - } else { - ETreeSortedPath *path = find_path (ets, node); - - if (path) { - free_children (path); - if (!reposition_path (ets, path)) { - e_tree_model_node_changed (E_TREE_MODEL (ets), path); - } else { - e_tree_model_no_change (E_TREE_MODEL (ets)); - } - } else { - e_tree_model_no_change (E_TREE_MODEL (ets)); - } - } -} - -static void -ets_proxy_node_data_changed (ETreeModel *etm, - ETreePath node, - ETreeSorted *ets) -{ - ETreeSortedPath *path = find_path (ets, node); - - if (path) { - if (!reposition_path (ets, path)) - e_tree_model_node_data_changed (E_TREE_MODEL (ets), path); - else - e_tree_model_no_change (E_TREE_MODEL (ets)); - } else - e_tree_model_no_change (E_TREE_MODEL (ets)); -} - -static void -ets_proxy_node_col_changed (ETreeModel *etm, - ETreePath node, - gint col, - ETreeSorted *ets) -{ - ETreeSortedPath *path = find_path (ets, node); - - if (path) { - gboolean changed = FALSE; - if (e_table_sorting_utils_affects_sort (ets->priv->sort_info, ets->priv->full_header, col)) - changed = reposition_path (ets, path); - if (!changed) - e_tree_model_node_col_changed (E_TREE_MODEL (ets), path, col); - else - e_tree_model_no_change (E_TREE_MODEL (ets)); - } else - e_tree_model_no_change (E_TREE_MODEL (ets)); -} - -static void -ets_proxy_node_inserted (ETreeModel *etm, - ETreePath parent, - ETreePath child, - ETreeSorted *ets) -{ - ETreeSortedPath *parent_path = find_path (ets, parent); - - if (parent_path && parent_path->num_children != -1) { - gint i; - gint j; - ETreeSortedPath *path; - gint position = parent_path->num_children; - ETreePath counter; - - for (counter = e_tree_model_node_get_next (etm, child); - counter; - counter = e_tree_model_node_get_next (etm, counter)) - position--; - - if (position != parent_path->num_children) { - for (i = 0; i < parent_path->num_children; i++) { - if (parent_path->children[i]->orig_position >= position) - parent_path->children[i]->orig_position++; - } - } - - i = parent_path->num_children; - path = new_path (parent_path, child); - path->orig_position = position; - if (!ETS_SORT_IDLE_ACTIVATED (ets)) { - ets->priv->insert_count++; - if (ets->priv->insert_count > ETS_INSERT_MAX) { - /* schedule a sort, and append instead */ - schedule_resort (ets, parent_path, TRUE, FALSE); - } else { - /* make sure we have an idle handler to reset the count every now and then */ - if (ets->priv->insert_idle_id == 0) { - ets->priv->insert_idle_id = g_idle_add_full (40, (GSourceFunc) ets_insert_idle, ets, NULL); - } - i = e_table_sorting_utils_tree_insert - (ets->priv->source, - ets->priv->sort_info, - ets->priv->full_header, - (ETreePath *) parent_path->children, - parent_path->num_children, - path); - } - } else { - mark_path_needs_resort (ets, parent_path, TRUE, FALSE); - } - parent_path->num_children++; - parent_path->children = g_renew (ETreeSortedPath *, parent_path->children, parent_path->num_children); - memmove (parent_path->children + i + 1, parent_path->children + i, (parent_path->num_children - 1 - i) * sizeof (gint)); - parent_path->children[i] = path; - for (j = i; j < parent_path->num_children; j++) { - parent_path->children[j]->position = j; - } - e_tree_model_node_inserted (E_TREE_MODEL (ets), parent_path, parent_path->children[i]); - } else if (ets->priv->root == NULL && parent == NULL) { - if (child) { - ets->priv->root = new_path (NULL, child); - e_tree_model_node_inserted (E_TREE_MODEL (ets), NULL, ets->priv->root); - } else { - e_tree_model_no_change (E_TREE_MODEL (ets)); - } - } else { - e_tree_model_no_change (E_TREE_MODEL (ets)); - } -} - -static void -ets_proxy_node_removed (ETreeModel *etm, - ETreePath parent, - ETreePath child, - gint old_position, - ETreeSorted *ets) -{ - ETreeSortedPath *parent_path = find_path (ets, parent); - ETreeSortedPath *path; - - if (parent_path) - path = find_child_path (ets, parent_path, child); - else - path = find_path (ets, child); - - d (g_print ("Setting last access %p. (ets_proxy_node_removed)\n ", ets->priv->last_access)); - ets->priv->last_access = NULL; - - if (path && parent_path && parent_path->num_children != -1) { - gint i; - for (i = 0; i < parent_path->num_children; i++) { - if (parent_path->children[i]->orig_position > old_position) - parent_path->children[i]->orig_position--; - } - - i = path->position; - - parent_path->num_children--; - memmove (parent_path->children + i, parent_path->children + i + 1, sizeof (ETreeSortedPath *) * (parent_path->num_children - i)); - for (; i < parent_path->num_children; i++) { - parent_path->children[i]->position = i; - } - e_tree_model_node_removed (E_TREE_MODEL (ets), parent_path, path, path->position); - free_path (path); - } else if (path && path == ets->priv->root) { - ets->priv->root = NULL; - e_tree_model_node_removed (E_TREE_MODEL (ets), NULL, path, -1); - free_path (path); - } -} - -static void -ets_proxy_node_deleted (ETreeModel *etm, - ETreePath child, - ETreeSorted *ets) -{ - e_tree_model_node_deleted (E_TREE_MODEL (ets), NULL); -} - -static void -ets_proxy_node_request_collapse (ETreeModel *etm, - ETreePath node, - ETreeSorted *ets) -{ - ETreeSortedPath *path = find_path (ets, node); - if (path) { - e_tree_model_node_request_collapse (E_TREE_MODEL (ets), path); - } -} - -static void -ets_sort_info_changed (ETableSortInfo *sort_info, - ETreeSorted *ets) -{ - schedule_resort (ets, ets->priv->root, TRUE, TRUE); -} - -/* Initialization and creation */ - -static void -e_tree_sorted_class_init (ETreeSortedClass *class) -{ - GObjectClass *object_class; - ETreeModelClass *tree_model_class; - - g_type_class_add_private (class, sizeof (ETreeSortedPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = ets_dispose; - object_class->finalize = ets_finalize; - - tree_model_class = E_TREE_MODEL_CLASS (class); - tree_model_class->get_root = ets_get_root; - tree_model_class->get_parent = ets_get_parent; - tree_model_class->get_first_child = ets_get_first_child; - tree_model_class->get_last_child = ets_get_last_child; - tree_model_class->get_prev = ets_get_prev; - tree_model_class->get_next = ets_get_next; - - tree_model_class->is_root = ets_is_root; - tree_model_class->is_expandable = ets_is_expandable; - tree_model_class->get_children = ets_get_children; - tree_model_class->depth = ets_depth; - - tree_model_class->icon_at = ets_icon_at; - - tree_model_class->get_expanded_default = ets_get_expanded_default; - tree_model_class->column_count = ets_column_count; - - tree_model_class->has_save_id = ets_has_save_id; - tree_model_class->get_save_id = ets_get_save_id; - - tree_model_class->has_get_node_by_id = ets_has_get_node_by_id; - tree_model_class->get_node_by_id = ets_get_node_by_id; - - tree_model_class->has_change_pending = ets_has_change_pending; - - tree_model_class->value_at = ets_value_at; - tree_model_class->set_value_at = ets_set_value_at; - tree_model_class->is_editable = ets_is_editable; - - tree_model_class->duplicate_value = ets_duplicate_value; - tree_model_class->free_value = ets_free_value; - tree_model_class->initialize_value = ets_initialize_value; - tree_model_class->value_is_empty = ets_value_is_empty; - tree_model_class->value_to_string = ets_value_to_string; - - signals[NODE_RESORTED] = g_signal_new ( - "node_resorted", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeSortedClass, node_resorted), - (GSignalAccumulator) NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); -} - -static void -e_tree_sorted_init (ETreeSorted *ets) -{ - ets->priv = E_TREE_SORTED_GET_PRIVATE (ets); -} - -/** - * e_tree_sorted_construct: - * @etree: - * - * - **/ -void -e_tree_sorted_construct (ETreeSorted *ets, - ETreeModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info) -{ - ets->priv->source = source; - if (source) - g_object_ref (source); - - ets->priv->full_header = full_header; - if (full_header) - g_object_ref (full_header); - - e_tree_sorted_set_sort_info (ets, sort_info); - - ets->priv->tree_model_pre_change_id = g_signal_connect ( - source, "pre_change", - G_CALLBACK (ets_proxy_pre_change), ets); - ets->priv->tree_model_no_change_id = g_signal_connect ( - source, "no_change", - G_CALLBACK (ets_proxy_no_change), ets); - ets->priv->tree_model_node_changed_id = g_signal_connect ( - source, "node_changed", - G_CALLBACK (ets_proxy_node_changed), ets); - ets->priv->tree_model_node_data_changed_id = g_signal_connect ( - source, "node_data_changed", - G_CALLBACK (ets_proxy_node_data_changed), ets); - ets->priv->tree_model_node_col_changed_id = g_signal_connect ( - source, "node_col_changed", - G_CALLBACK (ets_proxy_node_col_changed), ets); - ets->priv->tree_model_node_inserted_id = g_signal_connect ( - source, "node_inserted", - G_CALLBACK (ets_proxy_node_inserted), ets); - ets->priv->tree_model_node_removed_id = g_signal_connect ( - source, "node_removed", - G_CALLBACK (ets_proxy_node_removed), ets); - ets->priv->tree_model_node_deleted_id = g_signal_connect ( - source, "node_deleted", - G_CALLBACK (ets_proxy_node_deleted), ets); - ets->priv->tree_model_node_request_collapse_id = g_signal_connect ( - source, "node_request_collapse", - G_CALLBACK (ets_proxy_node_request_collapse), ets); - -} - -/** - * e_tree_sorted_new - * - * FIXME docs here. - * - * return values: a newly constructed ETreeSorted. - */ -ETreeSorted * -e_tree_sorted_new (ETreeModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info) -{ - ETreeSorted *ets = g_object_new (E_TYPE_TREE_SORTED, NULL); - - e_tree_sorted_construct (ets, source, full_header, sort_info); - - return ets; -} - -ETreePath -e_tree_sorted_view_to_model_path (ETreeSorted *ets, - ETreePath view_path) -{ - ETreeSortedPath *path = view_path; - if (path) { - ets->priv->last_access = path; - d (g_print ("Setting last access %p. (e_tree_sorted_view_to_model_path)\n", ets->priv->last_access)); - return path->corresponding; - } else - return NULL; -} - -ETreePath -e_tree_sorted_model_to_view_path (ETreeSorted *ets, - ETreePath model_path) -{ - return find_or_create_path (ets, model_path); -} - -gint -e_tree_sorted_orig_position (ETreeSorted *ets, - ETreePath path) -{ - ETreeSortedPath *sorted_path = path; - return sorted_path->orig_position; -} - -gint -e_tree_sorted_node_num_children (ETreeSorted *ets, - ETreePath path) -{ - ETreeSortedPath *sorted_path = path; - - if (sorted_path->num_children == -1) { - generate_children (ets, sorted_path); - } - - return sorted_path->num_children; -} - -void -e_tree_sorted_node_resorted (ETreeSorted *sorted, - ETreePath node) -{ - g_return_if_fail (sorted != NULL); - g_return_if_fail (E_IS_TREE_SORTED (sorted)); - - g_signal_emit (sorted, signals[NODE_RESORTED], 0, node); -} - -void -e_tree_sorted_set_sort_info (ETreeSorted *ets, - ETableSortInfo *sort_info) -{ - - g_return_if_fail (ets != NULL); - - if (ets->priv->sort_info) { - if (ets->priv->sort_info_changed_id != 0) - g_signal_handler_disconnect ( - ets->priv->sort_info, - ets->priv->sort_info_changed_id); - ets->priv->sort_info_changed_id = 0; - g_object_unref (ets->priv->sort_info); - } - - ets->priv->sort_info = sort_info; - if (sort_info) { - g_object_ref (sort_info); - ets->priv->sort_info_changed_id = g_signal_connect ( - ets->priv->sort_info, "sort_info_changed", - G_CALLBACK (ets_sort_info_changed), ets); - } - - if (ets->priv->root) - schedule_resort (ets, ets->priv->root, TRUE, TRUE); -} - -ETableSortInfo * -e_tree_sorted_get_sort_info (ETreeSorted *ets) -{ - return ets->priv->sort_info; -} - diff --git a/widgets/table/e-tree-sorted.h b/widgets/table/e-tree-sorted.h deleted file mode 100644 index 456ee15d14..0000000000 --- a/widgets/table/e-tree-sorted.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_SORTED_H_ -#define _E_TREE_SORTED_H_ - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <table/e-tree-model.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_SORTED \ - (e_tree_sorted_get_type ()) -#define E_TREE_SORTED(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_SORTED, ETreeSorted)) -#define E_TREE_SORTED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_SORTED, ETreeSortedClass)) -#define E_IS_TREE_SORTED(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_SORTED)) -#define E_IS_TREE_SORTED_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_SORTED)) -#define E_TREE_SORTED_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_SORTED, ETreeSortedClass)) - -G_BEGIN_DECLS - -typedef struct _ETreeSorted ETreeSorted; -typedef struct _ETreeSortedClass ETreeSortedClass; -typedef struct _ETreeSortedPrivate ETreeSortedPrivate; - -struct _ETreeSorted { - ETreeModel parent; - ETreeSortedPrivate *priv; -}; - -struct _ETreeSortedClass { - ETreeModelClass parent_class; - - /* Signals */ - void (*node_resorted) (ETreeSorted *etm, - ETreePath node); -}; - -GType e_tree_sorted_get_type (void) G_GNUC_CONST; -void e_tree_sorted_construct (ETreeSorted *etree, - ETreeModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info); -ETreeSorted * e_tree_sorted_new (ETreeModel *source, - ETableHeader *full_header, - ETableSortInfo *sort_info); - -ETreePath e_tree_sorted_view_to_model_path - (ETreeSorted *ets, - ETreePath view_path); -ETreePath e_tree_sorted_model_to_view_path - (ETreeSorted *ets, - ETreePath model_path); -gint e_tree_sorted_orig_position (ETreeSorted *ets, - ETreePath path); -gint e_tree_sorted_node_num_children (ETreeSorted *ets, - ETreePath path); - -void e_tree_sorted_node_resorted (ETreeSorted *tree_model, - ETreePath node); - -ETableSortInfo *e_tree_sorted_get_sort_info (ETreeSorted *tree_model); -void e_tree_sorted_set_sort_info (ETreeSorted *tree_model, - ETableSortInfo *sort_info); - -G_END_DECLS - -#endif /* _E_TREE_SORTED_H */ diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c deleted file mode 100644 index c610039c83..0000000000 --- a/widgets/table/e-tree-table-adapter.c +++ /dev/null @@ -1,1413 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <glib/gstdio.h> -#include <libxml/tree.h> -#include <libxml/parser.h> - -#include <libedataserver/libedataserver.h> - -#include "e-util/e-util.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-table-sorting-utils.h" -#include "e-tree-table-adapter.h" - -#define E_TREE_TABLE_ADAPTER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TREE_TABLE_ADAPTER, ETreeTableAdapterPrivate)) - -/* workaround for avoiding API breakage */ -#define etta_get_type e_tree_table_adapter_get_type -G_DEFINE_TYPE (ETreeTableAdapter, etta, E_TYPE_TABLE_MODEL) -#define d(x) - -#define INCREMENT_AMOUNT 100 - -enum { - SORTING_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -typedef struct { - ETreePath path; - guint32 num_visible_children; - guint32 index; - - guint expanded : 1; - guint expandable : 1; - guint expandable_set : 1; -} node_t; - -struct _ETreeTableAdapterPrivate { - ETreeModel *source; - ETableSortInfo *sort_info; - ETableHeader *header; - - gint n_map; - gint n_vals_allocated; - node_t **map_table; - GHashTable *nodes; - GNode *root; - - guint root_visible : 1; - guint remap_needed : 1; - - gint last_access; - - gint pre_change_id; - gint no_change_id; - gint rebuilt_id; - gint node_changed_id; - gint node_data_changed_id; - gint node_col_changed_id; - gint node_inserted_id; - gint node_removed_id; - gint node_request_collapse_id; - gint sort_info_changed_id; - - guint resort_idle_id; - - gint force_expanded_state; /* use this instead of model's default if not 0; <0 ... collapse, >0 ... expand */ -}; - -static void etta_sort_info_changed (ETableSortInfo *sort_info, ETreeTableAdapter *etta); - -static GNode * -lookup_gnode (ETreeTableAdapter *etta, - ETreePath path) -{ - GNode *gnode; - - if (!path) - return NULL; - - gnode = g_hash_table_lookup (etta->priv->nodes, path); - - return gnode; -} - -static void -resize_map (ETreeTableAdapter *etta, - gint size) -{ - if (size > etta->priv->n_vals_allocated) { - etta->priv->n_vals_allocated = MAX (etta->priv->n_vals_allocated + INCREMENT_AMOUNT, size); - etta->priv->map_table = g_renew (node_t *, etta->priv->map_table, etta->priv->n_vals_allocated); - } - - etta->priv->n_map = size; -} - -static void -move_map_elements (ETreeTableAdapter *etta, - gint to, - gint from, - gint count) -{ - if (count <= 0 || from >= etta->priv->n_map) - return; - memmove (etta->priv->map_table + to, etta->priv->map_table + from, count * sizeof (node_t *)); - etta->priv->remap_needed = TRUE; -} - -static gint -fill_map (ETreeTableAdapter *etta, - gint index, - GNode *gnode) -{ - GNode *p; - - if ((gnode != etta->priv->root) || etta->priv->root_visible) - etta->priv->map_table[index++] = gnode->data; - - for (p = gnode->children; p; p = p->next) - index = fill_map (etta, index, p); - - etta->priv->remap_needed = TRUE; - return index; -} - -static void -remap_indices (ETreeTableAdapter *etta) -{ - gint i; - for (i = 0; i < etta->priv->n_map; i++) - etta->priv->map_table[i]->index = i; - etta->priv->remap_needed = FALSE; -} - -static node_t * -get_node (ETreeTableAdapter *etta, - ETreePath path) -{ - GNode *gnode = lookup_gnode (etta, path); - - if (!gnode) - return NULL; - - return (node_t *) gnode->data; -} - -static void -resort_node (ETreeTableAdapter *etta, - GNode *gnode, - gboolean recurse) -{ - node_t *node = (node_t *) gnode->data; - ETreePath *paths, path; - GNode *prev, *curr; - gint i, count; - gboolean sort_needed; - - if (node->num_visible_children == 0) - return; - - sort_needed = etta->priv->sort_info && e_table_sort_info_sorting_get_count (etta->priv->sort_info) > 0; - - for (i = 0, path = e_tree_model_node_get_first_child (etta->priv->source, node->path); path; - path = e_tree_model_node_get_next (etta->priv->source, path), i++); - - count = i; - if (count <= 1) - return; - - paths = g_new0 (ETreePath, count); - - for (i = 0, path = e_tree_model_node_get_first_child (etta->priv->source, node->path); path; - path = e_tree_model_node_get_next (etta->priv->source, path), i++) - paths[i] = path; - - if (count > 1 && sort_needed) - e_table_sorting_utils_tree_sort (etta->priv->source, etta->priv->sort_info, etta->priv->header, paths, count); - - prev = NULL; - for (i = 0; i < count; i++) { - curr = lookup_gnode (etta, paths[i]); - if (!curr) - continue; - - if (prev) - prev->next = curr; - else - gnode->children = curr; - - curr->prev = prev; - curr->next = NULL; - prev = curr; - if (recurse) - resort_node (etta, curr, recurse); - } - - g_free (paths); -} - -static gint -get_row (ETreeTableAdapter *etta, - ETreePath path) -{ - node_t *node = get_node (etta, path); - if (!node) - return -1; - - if (etta->priv->remap_needed) - remap_indices (etta); - - return node->index; -} - -static ETreePath -get_path (ETreeTableAdapter *etta, - gint row) -{ - if (row == -1 && etta->priv->n_map > 0) - row = etta->priv->n_map - 1; - else if (row < 0 || row >= etta->priv->n_map) - return NULL; - - return etta->priv->map_table[row]->path; -} - -static void -kill_gnode (GNode *node, - ETreeTableAdapter *etta) -{ - g_hash_table_remove (etta->priv->nodes, ((node_t *) node->data)->path); - - while (node->children) { - GNode *next = node->children->next; - kill_gnode (node->children, etta); - node->children = next; - } - - g_free (node->data); - if (node == etta->priv->root) - etta->priv->root = NULL; - g_node_destroy (node); -} - -static void -update_child_counts (GNode *gnode, - gint delta) -{ - while (gnode) { - node_t *node = (node_t *) gnode->data; - node->num_visible_children += delta; - gnode = gnode->parent; - } -} - -static gint -delete_children (ETreeTableAdapter *etta, - GNode *gnode) -{ - node_t *node = (node_t *) gnode->data; - gint to_remove = node ? node->num_visible_children : 0; - - if (to_remove == 0) - return 0; - - while (gnode->children) { - GNode *next = gnode->children->next; - kill_gnode (gnode->children, etta); - gnode->children = next; - } - - return to_remove; -} - -static void -delete_node (ETreeTableAdapter *etta, - ETreePath parent, - ETreePath path) -{ - gint to_remove = 1; - gint parent_row = get_row (etta, parent); - gint row = get_row (etta, path); - GNode *gnode = lookup_gnode (etta, path); - GNode *parent_gnode = lookup_gnode (etta, parent); - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - - if (row == -1) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - - to_remove += delete_children (etta, gnode); - kill_gnode (gnode, etta); - - move_map_elements (etta, row, row + to_remove, etta->priv->n_map - row - to_remove); - resize_map (etta, etta->priv->n_map - to_remove); - - if (parent_gnode != NULL) { - node_t *parent_node = parent_gnode->data; - gboolean expandable = e_tree_model_node_is_expandable (etta->priv->source, parent); - - update_child_counts (parent_gnode, - to_remove); - if (parent_node->expandable != expandable) { - e_table_model_pre_change (E_TABLE_MODEL (etta)); - parent_node->expandable = expandable; - e_table_model_row_changed (E_TABLE_MODEL (etta), parent_row); - } - - resort_node (etta, parent_gnode, FALSE); - } - - e_table_model_rows_deleted (E_TABLE_MODEL (etta), row, to_remove); -} - -static GNode * -create_gnode (ETreeTableAdapter *etta, - ETreePath path) -{ - GNode *gnode; - node_t *node; - - node = g_new0 (node_t, 1); - node->path = path; - node->index = -1; - node->expanded = etta->priv->force_expanded_state == 0 ? e_tree_model_get_expanded_default (etta->priv->source) : etta->priv->force_expanded_state > 0; - node->expandable = e_tree_model_node_is_expandable (etta->priv->source, path); - node->expandable_set = 1; - node->num_visible_children = 0; - gnode = g_node_new (node); - g_hash_table_insert (etta->priv->nodes, path, gnode); - return gnode; -} - -static gint -insert_children (ETreeTableAdapter *etta, - GNode *gnode) -{ - ETreePath path, tmp; - gint count = 0; - gint pos = 0; - - path = ((node_t *) gnode->data)->path; - for (tmp = e_tree_model_node_get_first_child (etta->priv->source, path); - tmp; - tmp = e_tree_model_node_get_next (etta->priv->source, tmp), pos++) { - GNode *child = create_gnode (etta, tmp); - node_t *node = (node_t *) child->data; - if (node->expanded) - node->num_visible_children = insert_children (etta, child); - g_node_prepend (gnode, child); - count += node->num_visible_children + 1; - } - g_node_reverse_children (gnode); - return count; -} - -static void -generate_tree (ETreeTableAdapter *etta, - ETreePath path) -{ - GNode *gnode; - node_t *node; - gint size; - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - - g_return_if_fail (e_tree_model_node_is_root (etta->priv->source, path)); - - if (etta->priv->root) - kill_gnode (etta->priv->root, etta); - resize_map (etta, 0); - - gnode = create_gnode (etta, path); - node = (node_t *) gnode->data; - node->expanded = TRUE; - node->num_visible_children = insert_children (etta, gnode); - if (etta->priv->sort_info && e_table_sort_info_sorting_get_count (etta->priv->sort_info) > 0) - resort_node (etta, gnode, TRUE); - - etta->priv->root = gnode; - size = etta->priv->root_visible ? node->num_visible_children + 1 : node->num_visible_children; - resize_map (etta, size); - fill_map (etta, 0, gnode); - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -static void -insert_node (ETreeTableAdapter *etta, - ETreePath parent, - ETreePath path) -{ - GNode *gnode, *parent_gnode; - node_t *node, *parent_node; - gboolean expandable; - gint size, row; - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - - if (get_node (etta, path)) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - - parent_gnode = lookup_gnode (etta, parent); - if (!parent_gnode) { - ETreePath grandparent = e_tree_model_node_get_parent (etta->priv->source, parent); - if (e_tree_model_node_is_root (etta->priv->source, parent)) - generate_tree (etta, parent); - else - insert_node (etta, grandparent, parent); - e_table_model_changed (E_TABLE_MODEL (etta)); - return; - } - - parent_node = (node_t *) parent_gnode->data; - - if (parent_gnode != etta->priv->root) { - expandable = e_tree_model_node_is_expandable (etta->priv->source, parent); - if (parent_node->expandable != expandable) { - e_table_model_pre_change (E_TABLE_MODEL (etta)); - parent_node->expandable = expandable; - parent_node->expandable_set = 1; - e_table_model_row_changed (E_TABLE_MODEL (etta), parent_node->index); - } - } - - if (!e_tree_table_adapter_node_is_expanded (etta, parent)) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - - gnode = create_gnode (etta, path); - node = (node_t *) gnode->data; - - if (node->expanded) - node->num_visible_children = insert_children (etta, gnode); - - g_node_append (parent_gnode, gnode); - update_child_counts (parent_gnode, node->num_visible_children + 1); - resort_node (etta, parent_gnode, FALSE); - resort_node (etta, gnode, TRUE); - - size = node->num_visible_children + 1; - resize_map (etta, etta->priv->n_map + size); - if (parent_gnode == etta->priv->root) - row = 0; - else { - gint new_size = parent_node->num_visible_children + 1; - gint old_size = new_size - size; - row = parent_node->index; - move_map_elements (etta, row + new_size, row + old_size, etta->priv->n_map - row - new_size); - } - fill_map (etta, row, parent_gnode); - e_table_model_rows_inserted (E_TABLE_MODEL (etta), get_row (etta, path), size); -} - -typedef struct { - GSList *paths; - gboolean expanded; -} check_expanded_closure; - -static gboolean -check_expanded (GNode *gnode, - gpointer data) -{ - check_expanded_closure *closure = (check_expanded_closure *) data; - node_t *node = (node_t *) gnode->data; - - if (node->expanded != closure->expanded) - closure->paths = g_slist_prepend (closure->paths, node->path); - - return FALSE; -} - -static void -update_node (ETreeTableAdapter *etta, - ETreePath path) -{ - check_expanded_closure closure; - ETreePath parent = e_tree_model_node_get_parent (etta->priv->source, path); - GNode *gnode = lookup_gnode (etta, path); - GSList *l; - - closure.expanded = e_tree_model_get_expanded_default (etta->priv->source); - closure.paths = NULL; - - if (gnode) - g_node_traverse (gnode, G_POST_ORDER, G_TRAVERSE_ALL, -1, check_expanded, &closure); - - if (e_tree_model_node_is_root (etta->priv->source, path)) - generate_tree (etta, path); - else { - delete_node (etta, parent, path); - insert_node (etta, parent, path); - } - - for (l = closure.paths; l; l = l->next) - if (lookup_gnode (etta, l->data)) - e_tree_table_adapter_node_set_expanded (etta, l->data, !closure.expanded); - - g_slist_free (closure.paths); -} - -static void -etta_finalize (GObject *object) -{ - ETreeTableAdapterPrivate *priv; - - priv = E_TREE_TABLE_ADAPTER_GET_PRIVATE (object); - - if (priv->resort_idle_id) { - g_source_remove (priv->resort_idle_id); - priv->resort_idle_id = 0; - } - - if (priv->root) { - kill_gnode (priv->root, E_TREE_TABLE_ADAPTER (object)); - priv->root = NULL; - } - - g_hash_table_destroy (priv->nodes); - - g_free (priv->map_table); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (etta_parent_class)->finalize (object); -} - -static void -etta_dispose (GObject *object) -{ - ETreeTableAdapterPrivate *priv; - - priv = E_TREE_TABLE_ADAPTER_GET_PRIVATE (object); - - if (priv->sort_info) { - g_signal_handler_disconnect ( - priv->sort_info, priv->sort_info_changed_id); - g_object_unref (priv->sort_info); - priv->sort_info = NULL; - } - - if (priv->header) { - g_object_unref (priv->header); - priv->header = NULL; - } - - if (priv->source) { - g_signal_handler_disconnect ( - priv->source, priv->pre_change_id); - g_signal_handler_disconnect ( - priv->source, priv->no_change_id); - g_signal_handler_disconnect ( - priv->source, priv->rebuilt_id); - g_signal_handler_disconnect ( - priv->source, priv->node_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->node_data_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->node_col_changed_id); - g_signal_handler_disconnect ( - priv->source, priv->node_inserted_id); - g_signal_handler_disconnect ( - priv->source, priv->node_removed_id); - g_signal_handler_disconnect ( - priv->source, priv->node_request_collapse_id); - - g_object_unref (priv->source); - priv->source = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (etta_parent_class)->dispose (object); -} - -static gint -etta_column_count (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_column_count (etta->priv->source); -} - -static gboolean -etta_has_save_id (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_has_save_id (etta->priv->source); -} - -static gchar * -etta_get_save_id (ETableModel *etm, - gint row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_get_save_id (etta->priv->source, get_path (etta, row)); -} - -static gboolean -etta_has_change_pending (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_has_change_pending (etta->priv->source); -} - -static gint -etta_row_count (ETableModel *etm) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return etta->priv->n_map; -} - -static gpointer -etta_value_at (ETableModel *etm, - gint col, - gint row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - switch (col) { - case -1: - if (row == -1) - return NULL; - return get_path (etta, row); - case -2: - return etta->priv->source; - case -3: - return etta; - default: - return e_tree_model_value_at (etta->priv->source, get_path (etta, row), col); - } -} - -static void -etta_set_value_at (ETableModel *etm, - gint col, - gint row, - gconstpointer val) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - e_tree_model_set_value_at (etta->priv->source, get_path (etta, row), col, val); -} - -static gboolean -etta_is_cell_editable (ETableModel *etm, - gint col, - gint row) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_node_is_editable (etta->priv->source, get_path (etta, row), col); -} - -static void -etta_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ -} - -static gpointer -etta_duplicate_value (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_duplicate_value (etta->priv->source, col, value); -} - -static void -etta_free_value (ETableModel *etm, - gint col, - gpointer value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - e_tree_model_free_value (etta->priv->source, col, value); -} - -static gpointer -etta_initialize_value (ETableModel *etm, - gint col) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_initialize_value (etta->priv->source, col); -} - -static gboolean -etta_value_is_empty (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_value_is_empty (etta->priv->source, col, value); -} - -static gchar * -etta_value_to_string (ETableModel *etm, - gint col, - gconstpointer value) -{ - ETreeTableAdapter *etta = (ETreeTableAdapter *) etm; - - return e_tree_model_value_to_string (etta->priv->source, col, value); -} - -static void -etta_class_init (ETreeTableAdapterClass *class) -{ - GObjectClass *object_class; - ETableModelClass *table_model_class; - - g_type_class_add_private (class, sizeof (ETreeTableAdapterPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = etta_dispose; - object_class->finalize = etta_finalize; - - table_model_class = E_TABLE_MODEL_CLASS (class); - table_model_class->column_count = etta_column_count; - table_model_class->row_count = etta_row_count; - table_model_class->append_row = etta_append_row; - - table_model_class->value_at = etta_value_at; - table_model_class->set_value_at = etta_set_value_at; - table_model_class->is_cell_editable = etta_is_cell_editable; - - table_model_class->has_save_id = etta_has_save_id; - table_model_class->get_save_id = etta_get_save_id; - - table_model_class->has_change_pending = etta_has_change_pending; - table_model_class->duplicate_value = etta_duplicate_value; - table_model_class->free_value = etta_free_value; - table_model_class->initialize_value = etta_initialize_value; - table_model_class->value_is_empty = etta_value_is_empty; - table_model_class->value_to_string = etta_value_to_string; - - class->sorting_changed = NULL; - - signals[SORTING_CHANGED] = g_signal_new ( - "sorting_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeTableAdapterClass, sorting_changed), - NULL, NULL, - e_marshal_BOOLEAN__NONE, - G_TYPE_BOOLEAN, 0, - G_TYPE_NONE); -} - -static void -etta_init (ETreeTableAdapter *etta) -{ - etta->priv = E_TREE_TABLE_ADAPTER_GET_PRIVATE (etta); - - etta->priv->root_visible = TRUE; - etta->priv->remap_needed = TRUE; -} - -static void -etta_proxy_pre_change (ETreeModel *etm, - ETreeTableAdapter *etta) -{ - e_table_model_pre_change (E_TABLE_MODEL (etta)); -} - -static void -etta_proxy_no_change (ETreeModel *etm, - ETreeTableAdapter *etta) -{ - e_table_model_no_change (E_TABLE_MODEL (etta)); -} - -static void -etta_proxy_rebuilt (ETreeModel *etm, - ETreeTableAdapter *etta) -{ - if (!etta->priv->root) - return; - kill_gnode (etta->priv->root, etta); - etta->priv->root = NULL; - g_hash_table_destroy (etta->priv->nodes); - etta->priv->nodes = g_hash_table_new (NULL, NULL); -} - -static gboolean -resort_model (ETreeTableAdapter *etta) -{ - etta_sort_info_changed (NULL, etta); - etta->priv->resort_idle_id = 0; - return FALSE; -} - -static void -etta_proxy_node_changed (ETreeModel *etm, - ETreePath path, - ETreeTableAdapter *etta) -{ - update_node (etta, path); - e_table_model_changed (E_TABLE_MODEL (etta)); - - /* FIXME: Really it shouldnt be required. But a lot of thread - * which were supposed to be present in the list is way below - */ - if (!etta->priv->resort_idle_id) - etta->priv->resort_idle_id = g_idle_add ((GSourceFunc) resort_model, etta); -} - -static void -etta_proxy_node_data_changed (ETreeModel *etm, - ETreePath path, - ETreeTableAdapter *etta) -{ - gint row = get_row (etta, path); - - if (row == -1) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - - e_table_model_row_changed (E_TABLE_MODEL (etta), row); -} - -static void -etta_proxy_node_col_changed (ETreeModel *etm, - ETreePath path, - gint col, - ETreeTableAdapter *etta) -{ - gint row = get_row (etta, path); - - if (row == -1) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - - e_table_model_cell_changed (E_TABLE_MODEL (etta), col, row); -} - -static void -etta_proxy_node_inserted (ETreeModel *etm, - ETreePath parent, - ETreePath child, - ETreeTableAdapter *etta) -{ - if (e_tree_model_node_is_root (etm, child)) - generate_tree (etta, child); - else - insert_node (etta, parent, child); - - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -static void -etta_proxy_node_removed (ETreeModel *etm, - ETreePath parent, - ETreePath child, - gint old_position, - ETreeTableAdapter *etta) -{ - delete_node (etta, parent, child); - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -static void -etta_proxy_node_request_collapse (ETreeModel *etm, - ETreePath node, - ETreeTableAdapter *etta) -{ - e_tree_table_adapter_node_set_expanded (etta, node, FALSE); -} - -static void -etta_sort_info_changed (ETableSortInfo *sort_info, - ETreeTableAdapter *etta) -{ - if (!etta->priv->root) - return; - - /* the function is called also internally, with sort_info = NULL, - * thus skip those in signal emit */ - if (sort_info) { - gboolean handled = FALSE; - - g_signal_emit (etta, signals[SORTING_CHANGED], 0, &handled); - - if (handled) - return; - } - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - resort_node (etta, etta->priv->root, TRUE); - fill_map (etta, 0, etta->priv->root); - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -ETableModel * -e_tree_table_adapter_construct (ETreeTableAdapter *etta, - ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *header) -{ - ETreePath root; - - etta->priv->source = source; - g_object_ref (source); - - etta->priv->sort_info = sort_info; - if (sort_info) { - g_object_ref (sort_info); - etta->priv->sort_info_changed_id = g_signal_connect ( - sort_info, "sort_info_changed", - G_CALLBACK (etta_sort_info_changed), etta); - } - - etta->priv->header = header; - if (header) - g_object_ref (header); - - etta->priv->nodes = g_hash_table_new (NULL, NULL); - - root = e_tree_model_get_root (source); - - if (root) - generate_tree (etta, root); - - etta->priv->pre_change_id = g_signal_connect ( - source, "pre_change", - G_CALLBACK (etta_proxy_pre_change), etta); - etta->priv->no_change_id = g_signal_connect ( - source, "no_change", - G_CALLBACK (etta_proxy_no_change), etta); - etta->priv->rebuilt_id = g_signal_connect ( - source, "rebuilt", - G_CALLBACK (etta_proxy_rebuilt), etta); - etta->priv->node_changed_id = g_signal_connect ( - source, "node_changed", - G_CALLBACK (etta_proxy_node_changed), etta); - etta->priv->node_data_changed_id = g_signal_connect ( - source, "node_data_changed", - G_CALLBACK (etta_proxy_node_data_changed), etta); - etta->priv->node_col_changed_id = g_signal_connect ( - source, "node_col_changed", - G_CALLBACK (etta_proxy_node_col_changed), etta); - etta->priv->node_inserted_id = g_signal_connect ( - source, "node_inserted", - G_CALLBACK (etta_proxy_node_inserted), etta); - etta->priv->node_removed_id = g_signal_connect ( - source, "node_removed", - G_CALLBACK (etta_proxy_node_removed), etta); - etta->priv->node_request_collapse_id = g_signal_connect ( - source, "node_request_collapse", - G_CALLBACK (etta_proxy_node_request_collapse), etta); - - return E_TABLE_MODEL (etta); -} - -ETableModel * -e_tree_table_adapter_new (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *header) -{ - ETreeTableAdapter *etta = g_object_new (E_TYPE_TREE_TABLE_ADAPTER, NULL); - - e_tree_table_adapter_construct (etta, source, sort_info, header); - - return (ETableModel *) etta; -} - -typedef struct { - xmlNode *root; - gboolean expanded_default; - ETreeModel *model; -} TreeAndRoot; - -static void -save_expanded_state_func (gpointer keyp, - gpointer value, - gpointer data) -{ - ETreePath path = keyp; - node_t *node = ((GNode *) value)->data; - TreeAndRoot *tar = data; - xmlNode *xmlnode; - - if (node->expanded != tar->expanded_default) { - gchar *save_id = e_tree_model_get_save_id (tar->model, path); - xmlnode = xmlNewChild (tar->root, NULL, (const guchar *)"node", NULL); - e_xml_set_string_prop_by_name (xmlnode, (const guchar *)"id", save_id); - g_free (save_id); - } -} - -xmlDoc * -e_tree_table_adapter_save_expanded_state_xml (ETreeTableAdapter *etta) -{ - TreeAndRoot tar; - xmlDocPtr doc; - xmlNode *root; - - g_return_val_if_fail (etta != NULL, NULL); - - doc = xmlNewDoc ((const guchar *)"1.0"); - root = xmlNewDocNode (doc, NULL, (const guchar *)"expanded_state", NULL); - xmlDocSetRootElement (doc, root); - - tar.model = etta->priv->source; - tar.root = root; - tar.expanded_default = e_tree_model_get_expanded_default (etta->priv->source); - - e_xml_set_integer_prop_by_name (root, (const guchar *)"vers", 2); - e_xml_set_bool_prop_by_name (root, (const guchar *)"default", tar.expanded_default); - - g_hash_table_foreach (etta->priv->nodes, save_expanded_state_func, &tar); - - return doc; -} - -void -e_tree_table_adapter_save_expanded_state (ETreeTableAdapter *etta, - const gchar *filename) -{ - xmlDoc *doc; - - g_return_if_fail (etta != NULL); - - doc = e_tree_table_adapter_save_expanded_state_xml (etta); - if (doc) { - e_xml_save_file (filename, doc); - xmlFreeDoc (doc); - } -} - -static xmlDoc * -open_file (ETreeTableAdapter *etta, - const gchar *filename) -{ - xmlDoc *doc; - xmlNode *root; - gint vers; - gboolean model_default, saved_default; - - if (!g_file_test (filename, G_FILE_TEST_EXISTS)) - return NULL; - -#ifdef G_OS_WIN32 - { - gchar *locale_filename = g_win32_locale_filename_from_utf8 (filename); - doc = xmlParseFile (locale_filename); - g_free (locale_filename); - } -#else - doc = xmlParseFile (filename); -#endif - - if (!doc) - return NULL; - - root = xmlDocGetRootElement (doc); - if (root == NULL || strcmp ((gchar *) root->name, "expanded_state")) { - xmlFreeDoc (doc); - return NULL; - } - - vers = e_xml_get_integer_prop_by_name_with_default (root, (const guchar *)"vers", 0); - if (vers > 2) { - xmlFreeDoc (doc); - return NULL; - } - model_default = e_tree_model_get_expanded_default (etta->priv->source); - saved_default = e_xml_get_bool_prop_by_name_with_default (root, (const guchar *)"default", !model_default); - if (saved_default != model_default) { - xmlFreeDoc (doc); - return NULL; - } - - return doc; -} - -/* state: <0 ... collapse; 0 ... use default; >0 ... expand */ -void -e_tree_table_adapter_force_expanded_state (ETreeTableAdapter *etta, - gint state) -{ - g_return_if_fail (etta != NULL); - - etta->priv->force_expanded_state = state; -} - -void -e_tree_table_adapter_load_expanded_state_xml (ETreeTableAdapter *etta, - xmlDoc *doc) -{ - xmlNode *root, *child; - gboolean model_default; - gboolean file_default = FALSE; - - g_return_if_fail (etta != NULL); - g_return_if_fail (doc != NULL); - - root = xmlDocGetRootElement (doc); - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - - model_default = e_tree_model_get_expanded_default (etta->priv->source); - - if (!strcmp ((gchar *) root->name, "expanded_state")) { - gchar *state; - - state = e_xml_get_string_prop_by_name_with_default (root, (const guchar *)"default", ""); - - if (state[0] == 't') - file_default = TRUE; - else - file_default = FALSE; /* Even unspecified we'll consider as false */ - - g_free (state); - } - - /* Incase the default is changed, lets forget the changes and stick to default */ - - if (file_default != model_default) { - xmlFreeDoc (doc); - return; - } - - for (child = root->xmlChildrenNode; child; child = child->next) { - gchar *id; - ETreePath path; - - if (strcmp ((gchar *) child->name, "node")) { - d (g_warning ("unknown node '%s' in %s", child->name, filename)); - continue; - } - - id = e_xml_get_string_prop_by_name_with_default (child, (const guchar *)"id", ""); - - if (!strcmp (id, "")) { - g_free (id); - continue; - } - - path = e_tree_model_get_node_by_id (etta->priv->source, id); - if (path) - e_tree_table_adapter_node_set_expanded (etta, path, !model_default); - - g_free (id); - } - - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -void -e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, - const gchar *filename) -{ - xmlDoc *doc; - - g_return_if_fail (etta != NULL); - - doc = open_file (etta, filename); - if (!doc) - return; - - e_tree_table_adapter_load_expanded_state_xml (etta, doc); - - xmlFreeDoc (doc); -} - -void -e_tree_table_adapter_root_node_set_visible (ETreeTableAdapter *etta, - gboolean visible) -{ - gint size; - - g_return_if_fail (etta != NULL); - - if (etta->priv->root_visible == visible) - return; - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - - etta->priv->root_visible = visible; - if (!visible) { - ETreePath root = e_tree_model_get_root (etta->priv->source); - if (root) - e_tree_table_adapter_node_set_expanded (etta, root, TRUE); - } - size = (visible ? 1 : 0) + (etta->priv->root ? ((node_t *) etta->priv->root->data)->num_visible_children : 0); - resize_map (etta, size); - if (etta->priv->root) - fill_map (etta, 0, etta->priv->root); - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -void -e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, - ETreePath path, - gboolean expanded) -{ - GNode *gnode = lookup_gnode (etta, path); - node_t *node; - gint row; - - if (!expanded && (!gnode || (e_tree_model_node_is_root (etta->priv->source, path) && !etta->priv->root_visible))) - return; - - if (!gnode && expanded) { - ETreePath parent = e_tree_model_node_get_parent (etta->priv->source, path); - g_return_if_fail (parent != NULL); - e_tree_table_adapter_node_set_expanded (etta, parent, expanded); - gnode = lookup_gnode (etta, path); - } - g_return_if_fail (gnode != NULL); - - node = (node_t *) gnode->data; - - if (expanded == node->expanded) - return; - - node->expanded = expanded; - - row = get_row (etta, path); - if (row == -1) - return; - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - e_table_model_pre_change (E_TABLE_MODEL (etta)); - e_table_model_row_changed (E_TABLE_MODEL (etta), row); - - if (expanded) { - gint num_children = insert_children (etta, gnode); - update_child_counts (gnode, num_children); - if (etta->priv->sort_info && e_table_sort_info_sorting_get_count (etta->priv->sort_info) > 0) - resort_node (etta, gnode, TRUE); - resize_map (etta, etta->priv->n_map + num_children); - move_map_elements (etta, row + 1 + num_children, row + 1, etta->priv->n_map - row - 1 - num_children); - fill_map (etta, row, gnode); - if (num_children != 0) { - e_table_model_rows_inserted (E_TABLE_MODEL (etta), row + 1, num_children); - } else - e_table_model_no_change (E_TABLE_MODEL (etta)); - } else { - gint num_children = delete_children (etta, gnode); - if (num_children == 0) { - e_table_model_no_change (E_TABLE_MODEL (etta)); - return; - } - move_map_elements (etta, row + 1, row + 1 + num_children, etta->priv->n_map - row - 1 - num_children); - update_child_counts (gnode, - num_children); - resize_map (etta, etta->priv->n_map - num_children); - e_table_model_rows_deleted (E_TABLE_MODEL (etta), row + 1, num_children); - } -} - -void -e_tree_table_adapter_node_set_expanded_recurse (ETreeTableAdapter *etta, - ETreePath path, - gboolean expanded) -{ - ETreePath children; - - e_tree_table_adapter_node_set_expanded (etta, path, expanded); - - for (children = e_tree_model_node_get_first_child (etta->priv->source, path); - children; - children = e_tree_model_node_get_next (etta->priv->source, children)) { - e_tree_table_adapter_node_set_expanded_recurse (etta, children, expanded); - } -} - -ETreePath -e_tree_table_adapter_node_at_row (ETreeTableAdapter *etta, - gint row) -{ - return get_path (etta, row); -} - -gint -e_tree_table_adapter_row_of_node (ETreeTableAdapter *etta, - ETreePath path) -{ - return get_row (etta, path); -} - -gboolean -e_tree_table_adapter_root_node_is_visible (ETreeTableAdapter *etta) -{ - return etta->priv->root_visible; -} - -void -e_tree_table_adapter_show_node (ETreeTableAdapter *etta, - ETreePath path) -{ - ETreePath parent; - - parent = e_tree_model_node_get_parent (etta->priv->source, path); - - while (parent) { - e_tree_table_adapter_node_set_expanded (etta, parent, TRUE); - parent = e_tree_model_node_get_parent (etta->priv->source, parent); - } -} - -gboolean -e_tree_table_adapter_node_is_expanded (ETreeTableAdapter *etta, - ETreePath path) -{ - node_t *node = get_node (etta, path); - if (!e_tree_model_node_is_expandable (etta->priv->source, path) || !node) - return FALSE; - - return node->expanded; -} - -void -e_tree_table_adapter_set_sort_info (ETreeTableAdapter *etta, - ETableSortInfo *sort_info) -{ - if (etta->priv->sort_info) { - g_signal_handler_disconnect ( - etta->priv->sort_info, - etta->priv->sort_info_changed_id); - g_object_unref (etta->priv->sort_info); - } - - etta->priv->sort_info = sort_info; - if (sort_info) { - g_object_ref (sort_info); - etta->priv->sort_info_changed_id = g_signal_connect ( - sort_info, "sort_info_changed", - G_CALLBACK (etta_sort_info_changed), etta); - } - - if (!etta->priv->root) - return; - - e_table_model_pre_change (E_TABLE_MODEL (etta)); - resort_node (etta, etta->priv->root, TRUE); - fill_map (etta, 0, etta->priv->root); - e_table_model_changed (E_TABLE_MODEL (etta)); -} - -ETableSortInfo * -e_tree_table_adapter_get_sort_info (ETreeTableAdapter *etta) -{ - g_return_val_if_fail (etta != NULL, NULL); - - return etta->priv->sort_info; -} - -ETableHeader * -e_tree_table_adapter_get_header (ETreeTableAdapter *etta) -{ - g_return_val_if_fail (etta != NULL, NULL); - - return etta->priv->header; -} - -ETreePath -e_tree_table_adapter_node_get_next (ETreeTableAdapter *etta, - ETreePath path) -{ - GNode *node = lookup_gnode (etta, path); - - if (node && node->next) - return ((node_t *) node->next->data)->path; - - return NULL; -} diff --git a/widgets/table/e-tree-table-adapter.h b/widgets/table/e-tree-table-adapter.h deleted file mode 100644 index ea7b86b21d..0000000000 --- a/widgets/table/e-tree-table-adapter.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_TABLE_ADAPTER_H_ -#define _E_TREE_TABLE_ADAPTER_H_ - -#include <table/e-table-model.h> -#include <table/e-tree-model.h> -#include <table/e-table-sort-info.h> -#include <table/e-table-header.h> -#include <libxml/tree.h> - -/* Standard GObject macros */ -#define E_TYPE_TREE_TABLE_ADAPTER \ - (e_tree_table_adapter_get_type ()) -#define E_TREE_TABLE_ADAPTER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE_TABLE_ADAPTER, ETreeTableAdapter)) -#define E_TREE_TABLE_ADAPTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE_TABLE_ADAPTER, ETreeTableAdapterClass)) -#define E_IS_TREE_TABLE_ADAPTER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE_TABLE_ADAPTER)) -#define E_IS_TREE_TABLE_ADAPTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE_TABLE_ADAPTER)) -#define E_TREE_TABLE_ADAPTER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE_TABLE_ADAPTER, ETreeTableAdapterClass)) - -G_BEGIN_DECLS - -typedef struct _ETreeTableAdapter ETreeTableAdapter; -typedef struct _ETreeTableAdapterClass ETreeTableAdapterClass; -typedef struct _ETreeTableAdapterPrivate ETreeTableAdapterPrivate; - -struct _ETreeTableAdapter { - ETableModel parent; - ETreeTableAdapterPrivate *priv; -}; - -struct _ETreeTableAdapterClass { - ETableModelClass parent_class; - - /* Signals */ - gboolean (*sorting_changed) (ETreeTableAdapter *etta); -}; - -GType e_tree_table_adapter_get_type (void) G_GNUC_CONST; -ETableModel * e_tree_table_adapter_new (ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *header); -ETableModel * e_tree_table_adapter_construct (ETreeTableAdapter *ets, - ETreeModel *source, - ETableSortInfo *sort_info, - ETableHeader *header); - -ETreePath e_tree_table_adapter_node_get_next - (ETreeTableAdapter *etta, - ETreePath path); -gboolean e_tree_table_adapter_node_is_expanded - (ETreeTableAdapter *etta, - ETreePath path); -void e_tree_table_adapter_node_set_expanded - (ETreeTableAdapter *etta, - ETreePath path, - gboolean expanded); -void e_tree_table_adapter_node_set_expanded_recurse - (ETreeTableAdapter *etta, - ETreePath path, - gboolean expanded); -void e_tree_table_adapter_force_expanded_state - (ETreeTableAdapter *etta, - gint state); -void e_tree_table_adapter_root_node_set_visible - (ETreeTableAdapter *etta, - gboolean visible); -ETreePath e_tree_table_adapter_node_at_row - (ETreeTableAdapter *etta, - gint row); -gint e_tree_table_adapter_row_of_node - (ETreeTableAdapter *etta, - ETreePath path); -gboolean e_tree_table_adapter_root_node_is_visible - (ETreeTableAdapter *etta); - -void e_tree_table_adapter_show_node (ETreeTableAdapter *etta, - ETreePath path); - -void e_tree_table_adapter_save_expanded_state - (ETreeTableAdapter *etta, - const gchar *filename); -void e_tree_table_adapter_load_expanded_state - (ETreeTableAdapter *etta, - const gchar *filename); - -xmlDoc * e_tree_table_adapter_save_expanded_state_xml - (ETreeTableAdapter *etta); -void e_tree_table_adapter_load_expanded_state_xml - (ETreeTableAdapter *etta, - xmlDoc *doc); - -void e_tree_table_adapter_set_sort_info - (ETreeTableAdapter *etta, - ETableSortInfo *sort_info); -ETableSortInfo *e_tree_table_adapter_get_sort_info - (ETreeTableAdapter *etta); -ETableHeader * e_tree_table_adapter_get_header (ETreeTableAdapter *etta); - -G_END_DECLS - -#endif /* _E_TREE_TABLE_ADAPTER_H_ */ diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c deleted file mode 100644 index 78eef72746..0000000000 --- a/widgets/table/e-tree.c +++ /dev/null @@ -1,3956 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libgnomecanvas/libgnomecanvas.h> - -#include "gal-a11y-e-tree.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "misc/e-canvas.h" -#include "misc/e-canvas-utils.h" -#include "misc/e-canvas-background.h" -#include "text/e-text.h" - -#include "e-table-column-specification.h" -#include "e-table-header-item.h" -#include "e-table-header.h" -#include "e-table-item.h" -#include "e-table-sort-info.h" -#include "e-table-utils.h" -#ifdef E_TREE_USE_TREE_SELECTION -#include "e-tree-selection-model.h" -#else -#include "e-table-selection-model.h" -#endif -#include "e-tree.h" -#include "e-tree-table-adapter.h" - -#define COLUMN_HEADER_HEIGHT 16 - -#define d(x) - -#define E_TREE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TREE, ETreePrivate)) - -enum { - CURSOR_CHANGE, - CURSOR_ACTIVATED, - SELECTION_CHANGE, - DOUBLE_CLICK, - RIGHT_CLICK, - CLICK, - KEY_PRESS, - START_DRAG, - STATE_CHANGE, - WHITE_SPACE_EVENT, - - CUT_CLIPBOARD, - COPY_CLIPBOARD, - PASTE_CLIPBOARD, - SELECT_ALL, - - TREE_DRAG_BEGIN, - TREE_DRAG_END, - TREE_DRAG_DATA_GET, - TREE_DRAG_DATA_DELETE, - - TREE_DRAG_LEAVE, - TREE_DRAG_MOTION, - TREE_DRAG_DROP, - TREE_DRAG_DATA_RECEIVED, - - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_LENGTH_THRESHOLD, - PROP_HORIZONTAL_DRAW_GRID, - PROP_VERTICAL_DRAW_GRID, - PROP_DRAW_FOCUS, - PROP_ETTA, - PROP_UNIFORM_ROW_HEIGHT, - PROP_ALWAYS_SEARCH, - PROP_HADJUSTMENT, - PROP_VADJUSTMENT, - PROP_HSCROLL_POLICY, - PROP_VSCROLL_POLICY -}; - -enum { - ET_SCROLL_UP = 1 << 0, - ET_SCROLL_DOWN = 1 << 1, - ET_SCROLL_LEFT = 1 << 2, - ET_SCROLL_RIGHT = 1 << 3 -}; - -struct _ETreePrivate { - ETreeModel *model; - ETreeTableAdapter *etta; - - ETableHeader *full_header, *header; - - guint structure_change_id, expansion_change_id; - - ETableSortInfo *sort_info; - ESorter *sorter; - - guint sort_info_change_id, group_info_change_id; - - ESelectionModel *selection; - ETableSpecification *spec; - - ETableSearch *search; - - ETableCol *current_search_col; - - guint search_search_id; - guint search_accept_id; - - gint reflow_idle_id; - gint scroll_idle_id; - gint hover_idle_id; - - gboolean show_cursor_after_reflow; - - gint table_model_change_id; - gint table_row_change_id; - gint table_cell_change_id; - gint table_rows_delete_id; - - GnomeCanvasItem *info_text; - guint info_text_resize_id; - - GnomeCanvas *header_canvas, *table_canvas; - - GnomeCanvasItem *header_item, *root; - - GnomeCanvasItem *white_item; - GnomeCanvasItem *item; - - gint length_threshold; - - /* - * Configuration settings - */ - guint alternating_row_colors : 1; - guint horizontal_draw_grid : 1; - guint vertical_draw_grid : 1; - guint draw_focus : 1; - guint row_selection_active : 1; - - guint horizontal_scrolling : 1; - - guint scroll_direction : 4; - - guint do_drag : 1; - - guint uniform_row_height : 1; - - guint search_col_set : 1; - guint always_search : 1; - - ECursorMode cursor_mode; - - gint drop_row; - ETreePath drop_path; - gint drop_col; - - GnomeCanvasItem *drop_highlight; - gint last_drop_x; - gint last_drop_y; - gint last_drop_time; - GdkDragContext *last_drop_context; - - gint hover_x; - gint hover_y; - - gint drag_row; - ETreePath drag_path; - gint drag_col; - ETreeDragSourceSite *site; - - GList *expanded_list; - - gboolean state_changed; - guint state_change_freeze; - - gboolean is_dragging; -}; - -static guint et_signals[LAST_SIGNAL] = { 0, }; - -static void et_grab_focus (GtkWidget *widget); - -static void et_drag_begin (GtkWidget *widget, - GdkDragContext *context, - ETree *et); -static void et_drag_end (GtkWidget *widget, - GdkDragContext *context, - ETree *et); -static void et_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETree *et); -static void et_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - ETree *et); - -static void et_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - ETree *et); -static gboolean et_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETree *et); -static gboolean et_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETree *et); -static void et_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - ETree *et); - -static void scroll_off (ETree *et); -static void scroll_on (ETree *et, guint scroll_direction); -static void hover_off (ETree *et); -static void hover_on (ETree *et, gint x, gint y); -static void context_destroyed (gpointer data, GObject *ctx); - -G_DEFINE_TYPE_WITH_CODE (ETree, e_tree, GTK_TYPE_TABLE, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) - -static void -et_disconnect_from_etta (ETree *et) -{ - if (et->priv->table_model_change_id != 0) - g_signal_handler_disconnect ( - et->priv->etta, - et->priv->table_model_change_id); - if (et->priv->table_row_change_id != 0) - g_signal_handler_disconnect ( - et->priv->etta, - et->priv->table_row_change_id); - if (et->priv->table_cell_change_id != 0) - g_signal_handler_disconnect ( - et->priv->etta, - et->priv->table_cell_change_id); - if (et->priv->table_rows_delete_id != 0) - g_signal_handler_disconnect ( - et->priv->etta, - et->priv->table_rows_delete_id); - - et->priv->table_model_change_id = 0; - et->priv->table_row_change_id = 0; - et->priv->table_cell_change_id = 0; - et->priv->table_rows_delete_id = 0; -} - -static void -clear_current_search_col (ETree *et) -{ - et->priv->search_col_set = FALSE; -} - -static ETableCol * -current_search_col (ETree *et) -{ - if (!et->priv->search_col_set) { - et->priv->current_search_col = - e_table_util_calculate_current_search_col ( - et->priv->header, - et->priv->full_header, - et->priv->sort_info, - et->priv->always_search); - et->priv->search_col_set = TRUE; - } - - return et->priv->current_search_col; -} - -static void -e_tree_state_change (ETree *et) -{ - if (et->priv->state_change_freeze) - et->priv->state_changed = TRUE; - else - g_signal_emit (et, et_signals[STATE_CHANGE], 0); -} - -static void -change_trigger (GObject *object, - ETree *et) -{ - e_tree_state_change (et); -} - -static void -search_col_change_trigger (GObject *object, - ETree *et) -{ - clear_current_search_col (et); - e_tree_state_change (et); -} - -static void -disconnect_header (ETree *e_tree) -{ - if (e_tree->priv->header == NULL) - return; - - if (e_tree->priv->structure_change_id) - g_signal_handler_disconnect ( - e_tree->priv->header, - e_tree->priv->structure_change_id); - if (e_tree->priv->expansion_change_id) - g_signal_handler_disconnect ( - e_tree->priv->header, - e_tree->priv->expansion_change_id); - if (e_tree->priv->sort_info) { - if (e_tree->priv->sort_info_change_id) - g_signal_handler_disconnect ( - e_tree->priv->sort_info, - e_tree->priv->sort_info_change_id); - if (e_tree->priv->group_info_change_id) - g_signal_handler_disconnect ( - e_tree->priv->sort_info, - e_tree->priv->group_info_change_id); - - g_object_unref (e_tree->priv->sort_info); - } - g_object_unref (e_tree->priv->header); - e_tree->priv->header = NULL; - e_tree->priv->sort_info = NULL; -} - -static void -connect_header (ETree *e_tree, - ETableState *state) -{ - GValue *val = g_new0 (GValue, 1); - - if (e_tree->priv->header != NULL) - disconnect_header (e_tree); - - e_tree->priv->header = e_table_state_to_header ( - GTK_WIDGET (e_tree), e_tree->priv->full_header, state); - - e_tree->priv->structure_change_id = g_signal_connect ( - e_tree->priv->header, "structure_change", - G_CALLBACK (search_col_change_trigger), e_tree); - - e_tree->priv->expansion_change_id = g_signal_connect ( - e_tree->priv->header, "expansion_change", - G_CALLBACK (change_trigger), e_tree); - - if (state->sort_info) { - e_tree->priv->sort_info = e_table_sort_info_duplicate (state->sort_info); - e_table_sort_info_set_can_group (e_tree->priv->sort_info, FALSE); - e_tree->priv->sort_info_change_id = g_signal_connect ( - e_tree->priv->sort_info, "sort_info_changed", - G_CALLBACK (search_col_change_trigger), e_tree); - - e_tree->priv->group_info_change_id = g_signal_connect ( - e_tree->priv->sort_info, "group_info_changed", - G_CALLBACK (search_col_change_trigger), e_tree); - } else - e_tree->priv->sort_info = NULL; - - g_value_init (val, G_TYPE_OBJECT); - g_value_set_object (val, e_tree->priv->sort_info); - g_object_set_property (G_OBJECT (e_tree->priv->header), "sort_info", val); - g_free (val); -} - -static void -et_dispose (GObject *object) -{ - ETreePrivate *priv; - - priv = E_TREE_GET_PRIVATE (object); - - if (priv->search != NULL) { - g_signal_handler_disconnect ( - priv->search, priv->search_search_id); - g_signal_handler_disconnect ( - priv->search, priv->search_accept_id); - g_object_unref (priv->search); - priv->search = NULL; - } - - if (priv->reflow_idle_id > 0) { - g_source_remove (priv->reflow_idle_id); - priv->reflow_idle_id = 0; - } - - scroll_off (E_TREE (object)); - hover_off (E_TREE (object)); - g_list_foreach ( - priv->expanded_list, - (GFunc) g_free, NULL); - g_list_free (priv->expanded_list); - priv->expanded_list = NULL; - - et_disconnect_from_etta (E_TREE (object)); - - if (priv->etta != NULL) { - g_object_unref (priv->etta); - priv->etta = NULL; - } - - if (priv->model != NULL) { - g_object_unref (priv->model); - priv->model = NULL; - } - - if (priv->full_header != NULL) { - g_object_unref (priv->full_header); - priv->full_header = NULL; - } - - disconnect_header (E_TREE (object)); - - if (priv->selection != NULL) { - g_object_unref (priv->selection); - priv->selection = NULL; - } - - if (priv->spec != NULL) { - g_object_unref (priv->spec); - priv->spec = NULL; - } - - if (priv->sorter != NULL) { - g_object_unref (priv->sorter); - priv->sorter = NULL; - } - - if (priv->header_canvas != NULL) { - gtk_widget_destroy (GTK_WIDGET (priv->header_canvas)); - priv->header_canvas = NULL; - } - - if (priv->site) - e_tree_drag_source_unset (E_TREE (object)); - - if (priv->last_drop_context != NULL) { - g_object_weak_unref ( - G_OBJECT (priv->last_drop_context), - context_destroyed, object); - priv->last_drop_context = NULL; - } - - if (priv->info_text != NULL) { - g_object_run_dispose (G_OBJECT (priv->info_text)); - priv->info_text = NULL; - } - priv->info_text_resize_id = 0; - - if (priv->table_canvas != NULL) { - gtk_widget_destroy (GTK_WIDGET (priv->table_canvas)); - priv->table_canvas = NULL; - } - - /* do not unref it, it was owned by priv->table_canvas */ - priv->item = NULL; - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_tree_parent_class)->dispose (object); -} - -static void -et_unrealize (GtkWidget *widget) -{ - scroll_off (E_TREE (widget)); - hover_off (E_TREE (widget)); - - if (GTK_WIDGET_CLASS (e_tree_parent_class)->unrealize) - GTK_WIDGET_CLASS (e_tree_parent_class)->unrealize (widget); -} - -typedef struct { - ETree *et; - gchar *string; -} SearchSearchStruct; - -static gboolean -search_search_callback (ETreeModel *model, - ETreePath path, - gpointer data) -{ - SearchSearchStruct *cb_data = data; - gconstpointer value; - ETableCol *col = current_search_col (cb_data->et); - - value = e_tree_model_value_at ( - model, path, cb_data->et->priv->current_search_col->col_idx); - - return col->search (value, cb_data->string); -} - -static gboolean -et_search_search (ETableSearch *search, - gchar *string, - ETableSearchFlags flags, - ETree *et) -{ - ETreePath cursor; - ETreePath found; - SearchSearchStruct cb_data; - ETableCol *col = current_search_col (et); - - if (col == NULL) - return FALSE; - - cb_data.et = et; - cb_data.string = string; - - cursor = e_tree_get_cursor (et); - - if (cursor && (flags & E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST)) { - gconstpointer value; - - value = e_tree_model_value_at (et->priv->model, cursor, col->col_idx); - - if (col->search (value, string)) { - return TRUE; - } - } - - found = e_tree_model_node_find ( - et->priv->model, cursor, NULL, - E_TREE_FIND_NEXT_FORWARD, - search_search_callback, &cb_data); - if (found == NULL) - found = e_tree_model_node_find ( - et->priv->model, NULL, cursor, - E_TREE_FIND_NEXT_FORWARD, - search_search_callback, &cb_data); - - if (found && found != cursor) { - gint model_row; - - e_tree_table_adapter_show_node (et->priv->etta, found); - model_row = e_tree_table_adapter_row_of_node (et->priv->etta, found); - - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->priv->selection), - model_row, col->col_idx, GDK_CONTROL_MASK); - return TRUE; - } else if (cursor && !(flags & E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST)) { - gconstpointer value; - - value = e_tree_model_value_at (et->priv->model, cursor, col->col_idx); - - return col->search (value, string); - } else - return FALSE; -} - -static void -et_search_accept (ETableSearch *search, - ETree *et) -{ - ETableCol *col = current_search_col (et); - gint cursor; - - if (col == NULL) - return; - - g_object_get (et->priv->selection, "cursor_row", &cursor, NULL); - - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->priv->selection), - cursor, col->col_idx, 0); -} - -static void -e_tree_init (ETree *e_tree) -{ - gtk_widget_set_can_focus (GTK_WIDGET (e_tree), TRUE); - - gtk_table_set_homogeneous (GTK_TABLE (e_tree), FALSE); - - e_tree->priv = E_TREE_GET_PRIVATE (e_tree); - - e_tree->priv->alternating_row_colors = 1; - e_tree->priv->horizontal_draw_grid = 1; - e_tree->priv->vertical_draw_grid = 1; - e_tree->priv->draw_focus = 1; - e_tree->priv->cursor_mode = E_CURSOR_SIMPLE; - e_tree->priv->length_threshold = 200; - - e_tree->priv->drop_row = -1; - e_tree->priv->drop_col = -1; - - e_tree->priv->drag_row = -1; - e_tree->priv->drag_col = -1; - -#ifdef E_TREE_USE_TREE_SELECTION - e_tree->priv->selection = - E_SELECTION_MODEL (e_tree_selection_model_new ()); -#else - e_tree->priv->selection = - E_SELECTION_MODEL (e_table_selection_model_new ()); -#endif - - e_tree->priv->search = e_table_search_new (); - - e_tree->priv->search_search_id = g_signal_connect ( - e_tree->priv->search, "search", - G_CALLBACK (et_search_search), e_tree); - - e_tree->priv->search_accept_id = g_signal_connect ( - e_tree->priv->search, "accept", - G_CALLBACK (et_search_accept), e_tree); - - e_tree->priv->always_search = g_getenv ("GAL_ALWAYS_SEARCH") ? TRUE : FALSE; - - e_tree->priv->state_changed = FALSE; - e_tree->priv->state_change_freeze = 0; - - e_tree->priv->is_dragging = FALSE; -} - -/* Grab_focus handler for the ETree */ -static void -et_grab_focus (GtkWidget *widget) -{ - ETree *e_tree; - - e_tree = E_TREE (widget); - - gtk_widget_grab_focus (GTK_WIDGET (e_tree->priv->table_canvas)); -} - -/* Focus handler for the ETree */ -static gint -et_focus (GtkWidget *container, - GtkDirectionType direction) -{ - ETree *e_tree; - - e_tree = E_TREE (container); - - if (gtk_container_get_focus_child (GTK_CONTAINER (container))) { - gtk_container_set_focus_child (GTK_CONTAINER (container), NULL); - return FALSE; - } - - return gtk_widget_child_focus ( - GTK_WIDGET (e_tree->priv->table_canvas), direction); -} - -static void -set_header_canvas_width (ETree *e_tree) -{ - gdouble oldwidth, oldheight, width; - - if (!(e_tree->priv->header_item && - e_tree->priv->header_canvas && e_tree->priv->table_canvas)) - return; - - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_tree->priv->table_canvas), - NULL, NULL, &width, NULL); - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_tree->priv->header_canvas), - NULL, NULL, &oldwidth, &oldheight); - - if (oldwidth != width || - oldheight != E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height - 1) - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (e_tree->priv->header_canvas), - 0, 0, width, /* COLUMN_HEADER_HEIGHT - 1 */ - E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height - 1); - -} - -static void -header_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *alloc, - ETree *e_tree) -{ - GtkAllocation allocation; - - set_header_canvas_width (e_tree); - - widget = GTK_WIDGET (e_tree->priv->header_canvas); - gtk_widget_get_allocation (widget, &allocation); - - /* When the header item is created ->height == 0, - * as the font is only created when everything is realized. - * So we set the usize here as well, so that the size of the - * header is correct */ - if (allocation.height != E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height) - gtk_widget_set_size_request ( - widget, -1, - E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height); -} - -static void -e_tree_setup_header (ETree *e_tree) -{ - GtkWidget *widget; - gchar *pointer; - - widget = e_canvas_new (); - gtk_widget_set_can_focus (widget, FALSE); - e_tree->priv->header_canvas = GNOME_CANVAS (widget); - gtk_widget_show (widget); - - pointer = g_strdup_printf ("%p", (gpointer) e_tree); - - e_tree->priv->header_item = gnome_canvas_item_new ( - gnome_canvas_root (e_tree->priv->header_canvas), - e_table_header_item_get_type (), - "ETableHeader", e_tree->priv->header, - "full_header", e_tree->priv->full_header, - "sort_info", e_tree->priv->sort_info, - "dnd_code", pointer, - "tree", e_tree, - NULL); - - g_free (pointer); - - g_signal_connect ( - e_tree->priv->header_canvas, "size_allocate", - G_CALLBACK (header_canvas_size_allocate), e_tree); - - gtk_widget_set_size_request ( - GTK_WIDGET (e_tree->priv->header_canvas), -1, - E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height); -} - -static void -scroll_to_cursor (ETree *e_tree) -{ - ETreePath path; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gint x, y, w, h; - gdouble page_size; - gdouble lower; - gdouble upper; - gdouble value; - - path = e_tree_get_cursor (e_tree); - x = y = w = h = 0; - - if (path) { - gint row = e_tree_row_of_node (e_tree, path); - gint col = 0; - - if (row >= 0) - e_table_item_get_cell_geometry ( - E_TABLE_ITEM (e_tree->priv->item), - &row, &col, &x, &y, &w, &h); - } - - scrollable = GTK_SCROLLABLE (e_tree->priv->table_canvas); - adjustment = gtk_scrollable_get_vadjustment (scrollable); - - page_size = gtk_adjustment_get_page_size (adjustment); - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - value = gtk_adjustment_get_value (adjustment); - - if (y < value || y + h > value + page_size) { - value = CLAMP (y - page_size / 2, lower, upper - page_size); - gtk_adjustment_set_value (adjustment, value); - } -} - -static gboolean -tree_canvas_reflow_idle (ETree *e_tree) -{ - gdouble height, width; - gdouble oldheight, oldwidth; - GtkAllocation allocation; - GtkWidget *widget; - - widget = GTK_WIDGET (e_tree->priv->table_canvas); - gtk_widget_get_allocation (widget, &allocation); - - g_object_get ( - e_tree->priv->item, - "height", &height, "width", &width, NULL); - - height = MAX ((gint) height, allocation.height); - width = MAX ((gint) width, allocation.width); - - /* I have no idea why this needs to be -1, but it works. */ - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (e_tree->priv->table_canvas), - NULL, NULL, &oldwidth, &oldheight); - - if (oldwidth != width - 1 || - oldheight != height - 1) { - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (e_tree->priv->table_canvas), - 0, 0, width - 1, height - 1); - set_header_canvas_width (e_tree); - } - - e_tree->priv->reflow_idle_id = 0; - - if (e_tree->priv->show_cursor_after_reflow) { - e_tree->priv->show_cursor_after_reflow = FALSE; - scroll_to_cursor (e_tree); - } - - return FALSE; -} - -static void -tree_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *alloc, - ETree *e_tree) -{ - gdouble width; - gdouble height; - GValue *val = g_new0 (GValue, 1); - g_value_init (val, G_TYPE_DOUBLE); - - width = alloc->width; - g_value_set_double (val, width); - g_object_get ( - e_tree->priv->item, - "height", &height, - NULL); - height = MAX ((gint) height, alloc->height); - - g_object_set ( - e_tree->priv->item, - "width", width, - NULL); - g_object_set_property (G_OBJECT (e_tree->priv->header), "width", val); - g_free (val); - - if (e_tree->priv->reflow_idle_id) - g_source_remove (e_tree->priv->reflow_idle_id); - tree_canvas_reflow_idle (e_tree); -} - -static void -tree_canvas_reflow (GnomeCanvas *canvas, - ETree *e_tree) -{ - if (!e_tree->priv->reflow_idle_id) - e_tree->priv->reflow_idle_id = g_idle_add_full ( - 400, (GSourceFunc) tree_canvas_reflow_idle, - e_tree, NULL); -} - -static void -item_cursor_change (ETableItem *eti, - gint row, - ETree *et) -{ - ETreePath path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - g_signal_emit (et, et_signals[CURSOR_CHANGE], 0, row, path); -} - -static void -item_cursor_activated (ETableItem *eti, - gint row, - ETree *et) -{ - ETreePath path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - g_signal_emit (et, et_signals[CURSOR_ACTIVATED], 0, row, path); -} - -static void -item_double_click (ETableItem *eti, - gint row, - gint col, - GdkEvent *event, - ETree *et) -{ - ETreePath path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - g_signal_emit (et, et_signals[DOUBLE_CLICK], 0, row, path, col, event); -} - -static gboolean -item_right_click (ETableItem *eti, - gint row, - gint col, - GdkEvent *event, - ETree *et) -{ - ETreePath path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - gboolean return_val = 0; - - g_signal_emit ( - et, et_signals[RIGHT_CLICK], 0, - row, path, col, event, &return_val); - - return return_val; -} - -static gboolean -item_click (ETableItem *eti, - gint row, - gint col, - GdkEvent *event, - ETree *et) -{ - gboolean return_val = 0; - ETreePath path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - g_signal_emit ( - et, et_signals[CLICK], 0, row, path, col, event, &return_val); - - return return_val; -} - -static gint -item_key_press (ETableItem *eti, - gint row, - gint col, - GdkEvent *event, - ETree *et) -{ - gint return_val = 0; - GdkEventKey *key = (GdkEventKey *) event; - ETreePath path; - gint y, row_local, col_local; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gdouble page_size; - gdouble upper; - gdouble value; - - scrollable = GTK_SCROLLABLE (et->priv->table_canvas); - adjustment = gtk_scrollable_get_vadjustment (scrollable); - - page_size = gtk_adjustment_get_page_size (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - value = gtk_adjustment_get_value (adjustment); - - switch (key->keyval) { - case GDK_KEY_Page_Down: - case GDK_KEY_KP_Page_Down: - y = CLAMP (value + (2 * page_size - 50), 0, upper); - y -= value; - e_tree_get_cell_at (et, 30, y, &row_local, &col_local); - - if (row_local == -1) - row_local = e_table_model_row_count ( - E_TABLE_MODEL (et->priv->etta)) - 1; - - row_local = e_tree_view_to_model_row (et, row_local); - col_local = e_selection_model_cursor_col ( - E_SELECTION_MODEL (et->priv->selection)); - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->priv->selection), - row_local, col_local, key->state); - - return_val = 1; - break; - case GDK_KEY_Page_Up: - case GDK_KEY_KP_Page_Up: - y = CLAMP (value - (page_size - 50), 0, upper); - y -= value; - e_tree_get_cell_at (et, 30, y, &row_local, &col_local); - - if (row_local == -1) - row_local = e_table_model_row_count ( - E_TABLE_MODEL (et->priv->etta)) - 1; - - row_local = e_tree_view_to_model_row (et, row_local); - col_local = e_selection_model_cursor_col ( - E_SELECTION_MODEL (et->priv->selection)); - e_selection_model_select_as_key_press ( - E_SELECTION_MODEL (et->priv->selection), - row_local, col_local, key->state); - - return_val = 1; - break; - case GDK_KEY_plus: - case GDK_KEY_KP_Add: - case GDK_KEY_Right: - case GDK_KEY_KP_Right: - /* Only allow if the Shift modifier is used. - * eg. Ctrl-Equal shouldn't be handled. */ - if ((key->state & (GDK_SHIFT_MASK | GDK_LOCK_MASK | - GDK_MOD1_MASK)) != GDK_SHIFT_MASK) - break; - if (row != -1) { - path = e_tree_table_adapter_node_at_row ( - et->priv->etta, row); - if (path) - e_tree_table_adapter_node_set_expanded ( - et->priv->etta, path, TRUE); - } - return_val = 1; - break; - case GDK_KEY_underscore: - case GDK_KEY_KP_Subtract: - case GDK_KEY_Left: - case GDK_KEY_KP_Left: - /* Only allow if the Shift modifier is used. - * eg. Ctrl-Minus shouldn't be handled. */ - if ((key->state & (GDK_SHIFT_MASK | GDK_LOCK_MASK | - GDK_MOD1_MASK)) != GDK_SHIFT_MASK) - break; - if (row != -1) { - path = e_tree_table_adapter_node_at_row ( - et->priv->etta, row); - if (path) - e_tree_table_adapter_node_set_expanded ( - et->priv->etta, path, FALSE); - } - return_val = 1; - break; - case GDK_KEY_BackSpace: - if (e_table_search_backspace (et->priv->search)) - return TRUE; - /* Fallthrough */ - default: - if ((key->state & ~(GDK_SHIFT_MASK | GDK_LOCK_MASK | - GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | - GDK_MOD4_MASK | GDK_MOD5_MASK)) == 0 - && ((key->keyval >= GDK_KEY_a && key->keyval <= GDK_KEY_z) || - (key->keyval >= GDK_KEY_A && key->keyval <= GDK_KEY_Z) || - (key->keyval >= GDK_KEY_0 && key->keyval <= GDK_KEY_9))) { - e_table_search_input_character (et->priv->search, key->keyval); - } - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - g_signal_emit ( - et, - et_signals[KEY_PRESS], 0, - row, path, col, event, &return_val); - break; - } - return return_val; -} - -static gint -item_start_drag (ETableItem *eti, - gint row, - gint col, - GdkEvent *event, - ETree *et) -{ - ETreePath path; - gint return_val = 0; - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - g_signal_emit ( - et, et_signals[START_DRAG], 0, - row, path, col, event, &return_val); - - return return_val; -} - -static void -et_selection_model_selection_changed (ETableSelectionModel *etsm, - ETree *et) -{ - g_signal_emit (et, et_signals[SELECTION_CHANGE], 0); -} - -static void -et_selection_model_selection_row_changed (ETableSelectionModel *etsm, - gint row, - ETree *et) -{ - g_signal_emit (et, et_signals[SELECTION_CHANGE], 0); -} - -static void -et_build_item (ETree *et) -{ - et->priv->item = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP ( - gnome_canvas_root (et->priv->table_canvas)), - e_table_item_get_type (), - "ETableHeader", et->priv->header, - "ETableModel", et->priv->etta, - "selection_model", et->priv->selection, - "alternating_row_colors", et->priv->alternating_row_colors, - "horizontal_draw_grid", et->priv->horizontal_draw_grid, - "vertical_draw_grid", et->priv->vertical_draw_grid, - "drawfocus", et->priv->draw_focus, - "cursor_mode", et->priv->cursor_mode, - "length_threshold", et->priv->length_threshold, - "uniform_row_height", et->priv->uniform_row_height, - NULL); - - g_signal_connect ( - et->priv->item, "cursor_change", - G_CALLBACK (item_cursor_change), et); - g_signal_connect ( - et->priv->item, "cursor_activated", - G_CALLBACK (item_cursor_activated), et); - g_signal_connect ( - et->priv->item, "double_click", - G_CALLBACK (item_double_click), et); - g_signal_connect ( - et->priv->item, "right_click", - G_CALLBACK (item_right_click), et); - g_signal_connect ( - et->priv->item, "click", - G_CALLBACK (item_click), et); - g_signal_connect ( - et->priv->item, "key_press", - G_CALLBACK (item_key_press), et); - g_signal_connect ( - et->priv->item, "start_drag", - G_CALLBACK (item_start_drag), et); -} - -static void -et_canvas_style_set (GtkWidget *widget, - GtkStyle *prev_style) -{ - GtkStyle *style; - - style = gtk_widget_get_style (widget); - - gnome_canvas_item_set ( - E_TREE (widget)->priv->white_item, - "fill_color_gdk", &style->base[GTK_STATE_NORMAL], - NULL); -} - -static gboolean -white_item_event (GnomeCanvasItem *white_item, - GdkEvent *event, - ETree *e_tree) -{ - gboolean return_val = 0; - g_signal_emit ( - e_tree, - et_signals[WHITE_SPACE_EVENT], 0, - event, &return_val); - return return_val; -} - -static gint -et_canvas_root_event (GnomeCanvasItem *root, - GdkEvent *event, - ETree *e_tree) -{ - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - if (event->button.button != 4 && event->button.button != 5) { - if (gtk_widget_has_focus (GTK_WIDGET (root->canvas))) { - GnomeCanvasItem *item = GNOME_CANVAS (root->canvas)->focused_item; - - if (E_IS_TABLE_ITEM (item)) { - e_table_item_leave_edit (E_TABLE_ITEM (item)); - return TRUE; - } - } - } - break; - default: - break; - } - - return FALSE; -} - -/* Handler for focus events in the table_canvas; we have to repaint ourselves - * and give the focus to some ETableItem. - */ -static gboolean -table_canvas_focus_event_cb (GtkWidget *widget, - GdkEventFocus *event, - gpointer data) -{ - GnomeCanvas *canvas; - ETree *tree; - - gtk_widget_queue_draw (widget); - - if (!event->in) - return TRUE; - - canvas = GNOME_CANVAS (widget); - tree = E_TREE (data); - - if (!canvas->focused_item || - (e_selection_model_cursor_row (tree->priv->selection) == -1)) { - e_table_item_set_cursor (E_TABLE_ITEM (tree->priv->item), 0, 0); - gnome_canvas_item_grab_focus (tree->priv->item); - } - - return TRUE; -} - -static void -e_tree_setup_table (ETree *e_tree) -{ - GtkWidget *widget; - GtkStyle *style; - - e_tree->priv->table_canvas = GNOME_CANVAS (e_canvas_new ()); - g_signal_connect ( - e_tree->priv->table_canvas, "size_allocate", - G_CALLBACK (tree_canvas_size_allocate), e_tree); - g_signal_connect ( - e_tree->priv->table_canvas, "focus_in_event", - G_CALLBACK (table_canvas_focus_event_cb), e_tree); - g_signal_connect ( - e_tree->priv->table_canvas, "focus_out_event", - G_CALLBACK (table_canvas_focus_event_cb), e_tree); - - g_signal_connect ( - e_tree->priv->table_canvas, "drag_begin", - G_CALLBACK (et_drag_begin), e_tree); - g_signal_connect ( - e_tree->priv->table_canvas, "drag_end", - G_CALLBACK (et_drag_end), e_tree); - g_signal_connect ( - e_tree->priv->table_canvas, "drag_data_get", - G_CALLBACK (et_drag_data_get), e_tree); - g_signal_connect ( - e_tree->priv->table_canvas, "drag_data_delete", - G_CALLBACK (et_drag_data_delete), e_tree); - g_signal_connect ( - e_tree, "drag_motion", - G_CALLBACK (et_drag_motion), e_tree); - g_signal_connect ( - e_tree, "drag_leave", - G_CALLBACK (et_drag_leave), e_tree); - g_signal_connect ( - e_tree, "drag_drop", - G_CALLBACK (et_drag_drop), e_tree); - g_signal_connect ( - e_tree, "drag_data_received", - G_CALLBACK (et_drag_data_received), e_tree); - - g_signal_connect ( - e_tree->priv->table_canvas, "reflow", - G_CALLBACK (tree_canvas_reflow), e_tree); - - widget = GTK_WIDGET (e_tree->priv->table_canvas); - style = gtk_widget_get_style (widget); - - gtk_widget_show (widget); - - e_tree->priv->white_item = gnome_canvas_item_new ( - gnome_canvas_root (e_tree->priv->table_canvas), - e_canvas_background_get_type (), - "fill_color_gdk", &style->base[GTK_STATE_NORMAL], - NULL); - - g_signal_connect ( - e_tree->priv->white_item, "event", - G_CALLBACK (white_item_event), e_tree); - g_signal_connect ( - gnome_canvas_root (e_tree->priv->table_canvas), "event", - G_CALLBACK (et_canvas_root_event), e_tree); - - et_build_item (e_tree); -} - -/** - * e_tree_set_search_column: - * @e_tree: #ETree object that will be modified - * @col: Column index to use for searches - * - * This routine sets the current search column to be used for keypress - * searches of the #ETree. If -1 is passed in for column, the current - * search column is cleared. - */ -void -e_tree_set_search_column (ETree *e_tree, - gint col) -{ - if (col == -1) { - clear_current_search_col (e_tree); - return; - } - - e_tree->priv->search_col_set = TRUE; - e_tree->priv->current_search_col = e_table_header_get_column ( - e_tree->priv->full_header, col); -} - -void -e_tree_set_state_object (ETree *e_tree, - ETableState *state) -{ - GValue *val; - GtkAllocation allocation; - GtkWidget *widget; - - val = g_new0 (GValue, 1); - g_value_init (val, G_TYPE_DOUBLE); - - connect_header (e_tree, state); - - widget = GTK_WIDGET (e_tree->priv->table_canvas); - gtk_widget_get_allocation (widget, &allocation); - - g_value_set_double (val, (gdouble) allocation.width); - g_object_set_property (G_OBJECT (e_tree->priv->header), "width", val); - g_free (val); - - if (e_tree->priv->header_item) - g_object_set ( - e_tree->priv->header_item, - "ETableHeader", e_tree->priv->header, - "sort_info", e_tree->priv->sort_info, - NULL); - - if (e_tree->priv->item) - g_object_set ( - e_tree->priv->item, - "ETableHeader", e_tree->priv->header, - NULL); - - if (e_tree->priv->etta) - e_tree_table_adapter_set_sort_info ( - e_tree->priv->etta, e_tree->priv->sort_info); - - e_tree_state_change (e_tree); -} - -/** - * e_tree_set_state: - * @e_tree: #ETree object that will be modified - * @state_str: a string with the XML representation of the #ETableState. - * - * This routine sets the state (as described by #ETableState) of the - * #ETree object. - */ -void -e_tree_set_state (ETree *e_tree, - const gchar *state_str) -{ - ETableState *state; - - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - g_return_if_fail (state_str != NULL); - - state = e_table_state_new (); - e_table_state_load_from_string (state, state_str); - - if (state->col_count > 0) - e_tree_set_state_object (e_tree, state); - - g_object_unref (state); -} - -/** - * e_tree_load_state: - * @e_tree: #ETree object that will be modified - * @filename: name of the file containing the state to be loaded into the #ETree - * - * An #ETableState will be loaded form the file pointed by @filename into the - * @e_tree object. - */ -void -e_tree_load_state (ETree *e_tree, - const gchar *filename) -{ - ETableState *state; - - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - g_return_if_fail (filename != NULL); - - state = e_table_state_new (); - e_table_state_load_from_file (state, filename); - - if (state->col_count > 0) - e_tree_set_state_object (e_tree, state); - - g_object_unref (state); -} - -/** - * e_tree_get_state_object: - * @e_tree: #ETree object to act on - * - * Builds an #ETableState corresponding to the current state of the - * #ETree. - * - * Return value: - * The %ETableState object generated. - **/ -ETableState * -e_tree_get_state_object (ETree *e_tree) -{ - ETableState *state; - gint full_col_count; - gint i, j; - - state = e_table_state_new (); - state->sort_info = e_tree->priv->sort_info; - if (state->sort_info) - g_object_ref (state->sort_info); - - state->col_count = e_table_header_count (e_tree->priv->header); - full_col_count = e_table_header_count (e_tree->priv->full_header); - state->columns = g_new (int, state->col_count); - state->expansions = g_new (double, state->col_count); - for (i = 0; i < state->col_count; i++) { - ETableCol *col = e_table_header_get_column (e_tree->priv->header, i); - state->columns[i] = -1; - for (j = 0; j < full_col_count; j++) { - if (col->col_idx == e_table_header_index (e_tree->priv->full_header, j)) { - state->columns[i] = j; - break; - } - } - state->expansions[i] = col->expansion; - } - - return state; -} - -/** - * e_tree_get_state: - * @e_tree: The #ETree to act on - * - * Builds a state object based on the current state and returns the - * string corresponding to that state. - * - * Return value: - * A string describing the current state of the #ETree. - **/ -gchar * -e_tree_get_state (ETree *e_tree) -{ - ETableState *state; - gchar *string; - - state = e_tree_get_state_object (e_tree); - string = e_table_state_save_to_string (state); - g_object_unref (state); - return string; -} - -/** - * e_tree_save_state: - * @e_tree: The #ETree to act on - * @filename: name of the file to save to - * - * Saves the state of the @e_tree object into the file pointed by - * @filename. - **/ -void -e_tree_save_state (ETree *e_tree, - const gchar *filename) -{ - ETableState *state; - - state = e_tree_get_state_object (e_tree); - e_table_state_save_to_file (state, filename); - g_object_unref (state); -} - -/** - * e_tree_get_spec: - * @e_tree: The #ETree to query - * - * Returns the specification object. - * - * Return value: - **/ -ETableSpecification * -e_tree_get_spec (ETree *e_tree) -{ - return e_tree->priv->spec; -} - -static void -et_table_model_changed (ETableModel *model, - ETree *et) -{ - if (et->priv->horizontal_scrolling) - e_table_header_update_horizontal (et->priv->header); -} - -static void -et_table_row_changed (ETableModel *table_model, - gint row, - ETree *et) -{ - et_table_model_changed (table_model, et); -} - -static void -et_table_cell_changed (ETableModel *table_model, - gint view_col, - gint row, - ETree *et) -{ - et_table_model_changed (table_model, et); -} - -static void -et_table_rows_deleted (ETableModel *table_model, - gint row, - gint count, - ETree *et) -{ - ETreePath * node, * prev_node; - - /* If the cursor is still valid after this deletion, we're done */ - if (e_selection_model_cursor_row (et->priv->selection) >= 0 - || row == 0) - return; - - prev_node = e_tree_node_at_row (et, row - 1); - node = e_tree_get_cursor (et); - - /* Check if the cursor is a child of the node directly before the - * deleted region (implying that an expander was collapsed with - * the cursor inside it) */ - while (node) { - node = e_tree_model_node_get_parent (et->priv->model, node); - if (node == prev_node) { - /* Set the cursor to the still-visible parent */ - e_tree_set_cursor (et, prev_node); - return; - } - } -} - -static void -et_connect_to_etta (ETree *et) -{ - et->priv->table_model_change_id = g_signal_connect ( - et->priv->etta, "model_changed", - G_CALLBACK (et_table_model_changed), et); - - et->priv->table_row_change_id = g_signal_connect ( - et->priv->etta, "model_row_changed", - G_CALLBACK (et_table_row_changed), et); - - et->priv->table_cell_change_id = g_signal_connect ( - et->priv->etta, "model_cell_changed", - G_CALLBACK (et_table_cell_changed), et); - - et->priv->table_rows_delete_id = g_signal_connect ( - et->priv->etta, "model_rows_deleted", - G_CALLBACK (et_table_rows_deleted), et); - -} - -static gboolean -et_real_construct (ETree *e_tree, - ETreeModel *etm, - ETableExtras *ete, - ETableSpecification *specification, - ETableState *state) -{ - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gint row = 0; - - if (ete) - g_object_ref (ete); - else - ete = e_table_extras_new (); - - e_tree->priv->alternating_row_colors = specification->alternating_row_colors; - e_tree->priv->horizontal_draw_grid = specification->horizontal_draw_grid; - e_tree->priv->vertical_draw_grid = specification->vertical_draw_grid; - e_tree->priv->draw_focus = specification->draw_focus; - e_tree->priv->cursor_mode = specification->cursor_mode; - e_tree->priv->full_header = e_table_spec_to_full_header (specification, ete); - - connect_header (e_tree, state); - - e_tree->priv->horizontal_scrolling = specification->horizontal_scrolling; - - e_tree->priv->model = etm; - g_object_ref (etm); - - e_tree->priv->etta = E_TREE_TABLE_ADAPTER ( - e_tree_table_adapter_new (e_tree->priv->model, - e_tree->priv->sort_info, e_tree->priv->full_header)); - - et_connect_to_etta (e_tree); - - e_tree->priv->sorter = e_sorter_new (); - - g_object_set ( - e_tree->priv->selection, - "sorter", e_tree->priv->sorter, -#ifdef E_TREE_USE_TREE_SELECTION - "model", e_tree->priv->model, - "etta", e_tree->priv->etta, -#else - "model", e_tree->priv->etta, -#endif - "selection_mode", specification->selection_mode, - "cursor_mode", specification->cursor_mode, - NULL); - - g_signal_connect ( - e_tree->priv->selection, "selection_changed", - G_CALLBACK (et_selection_model_selection_changed), e_tree); - g_signal_connect ( - e_tree->priv->selection, "selection_row_changed", - G_CALLBACK (et_selection_model_selection_row_changed), e_tree); - - if (!specification->no_headers) { - e_tree_setup_header (e_tree); - } - e_tree_setup_table (e_tree); - - scrollable = GTK_SCROLLABLE (e_tree->priv->table_canvas); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - gtk_adjustment_set_step_increment (adjustment, 20); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - gtk_adjustment_set_step_increment (adjustment, 20); - - if (!specification->no_headers) { - /* - * The header - */ - gtk_table_attach ( - GTK_TABLE (e_tree), - GTK_WIDGET (e_tree->priv->header_canvas), - 0, 1, 0 + row, 1 + row, - GTK_FILL | GTK_EXPAND, - GTK_FILL, 0, 0); - row++; - } - - gtk_table_attach ( - GTK_TABLE (e_tree), - GTK_WIDGET (e_tree->priv->table_canvas), - 0, 1, 0 + row, 1 + row, - GTK_FILL | GTK_EXPAND, - GTK_FILL | GTK_EXPAND, - 0, 0); - - g_object_unref (ete); - - return TRUE; -} - -/** - * e_tree_construct: - * @e_tree: The newly created #ETree object. - * @etm: The model for this table. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec_str: The spec. - * @state_str: An optional state. (%NULL is valid.) - * - * This is the internal implementation of e_tree_new() for use by - * subclasses or language bindings. See e_tree_new() for details. - * - * Return value: %TRUE on success, %FALSE if an error occurred - **/ -gboolean -e_tree_construct (ETree *e_tree, - ETreeModel *etm, - ETableExtras *ete, - const gchar *spec_str, - const gchar *state_str) -{ - ETableSpecification *specification; - ETableState *state; - - g_return_val_if_fail (e_tree != NULL, FALSE); - g_return_val_if_fail (E_IS_TREE (e_tree), FALSE); - g_return_val_if_fail (etm != NULL, FALSE); - g_return_val_if_fail (E_IS_TREE_MODEL (etm), FALSE); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), FALSE); - g_return_val_if_fail (spec_str != NULL, FALSE); - - specification = e_table_specification_new (); - if (!e_table_specification_load_from_string (specification, spec_str)) { - g_object_unref (specification); - return FALSE; - } - if (state_str) { - state = e_table_state_new (); - e_table_state_load_from_string (state, state_str); - if (state->col_count <= 0) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - } else { - state = specification->state; - g_object_ref (state); - } - - if (!et_real_construct (e_tree, etm, ete, specification, state)) { - g_object_unref (specification); - g_object_unref (state); - return FALSE; - } - - e_tree->priv->spec = specification; - e_tree->priv->spec->allow_grouping = FALSE; - - g_object_unref (state); - - return TRUE; -} - -/** - * e_tree_construct_from_spec_file: - * @e_tree: The newly created #ETree object. - * @etm: The model for this tree - * @ete: An optional #ETableExtras (%NULL is valid.) - * @spec_fn: The filename of the spec - * @state_fn: An optional state file (%NULL is valid.) - * - * This is the internal implementation of e_tree_new_from_spec_file() - * for use by subclasses or language bindings. See - * e_tree_new_from_spec_file() for details. - * - * Return value: %TRUE on success, %FALSE if an error occurred - **/ -gboolean -e_tree_construct_from_spec_file (ETree *e_tree, - ETreeModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn) -{ - ETableSpecification *specification; - ETableState *state; - - g_return_val_if_fail (e_tree != NULL, FALSE); - g_return_val_if_fail (E_IS_TREE (e_tree), FALSE); - g_return_val_if_fail (etm != NULL, FALSE); - g_return_val_if_fail (E_IS_TREE_MODEL (etm), FALSE); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), FALSE); - g_return_val_if_fail (spec_fn != NULL, FALSE); - - specification = e_table_specification_new (); - if (!e_table_specification_load_from_file (specification, spec_fn)) { - g_object_unref (specification); - return FALSE; - } - if (state_fn) { - state = e_table_state_new (); - if (!e_table_state_load_from_file (state, state_fn)) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - if (state->col_count <= 0) { - g_object_unref (state); - state = specification->state; - g_object_ref (state); - } - } else { - state = specification->state; - g_object_ref (state); - } - - if (!et_real_construct (e_tree, etm, ete, specification, state)) { - g_object_unref (specification); - g_object_unref (state); - return FALSE; - } - - e_tree->priv->spec = specification; - e_tree->priv->spec->allow_grouping = FALSE; - - g_object_unref (state); - - return TRUE; -} - -/** - * e_tree_new: - * @etm: The model for this tree - * @ete: An optional #ETableExtras (%NULL is valid.) - * @spec: The spec - * @state: An optional state (%NULL is valid.) - * - * This function creates an #ETree from the given parameters. The - * #ETreeModel is a tree model to be represented. The #ETableExtras - * is an optional set of pixbufs, cells, and sorting functions to be - * used when interpreting the spec. If you pass in %NULL it uses the - * default #ETableExtras. (See e_table_extras_new()). - * - * @spec is the specification of the set of viewable columns and the - * default sorting state and such. @state is an optional string - * specifying the current sorting state and such. If @state is NULL, - * then the default state from the spec will be used. - * - * Return value: - * The newly created #ETree or %NULL if there's an error. - **/ -GtkWidget * -e_tree_new (ETreeModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state) -{ - ETree *e_tree; - - g_return_val_if_fail (etm != NULL, NULL); - g_return_val_if_fail (E_IS_TREE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec != NULL, NULL); - - e_tree = g_object_new (E_TYPE_TREE, NULL); - - if (!e_tree_construct (e_tree, etm, ete, spec, state)) { - g_object_unref (e_tree); - return NULL; - } - - return (GtkWidget *) e_tree; -} - -/** - * e_tree_new_from_spec_file: - * @etm: The model for this tree. - * @ete: An optional #ETableExtras. (%NULL is valid.) - * @spec_fn: The filename of the spec. - * @state_fn: An optional state file. (%NULL is valid.) - * - * This is very similar to e_tree_new(), except instead of passing in - * strings you pass in the file names of the spec and state to load. - * - * @spec_fn is the filename of the spec to load. If this file doesn't - * exist, e_tree_new_from_spec_file will return %NULL. - * - * @state_fn is the filename of the initial state to load. If this is - * %NULL or if the specified file doesn't exist, the default state - * from the spec file is used. - * - * Return value: - * The newly created #ETree or %NULL if there's an error. - **/ -GtkWidget * -e_tree_new_from_spec_file (ETreeModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn) -{ - ETree *e_tree; - - g_return_val_if_fail (etm != NULL, NULL); - g_return_val_if_fail (E_IS_TREE_MODEL (etm), NULL); - g_return_val_if_fail (ete == NULL || E_IS_TABLE_EXTRAS (ete), NULL); - g_return_val_if_fail (spec_fn != NULL, NULL); - - e_tree = g_object_new (E_TYPE_TREE, NULL); - - if (!e_tree_construct_from_spec_file (e_tree, etm, ete, spec_fn, state_fn)) { - g_object_unref (e_tree); - return NULL; - } - - return (GtkWidget *) e_tree; -} - -void -e_tree_show_cursor_after_reflow (ETree *e_tree) -{ - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - - e_tree->priv->show_cursor_after_reflow = TRUE; -} - -void -e_tree_set_cursor (ETree *e_tree, - ETreePath path) -{ -#ifndef E_TREE_USE_TREE_SELECTION - gint row; -#endif - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - g_return_if_fail (path != NULL); - -#ifdef E_TREE_USE_TREE_SELECTION - e_tree_selection_model_select_single_path ( - E_TREE_SELECTION_MODEL (e_tree->priv->selection), path); - e_tree_selection_model_change_cursor ( - E_TREE_SELECTION_MODEL (e_tree->priv->selection), path); -#else - row = e_tree_table_adapter_row_of_node ( - E_TREE_TABLE_ADAPTER (e_tree->priv->etta), path); - - if (row == -1) - return; - - g_object_set ( - e_tree->priv->selection, - "cursor_row", row, - NULL); -#endif -} - -ETreePath -e_tree_get_cursor (ETree *e_tree) -{ -#ifdef E_TREE_USE_TREE_SELECTION - return e_tree_selection_model_get_cursor ( - E_TREE_SELECTION_MODEL (e_tree->priv->selection)); -#else - gint row; - g_return_val_if_fail (e_tree != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (e_tree), NULL); - - g_object_get ( - e_tree->priv->selection, - "cursor_row", &row, - NULL); - if (row == -1) - return NULL; - - return e_tree_table_adapter_node_at_row ( - E_TREE_TABLE_ADAPTER (e_tree->priv->etta), row); -#endif -} - -void -e_tree_selected_row_foreach (ETree *e_tree, - EForeachFunc callback, - gpointer closure) -{ - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - - e_selection_model_foreach (e_tree->priv->selection, - callback, - closure); -} - -#ifdef E_TREE_USE_TREE_SELECTION -void -e_tree_selected_path_foreach (ETree *e_tree, - ETreeForeachFunc callback, - gpointer closure) -{ - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - - e_tree_selection_model_foreach ( - E_TREE_SELECTION_MODEL (e_tree->priv->selection), - callback, closure); -} - -/* Standard functions */ -static void -et_foreach_recurse (ETreeModel *model, - ETreePath path, - ETreeForeachFunc callback, - gpointer closure) -{ - ETreePath child; - - callback (path, closure); - - child = e_tree_model_node_get_first_child (E_TREE_MODEL (model), path); - for (; child; child = e_tree_model_node_get_next (E_TREE_MODEL (model), child)) - if (child) - et_foreach_recurse (model, child, callback, closure); -} - -void -e_tree_path_foreach (ETree *e_tree, - ETreeForeachFunc callback, - gpointer closure) -{ - ETreePath root; - - g_return_if_fail (e_tree != NULL); - g_return_if_fail (E_IS_TREE (e_tree)); - - root = e_tree_model_get_root (e_tree->priv->model); - - if (root) - et_foreach_recurse (e_tree->priv->model, - root, - callback, - closure); -} -#endif - -EPrintable * -e_tree_get_printable (ETree *e_tree) -{ - g_return_val_if_fail (e_tree != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (e_tree), NULL); - - return e_table_item_get_printable (E_TABLE_ITEM (e_tree->priv->item)); -} - -static void -et_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ETree *etree = E_TREE (object); - - switch (property_id) { - case PROP_ETTA: - g_value_set_object (value, etree->priv->etta); - break; - - case PROP_UNIFORM_ROW_HEIGHT: - g_value_set_boolean (value, etree->priv->uniform_row_height); - break; - - case PROP_ALWAYS_SEARCH: - g_value_set_boolean (value, etree->priv->always_search); - break; - - case PROP_HADJUSTMENT: - if (etree->priv->table_canvas) - g_object_get_property ( - G_OBJECT (etree->priv->table_canvas), - "hadjustment", value); - else - g_value_set_object (value, NULL); - break; - - case PROP_VADJUSTMENT: - if (etree->priv->table_canvas) - g_object_get_property ( - G_OBJECT (etree->priv->table_canvas), - "vadjustment", value); - else - g_value_set_object (value, NULL); - break; - - case PROP_HSCROLL_POLICY: - if (etree->priv->table_canvas) - g_object_get_property ( - G_OBJECT (etree->priv->table_canvas), - "hscroll-policy", value); - else - g_value_set_enum (value, 0); - break; - - case PROP_VSCROLL_POLICY: - if (etree->priv->table_canvas) - g_object_get_property ( - G_OBJECT (etree->priv->table_canvas), - "vscroll-policy", value); - else - g_value_set_enum (value, 0); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -typedef struct { - gchar *arg; - gboolean setting; -} bool_closure; - -static void -et_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ETree *etree = E_TREE (object); - - switch (property_id) { - case PROP_LENGTH_THRESHOLD: - etree->priv->length_threshold = g_value_get_int (value); - if (etree->priv->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etree->priv->item), - "length_threshold", - etree->priv->length_threshold, - NULL); - } - break; - - case PROP_HORIZONTAL_DRAW_GRID: - etree->priv->horizontal_draw_grid = g_value_get_boolean (value); - if (etree->priv->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etree->priv->item), - "horizontal_draw_grid", - etree->priv->horizontal_draw_grid, - NULL); - } - break; - - case PROP_VERTICAL_DRAW_GRID: - etree->priv->vertical_draw_grid = g_value_get_boolean (value); - if (etree->priv->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etree->priv->item), - "vertical_draw_grid", - etree->priv->vertical_draw_grid, - NULL); - } - break; - - case PROP_DRAW_FOCUS: - etree->priv->draw_focus = g_value_get_boolean (value); - if (etree->priv->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etree->priv->item), - "drawfocus", - etree->priv->draw_focus, - NULL); - } - break; - - case PROP_UNIFORM_ROW_HEIGHT: - etree->priv->uniform_row_height = g_value_get_boolean (value); - if (etree->priv->item) { - gnome_canvas_item_set ( - GNOME_CANVAS_ITEM (etree->priv->item), - "uniform_row_height", - etree->priv->uniform_row_height, - NULL); - } - break; - - case PROP_ALWAYS_SEARCH: - if (etree->priv->always_search == g_value_get_boolean (value)) - return; - etree->priv->always_search = g_value_get_boolean (value); - clear_current_search_col (etree); - break; - - case PROP_HADJUSTMENT: - if (etree->priv->table_canvas) - g_object_set_property ( - G_OBJECT (etree->priv->table_canvas), - "hadjustment", value); - break; - - case PROP_VADJUSTMENT: - if (etree->priv->table_canvas) - g_object_set_property ( - G_OBJECT (etree->priv->table_canvas), - "vadjustment", value); - break; - - case PROP_HSCROLL_POLICY: - if (etree->priv->table_canvas) - g_object_set_property ( - G_OBJECT (etree->priv->table_canvas), - "hscroll-policy", value); - break; - - case PROP_VSCROLL_POLICY: - if (etree->priv->table_canvas) - g_object_set_property ( - G_OBJECT (etree->priv->table_canvas), - "vscroll-policy", value); - break; - } -} - -gint -e_tree_get_next_row (ETree *e_tree, - gint model_row) -{ - g_return_val_if_fail (e_tree != NULL, -1); - g_return_val_if_fail (E_IS_TREE (e_tree), -1); - - if (e_tree->priv->sorter) { - gint i; - i = e_sorter_model_to_sorted (E_SORTER (e_tree->priv->sorter), model_row); - i++; - if (i < e_table_model_row_count (E_TABLE_MODEL (e_tree->priv->etta))) { - return e_sorter_sorted_to_model (E_SORTER (e_tree->priv->sorter), i); - } else - return -1; - } else { - gint row_count; - - row_count = e_table_model_row_count ( - E_TABLE_MODEL (e_tree->priv->etta)); - - if (model_row < row_count - 1) - return model_row + 1; - else - return -1; - } -} - -gint -e_tree_get_prev_row (ETree *e_tree, - gint model_row) -{ - g_return_val_if_fail (e_tree != NULL, -1); - g_return_val_if_fail (E_IS_TREE (e_tree), -1); - - if (e_tree->priv->sorter) { - gint i; - i = e_sorter_model_to_sorted (E_SORTER (e_tree->priv->sorter), model_row); - i--; - if (i >= 0) - return e_sorter_sorted_to_model (E_SORTER (e_tree->priv->sorter), i); - else - return -1; - } else - return model_row - 1; -} - -gint -e_tree_model_to_view_row (ETree *e_tree, - gint model_row) -{ - g_return_val_if_fail (e_tree != NULL, -1); - g_return_val_if_fail (E_IS_TREE (e_tree), -1); - - if (e_tree->priv->sorter) - return e_sorter_model_to_sorted (E_SORTER (e_tree->priv->sorter), model_row); - else - return model_row; -} - -gint -e_tree_view_to_model_row (ETree *e_tree, - gint view_row) -{ - g_return_val_if_fail (e_tree != NULL, -1); - g_return_val_if_fail (E_IS_TREE (e_tree), -1); - - if (e_tree->priv->sorter) - return e_sorter_sorted_to_model (E_SORTER (e_tree->priv->sorter), view_row); - else - return view_row; -} - -gboolean -e_tree_node_is_expanded (ETree *et, - ETreePath path) -{ - g_return_val_if_fail (path, FALSE); - - return e_tree_table_adapter_node_is_expanded (et->priv->etta, path); -} - -void -e_tree_node_set_expanded (ETree *et, - ETreePath path, - gboolean expanded) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - - e_tree_table_adapter_node_set_expanded (et->priv->etta, path, expanded); -} - -void -e_tree_node_set_expanded_recurse (ETree *et, - ETreePath path, - gboolean expanded) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - - e_tree_table_adapter_node_set_expanded_recurse (et->priv->etta, path, expanded); -} - -void -e_tree_root_node_set_visible (ETree *et, - gboolean visible) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - - e_tree_table_adapter_root_node_set_visible (et->priv->etta, visible); -} - -ETreePath -e_tree_node_at_row (ETree *et, - gint row) -{ - ETreePath path = { 0 }; - - g_return_val_if_fail (et != NULL, path); - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - return path; -} - -gint -e_tree_row_of_node (ETree *et, - ETreePath path) -{ - g_return_val_if_fail (et != NULL, -1); - - return e_tree_table_adapter_row_of_node (et->priv->etta, path); -} - -gboolean -e_tree_root_node_is_visible (ETree *et) -{ - g_return_val_if_fail (et != NULL, FALSE); - - return e_tree_table_adapter_root_node_is_visible (et->priv->etta); -} - -void -e_tree_show_node (ETree *et, - ETreePath path) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - - e_tree_table_adapter_show_node (et->priv->etta, path); -} - -void -e_tree_save_expanded_state (ETree *et, - gchar *filename) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - - e_tree_table_adapter_save_expanded_state (et->priv->etta, filename); -} - -void -e_tree_load_expanded_state (ETree *et, - gchar *filename) -{ - g_return_if_fail (et != NULL); - - e_tree_table_adapter_load_expanded_state (et->priv->etta, filename); -} - -xmlDoc * -e_tree_save_expanded_state_xml (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return e_tree_table_adapter_save_expanded_state_xml (et->priv->etta); -} - -void -e_tree_load_expanded_state_xml (ETree *et, - xmlDoc *doc) -{ - g_return_if_fail (et != NULL); - g_return_if_fail (E_IS_TREE (et)); - g_return_if_fail (doc != NULL); - - e_tree_table_adapter_load_expanded_state_xml (et->priv->etta, doc); -} - -/* state: <0 ... collapse; 0 ... no force - use default; >0 ... expand; - * when using this, be sure to reset to 0 once no forcing is required - * anymore, aka the build of the tree is done */ -void -e_tree_force_expanded_state (ETree *et, - gint state) -{ - g_return_if_fail (et != NULL); - - e_tree_table_adapter_force_expanded_state (et->priv->etta, state); -} - -gint -e_tree_row_count (ETree *et) -{ - g_return_val_if_fail (et != NULL, -1); - - return e_table_model_row_count (E_TABLE_MODEL (et->priv->etta)); -} - -GtkWidget * -e_tree_get_tooltip (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - - return E_CANVAS (et->priv->table_canvas)->tooltip_window; -} - -static ETreePath -find_next_in_range (ETree *et, - gint start, - gint end, - ETreePathFunc func, - gpointer data) -{ - ETreePath path; - gint row; - - for (row = start; row <= end; row++) { - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - if (path && func (et->priv->model, path, data)) - return path; - } - - return NULL; -} - -static ETreePath -find_prev_in_range (ETree *et, - gint start, - gint end, - ETreePathFunc func, - gpointer data) -{ - ETreePath path; - gint row; - - for (row = start; row >= end; row--) { - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - if (path && func (et->priv->model, path, data)) - return path; - } - - return NULL; -} - -gboolean -e_tree_find_next (ETree *et, - ETreeFindNextParams params, - ETreePathFunc func, - gpointer data) -{ - ETreePath cursor, found; - gint row, row_count; - - cursor = e_tree_get_cursor (et); - row = e_tree_table_adapter_row_of_node (et->priv->etta, cursor); - row_count = e_table_model_row_count (E_TABLE_MODEL (et->priv->etta)); - - if (params & E_TREE_FIND_NEXT_FORWARD) - found = find_next_in_range (et, row + 1, row_count - 1, func, data); - else - found = find_prev_in_range (et, row == -1 ? -1 : row - 1, 0, func, data); - - if (found) { - e_tree_table_adapter_show_node (et->priv->etta, found); - e_tree_set_cursor (et, found); - return TRUE; - } - - if (params & E_TREE_FIND_NEXT_WRAP) { - if (params & E_TREE_FIND_NEXT_FORWARD) - found = find_next_in_range (et, 0, row, func, data); - else - found = find_prev_in_range (et, row_count - 1, row, func, data); - - if (found && found != cursor) { - e_tree_table_adapter_show_node (et->priv->etta, found); - e_tree_set_cursor (et, found); - return TRUE; - } - } - - return FALSE; -} - -void -e_tree_right_click_up (ETree *et) -{ - e_selection_model_right_click_up (et->priv->selection); -} - -/** - * e_tree_get_model: - * @et: the ETree - * - * Returns the model upon which this ETree is based. - * - * Returns: the model - **/ -ETreeModel * -e_tree_get_model (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return et->priv->model; -} - -/** - * e_tree_get_selection_model: - * @et: the ETree - * - * Returns the selection model of this ETree. - * - * Returns: the selection model - **/ -ESelectionModel * -e_tree_get_selection_model (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return et->priv->selection; -} - -/** - * e_tree_get_table_adapter: - * @et: the ETree - * - * Returns the table adapter this ETree uses. - * - * Returns: the model - **/ -ETreeTableAdapter * -e_tree_get_table_adapter (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return et->priv->etta; -} - -ETableItem * -e_tree_get_item (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return E_TABLE_ITEM (et->priv->item); -} - -GnomeCanvasItem * -e_tree_get_header_item (ETree *et) -{ - g_return_val_if_fail (et != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (et), NULL); - - return et->priv->header_item; -} - -struct _ETreeDragSourceSite -{ - GdkModifierType start_button_mask; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction actions; /* Possible actions */ - GdkPixbuf *pixbuf; /* Icon for drag data */ - - /* Stored button press information to detect drag beginning */ - gint state; - gint x, y; - gint row, col; -}; - -typedef enum -{ - GTK_DRAG_STATUS_DRAG, - GTK_DRAG_STATUS_WAIT, - GTK_DRAG_STATUS_DROP -} GtkDragStatus; - -typedef struct _GtkDragDestInfo GtkDragDestInfo; -typedef struct _GtkDragSourceInfo GtkDragSourceInfo; - -struct _GtkDragDestInfo -{ - GtkWidget *widget; /* Widget in which drag is in */ - GdkDragContext *context; /* Drag context */ - GtkDragSourceInfo *proxy_source; /* Set if this is a proxy drag */ - GtkSelectionData *proxy_data; /* Set while retrieving proxied data */ - guint dropped : 1; /* Set after we receive a drop */ - guint32 proxy_drop_time; /* Timestamp for proxied drop */ - guint proxy_drop_wait : 1; /* Set if we are waiting for a - * status reply before sending - * a proxied drop on. - */ - gint drop_x, drop_y; /* Position of drop */ -}; - -struct _GtkDragSourceInfo -{ - GtkWidget *widget; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction possible_actions; /* Actions allowed by source */ - GdkDragContext *context; /* drag context */ - GtkWidget *icon_window; /* Window for drag */ - GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ - GdkCursor *cursor; /* Cursor for drag */ - gint hot_x, hot_y; /* Hot spot for drag */ - gint button; /* mouse button starting drag */ - - GtkDragStatus status; /* drag status */ - GdkEvent *last_event; /* motion event waiting for response */ - - gint start_x, start_y; /* Initial position */ - gint cur_x, cur_y; /* Current Position */ - - GList *selections; /* selections we've claimed */ - - GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ - - guint drop_timeout; /* Timeout for aborting drop */ - guint destroy_icon : 1; /* If true, destroy icon_window - */ -}; - -/* Drag & drop stuff. */ -/* Target */ - -void -e_tree_drag_get_data (ETree *tree, - gint row, - gint col, - GdkDragContext *context, - GdkAtom target, - guint32 time) -{ - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - gtk_drag_get_data ( - GTK_WIDGET (tree), - context, - target, - time); - -} - -/** - * e_tree_drag_highlight: - * @tree: - * @row: - * @col: - * - * Set col to -1 to highlight the entire row. - * Set row to -1 to turn off the highlight. - */ -void -e_tree_drag_highlight (ETree *tree, - gint row, - gint col) -{ - GtkAllocation allocation; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - GtkStyle *style; - - g_return_if_fail (E_IS_TREE (tree)); - - scrollable = GTK_SCROLLABLE (tree->priv->table_canvas); - style = gtk_widget_get_style (GTK_WIDGET (tree)); - gtk_widget_get_allocation (GTK_WIDGET (scrollable), &allocation); - - if (row != -1) { - gint x, y, width, height; - if (col == -1) { - e_tree_get_cell_geometry (tree, row, 0, &x, &y, &width, &height); - x = 0; - width = allocation.width; - } else { - e_tree_get_cell_geometry (tree, row, col, &x, &y, &width, &height); - adjustment = gtk_scrollable_get_hadjustment (scrollable); - x += gtk_adjustment_get_value (adjustment); - } - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - y += gtk_adjustment_get_value (adjustment); - - if (tree->priv->drop_highlight == NULL) { - tree->priv->drop_highlight = gnome_canvas_item_new ( - gnome_canvas_root (tree->priv->table_canvas), - gnome_canvas_rect_get_type (), - "fill_color", NULL, - "outline_color_gdk", &style->fg[GTK_STATE_NORMAL], - NULL); - } - - gnome_canvas_item_set ( - tree->priv->drop_highlight, - "x1", (gdouble) x, - "x2", (gdouble) x + width - 1, - "y1", (gdouble) y, - "y2", (gdouble) y + height - 1, - NULL); - } else { - g_object_run_dispose (G_OBJECT (tree->priv->drop_highlight)); - tree->priv->drop_highlight = NULL; - } -} - -void -e_tree_drag_unhighlight (ETree *tree) -{ - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - if (tree->priv->drop_highlight) { - g_object_run_dispose (G_OBJECT (tree->priv->drop_highlight)); - tree->priv->drop_highlight = NULL; - } -} - -void e_tree_drag_dest_set (ETree *tree, - GtkDestDefaults flags, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - gtk_drag_dest_set ( - GTK_WIDGET (tree), - flags, - targets, - n_targets, - actions); -} - -void e_tree_drag_dest_set_proxy (ETree *tree, - GdkWindow *proxy_window, - GdkDragProtocol protocol, - gboolean use_coordinates) -{ - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - gtk_drag_dest_set_proxy ( - GTK_WIDGET (tree), - proxy_window, - protocol, - use_coordinates); -} - -/* - * There probably should be functions for setting the targets - * as a GtkTargetList - */ - -void -e_tree_drag_dest_unset (GtkWidget *widget) -{ - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_TREE (widget)); - - gtk_drag_dest_unset (widget); -} - -/* Source side */ - -static gint -et_real_start_drag (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkEvent *event) -{ - GtkDragSourceInfo *info; - GdkDragContext *context; - ETreeDragSourceSite *site; - - if (tree->priv->do_drag) { - site = tree->priv->site; - - site->state = 0; - context = e_tree_drag_begin ( - tree, row, col, - site->target_list, - site->actions, - 1, event); - - if (context) { - info = g_dataset_get_data (context, "gtk-info"); - - if (info && !info->icon_window) { - if (site->pixbuf) - gtk_drag_set_icon_pixbuf ( - context, - site->pixbuf, - -2, -2); - else - gtk_drag_set_icon_default (context); - } - } - return TRUE; - } - return FALSE; -} - -void -e_tree_drag_source_set (ETree *tree, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions) -{ - ETreeDragSourceSite *site; - GtkWidget *canvas; - - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - canvas = GTK_WIDGET (tree->priv->table_canvas); - site = tree->priv->site; - - tree->priv->do_drag = TRUE; - - gtk_widget_add_events ( - canvas, - gtk_widget_get_events (canvas) | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_MOTION_MASK | GDK_STRUCTURE_MASK); - - if (site) { - if (site->target_list) - gtk_target_list_unref (site->target_list); - } else { - site = g_new0 (ETreeDragSourceSite, 1); - tree->priv->site = site; - } - - site->start_button_mask = start_button_mask; - - if (targets) - site->target_list = gtk_target_list_new (targets, n_targets); - else - site->target_list = NULL; - - site->actions = actions; -} - -void -e_tree_drag_source_unset (ETree *tree) -{ - ETreeDragSourceSite *site; - - g_return_if_fail (tree != NULL); - g_return_if_fail (E_IS_TREE (tree)); - - site = tree->priv->site; - - if (site) { - if (site->target_list) - gtk_target_list_unref (site->target_list); - g_free (site); - tree->priv->site = NULL; - } -} - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ - -GdkDragContext * -e_tree_drag_begin (ETree *tree, - gint row, - gint col, - GtkTargetList *targets, - GdkDragAction actions, - gint button, - GdkEvent *event) -{ - ETreePath path; - g_return_val_if_fail (tree != NULL, NULL); - g_return_val_if_fail (E_IS_TREE (tree), NULL); - - path = e_tree_table_adapter_node_at_row (tree->priv->etta, row); - - tree->priv->drag_row = row; - tree->priv->drag_path = path; - tree->priv->drag_col = col; - - return gtk_drag_begin ( - GTK_WIDGET (tree->priv->table_canvas), - targets, - actions, - button, - event); -} - -/** - * e_tree_is_dragging: - * @tree: An #ETree widget - * - * Returns whether is @tree in a drag&drop operation. - **/ -gboolean -e_tree_is_dragging (ETree *tree) -{ - g_return_val_if_fail (tree != NULL, FALSE); - g_return_val_if_fail (tree->priv != NULL, FALSE); - - return tree->priv->is_dragging; -} - -/** - * e_tree_get_cell_at: - * @tree: An ETree widget - * @x: X coordinate for the pixel - * @y: Y coordinate for the pixel - * @row_return: Pointer to return the row value - * @col_return: Pointer to return the column value - * - * Return the row and column for the cell in which the pixel at (@x, @y) is - * contained. - **/ -void -e_tree_get_cell_at (ETree *tree, - gint x, - gint y, - gint *row_return, - gint *col_return) -{ - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - - g_return_if_fail (E_IS_TREE (tree)); - g_return_if_fail (row_return != NULL); - g_return_if_fail (col_return != NULL); - - /* FIXME it would be nice if it could handle a NULL row_return or - * col_return gracefully. */ - - if (row_return) - *row_return = -1; - if (col_return) - *col_return = -1; - - scrollable = GTK_SCROLLABLE (tree->priv->table_canvas); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - x += gtk_adjustment_get_value (adjustment); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - y += gtk_adjustment_get_value (adjustment); - - e_table_item_compute_location ( - E_TABLE_ITEM (tree->priv->item), - &x, &y, row_return, col_return); -} - -/** - * e_tree_get_cell_geometry: - * @tree: The tree. - * @row: The row to get the geometry of. - * @col: The col to get the geometry of. - * @x_return: Returns the x coordinate of the upper right hand corner - * of the cell with respect to the widget. - * @y_return: Returns the y coordinate of the upper right hand corner - * of the cell with respect to the widget. - * @width_return: Returns the width of the cell. - * @height_return: Returns the height of the cell. - * - * Computes the data about this cell. - **/ -void -e_tree_get_cell_geometry (ETree *tree, - gint row, - gint col, - gint *x_return, - gint *y_return, - gint *width_return, - gint *height_return) -{ - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - - g_return_if_fail (E_IS_TREE (tree)); - g_return_if_fail (row >= 0); - g_return_if_fail (col >= 0); - - /* FIXME it would be nice if it could handle a NULL row_return or - * col_return gracefully. */ - - e_table_item_get_cell_geometry ( - E_TABLE_ITEM (tree->priv->item), - &row, &col, x_return, y_return, - width_return, height_return); - - scrollable = GTK_SCROLLABLE (tree->priv->table_canvas); - - if (x_return) { - adjustment = gtk_scrollable_get_hadjustment (scrollable); - (*x_return) -= gtk_adjustment_get_value (adjustment); - } - - if (y_return) { - adjustment = gtk_scrollable_get_vadjustment (scrollable); - (*y_return) -= gtk_adjustment_get_value (adjustment); - } -} - -static void -et_drag_begin (GtkWidget *widget, - GdkDragContext *context, - ETree *et) -{ - et->priv->is_dragging = TRUE; - - g_signal_emit ( - et, - et_signals[TREE_DRAG_BEGIN], 0, - et->priv->drag_row, - et->priv->drag_path, - et->priv->drag_col, - context); -} - -static void -et_drag_end (GtkWidget *widget, - GdkDragContext *context, - ETree *et) -{ - et->priv->is_dragging = FALSE; - - g_signal_emit ( - et, - et_signals[TREE_DRAG_END], 0, - et->priv->drag_row, - et->priv->drag_path, - et->priv->drag_col, - context); -} - -static void -et_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - ETree *et) -{ - g_signal_emit ( - et, - et_signals[TREE_DRAG_DATA_GET], 0, - et->priv->drag_row, - et->priv->drag_path, - et->priv->drag_col, - context, - selection_data, - info, - time); -} - -static void -et_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - ETree *et) -{ - g_signal_emit ( - et, - et_signals[TREE_DRAG_DATA_DELETE], 0, - et->priv->drag_row, - et->priv->drag_path, - et->priv->drag_col, - context); -} - -static gboolean -do_drag_motion (ETree *et, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - gboolean ret_val = FALSE; - gint row, col; - ETreePath path; - - e_tree_get_cell_at (et, x, y, &row, &col); - - if (row != et->priv->drop_row && col != et->priv->drop_col) { - g_signal_emit ( - et, et_signals[TREE_DRAG_LEAVE], 0, - et->priv->drop_row, - et->priv->drop_path, - et->priv->drop_col, - context, - time); - } - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - et->priv->drop_row = row; - et->priv->drop_path = path; - et->priv->drop_col = col; - g_signal_emit ( - et, et_signals[TREE_DRAG_MOTION], 0, - et->priv->drop_row, - et->priv->drop_path, - et->priv->drop_col, - context, - x, y, - time, - &ret_val); - - return ret_val; -} - -static gboolean -scroll_timeout (gpointer data) -{ - ETree *et = data; - gint dx = 0, dy = 0; - GtkAdjustment *adjustment; - GtkScrollable *scrollable; - gdouble old_h_value; - gdouble new_h_value; - gdouble old_v_value; - gdouble new_v_value; - gdouble page_size; - gdouble lower; - gdouble upper; - - if (et->priv->scroll_direction & ET_SCROLL_DOWN) - dy += 20; - if (et->priv->scroll_direction & ET_SCROLL_UP) - dy -= 20; - - if (et->priv->scroll_direction & ET_SCROLL_RIGHT) - dx += 20; - if (et->priv->scroll_direction & ET_SCROLL_LEFT) - dx -= 20; - - scrollable = GTK_SCROLLABLE (et->priv->table_canvas); - - adjustment = gtk_scrollable_get_hadjustment (scrollable); - - page_size = gtk_adjustment_get_page_size (adjustment); - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - - old_h_value = gtk_adjustment_get_value (adjustment); - new_h_value = CLAMP (old_h_value + dx, lower, upper - page_size); - - gtk_adjustment_set_value (adjustment, new_h_value); - - adjustment = gtk_scrollable_get_vadjustment (scrollable); - - page_size = gtk_adjustment_get_page_size (adjustment); - lower = gtk_adjustment_get_lower (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - - old_v_value = gtk_adjustment_get_value (adjustment); - new_v_value = CLAMP (old_v_value + dy, lower, upper - page_size); - - gtk_adjustment_set_value (adjustment, new_v_value); - - if (new_h_value != old_h_value || new_v_value != old_v_value) - do_drag_motion ( - et, - et->priv->last_drop_context, - et->priv->last_drop_x, - et->priv->last_drop_y, - et->priv->last_drop_time); - - return TRUE; -} - -static void -scroll_on (ETree *et, - guint scroll_direction) -{ - if (et->priv->scroll_idle_id == 0 || - scroll_direction != et->priv->scroll_direction) { - if (et->priv->scroll_idle_id != 0) - g_source_remove (et->priv->scroll_idle_id); - et->priv->scroll_direction = scroll_direction; - et->priv->scroll_idle_id = g_timeout_add (100, scroll_timeout, et); - } -} - -static void -scroll_off (ETree *et) -{ - if (et->priv->scroll_idle_id) { - g_source_remove (et->priv->scroll_idle_id); - et->priv->scroll_idle_id = 0; - } -} - -static gboolean -hover_timeout (gpointer data) -{ - ETree *et = data; - gint x = et->priv->hover_x; - gint y = et->priv->hover_y; - gint row, col; - ETreePath path; - - e_tree_get_cell_at (et, x, y, &row, &col); - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - if (path && e_tree_model_node_is_expandable (et->priv->model, path)) { - if (!e_tree_table_adapter_node_is_expanded (et->priv->etta, path)) { - if (e_tree_model_has_save_id (et->priv->model) && - e_tree_model_has_get_node_by_id (et->priv->model)) - et->priv->expanded_list = g_list_prepend ( - et->priv->expanded_list, - e_tree_model_get_save_id ( - et->priv->model, path)); - - e_tree_table_adapter_node_set_expanded ( - et->priv->etta, path, TRUE); - } - } - - return TRUE; -} - -static void -hover_on (ETree *et, - gint x, - gint y) -{ - et->priv->hover_x = x; - et->priv->hover_y = y; - if (et->priv->hover_idle_id != 0) - g_source_remove (et->priv->hover_idle_id); - et->priv->hover_idle_id = g_timeout_add (500, hover_timeout, et); -} - -static void -hover_off (ETree *et) -{ - if (et->priv->hover_idle_id) { - g_source_remove (et->priv->hover_idle_id); - et->priv->hover_idle_id = 0; - } -} - -static void -collapse_drag (ETree *et, - ETreePath drop) -{ - GList *list; - - /* We only want to leave open parents of the node dropped in. - * Not the node itself. */ - if (drop) { - drop = e_tree_model_node_get_parent (et->priv->model, drop); - } - - for (list = et->priv->expanded_list; list; list = list->next) { - gchar *save_id = list->data; - ETreePath path; - - path = e_tree_model_get_node_by_id (et->priv->model, save_id); - if (path) { - ETreePath search; - gboolean found = FALSE; - - for (search = drop; search; - search = e_tree_model_node_get_parent ( - et->priv->model, search)) { - if (path == search) { - found = TRUE; - break; - } - } - - if (!found) - e_tree_table_adapter_node_set_expanded ( - et->priv->etta, path, FALSE); - } - g_free (save_id); - } - g_list_free (et->priv->expanded_list); - et->priv->expanded_list = NULL; -} - -static void -context_destroyed (gpointer data, - GObject *ctx) -{ - ETree *et = data; - if (et->priv) { - et->priv->last_drop_x = 0; - et->priv->last_drop_y = 0; - et->priv->last_drop_time = 0; - et->priv->last_drop_context = NULL; - collapse_drag (et, NULL); - scroll_off (et); - hover_off (et); - } - g_object_unref (et); -} - -static void -context_connect (ETree *et, - GdkDragContext *context) -{ - if (context == et->priv->last_drop_context) - return; - - if (et->priv->last_drop_context) - g_object_weak_unref ( - G_OBJECT (et->priv->last_drop_context), - context_destroyed, et); - else - g_object_ref (et); - - g_object_weak_ref (G_OBJECT (context), context_destroyed, et); -} - -static void -et_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - ETree *et) -{ - g_signal_emit ( - et, - et_signals[TREE_DRAG_LEAVE], 0, - et->priv->drop_row, - et->priv->drop_path, - et->priv->drop_col, - context, - time); - et->priv->drop_row = -1; - et->priv->drop_col = -1; - - scroll_off (et); - hover_off (et); -} - -static gboolean -et_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETree *et) -{ - GtkAllocation allocation; - gint ret_val; - guint direction = 0; - - et->priv->last_drop_x = x; - et->priv->last_drop_y = y; - et->priv->last_drop_time = time; - context_connect (et, context); - et->priv->last_drop_context = context; - - if (et->priv->hover_idle_id != 0) { - if (abs (et->priv->hover_x - x) > 3 || - abs (et->priv->hover_y - y) > 3) { - hover_on (et, x, y); - } - } else { - hover_on (et, x, y); - } - - ret_val = do_drag_motion (et, context, x, y, time); - - gtk_widget_get_allocation (widget, &allocation); - - if (y < 20) - direction |= ET_SCROLL_UP; - if (y > allocation.height - 20) - direction |= ET_SCROLL_DOWN; - if (x < 20) - direction |= ET_SCROLL_LEFT; - if (x > allocation.width - 20) - direction |= ET_SCROLL_RIGHT; - - if (direction != 0) - scroll_on (et, direction); - else - scroll_off (et); - - return ret_val; -} - -static gboolean -et_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - ETree *et) -{ - gboolean ret_val = FALSE; - gint row, col; - ETreePath path; - - e_tree_get_cell_at (et, x, y, &row, &col); - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - - if (row != et->priv->drop_row && col != et->priv->drop_row) { - g_signal_emit ( - et, et_signals[TREE_DRAG_LEAVE], 0, - et->priv->drop_row, - et->priv->drop_path, - et->priv->drop_col, - context, - time); - g_signal_emit ( - et, et_signals[TREE_DRAG_MOTION], 0, - row, - path, - col, - context, - x, - y, - time, - &ret_val); - } - et->priv->drop_row = row; - et->priv->drop_path = path; - et->priv->drop_col = col; - - g_signal_emit ( - et, et_signals[TREE_DRAG_DROP], 0, - et->priv->drop_row, - et->priv->drop_path, - et->priv->drop_col, - context, - x, - y, - time, - &ret_val); - - et->priv->drop_row = -1; - et->priv->drop_path = NULL; - et->priv->drop_col = -1; - - collapse_drag (et, path); - - scroll_off (et); - return ret_val; -} - -static void -et_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time, - ETree *et) -{ - gint row, col; - ETreePath path; - - e_tree_get_cell_at (et, x, y, &row, &col); - - path = e_tree_table_adapter_node_at_row (et->priv->etta, row); - g_signal_emit ( - et, et_signals[TREE_DRAG_DATA_RECEIVED], 0, - row, - path, - col, - context, - x, - y, - selection_data, - info, - time); -} - -static void -e_tree_class_init (ETreeClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (ETreePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = et_dispose; - object_class->set_property = et_set_property; - object_class->get_property = et_get_property; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->grab_focus = et_grab_focus; - widget_class->unrealize = et_unrealize; - widget_class->style_set = et_canvas_style_set; - widget_class->focus = et_focus; - - class->start_drag = et_real_start_drag; - - et_signals[CURSOR_CHANGE] = g_signal_new ( - "cursor_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, cursor_change), - NULL, NULL, - e_marshal_NONE__INT_POINTER, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_POINTER); - - et_signals[CURSOR_ACTIVATED] = g_signal_new ( - "cursor_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, cursor_activated), - NULL, NULL, - e_marshal_NONE__INT_POINTER, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_POINTER); - - et_signals[SELECTION_CHANGE] = g_signal_new ( - "selection_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, selection_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - et_signals[DOUBLE_CLICK] = g_signal_new ( - "double_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, double_click), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_BOXED, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[RIGHT_CLICK] = g_signal_new ( - "right_click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, right_click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_POINTER_INT_BOXED, - G_TYPE_BOOLEAN, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[CLICK] = g_signal_new ( - "click", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, click), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_POINTER_INT_BOXED, - G_TYPE_BOOLEAN, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[KEY_PRESS] = g_signal_new ( - "key_press", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, key_press), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__INT_POINTER_INT_BOXED, - G_TYPE_BOOLEAN, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[START_DRAG] = g_signal_new ( - "start_drag", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, start_drag), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_BOXED, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[STATE_CHANGE] = g_signal_new ( - "state_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, state_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - et_signals[WHITE_SPACE_EVENT] = g_signal_new ( - "white_space_event", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, white_space_event), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__POINTER, - G_TYPE_BOOLEAN, 1, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - et_signals[TREE_DRAG_BEGIN] = g_signal_new ( - "tree_drag_begin", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_begin), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_BOXED, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TREE_DRAG_END] = g_signal_new ( - "tree_drag_end", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_end), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_BOXED, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TREE_DRAG_DATA_GET] = g_signal_new ( - "tree_drag_data_get", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_data_get), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_OBJECT_BOXED_UINT_UINT, - G_TYPE_NONE, 7, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_UINT, - G_TYPE_UINT); - - et_signals[TREE_DRAG_DATA_DELETE] = g_signal_new ( - "tree_drag_data_delete", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_data_delete), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_OBJECT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT); - - et_signals[TREE_DRAG_LEAVE] = g_signal_new ( - "tree_drag_leave", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_leave), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_OBJECT_UINT, - G_TYPE_NONE, 5, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_UINT); - - et_signals[TREE_DRAG_MOTION] = g_signal_new ( - "tree_drag_motion", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_motion), - NULL, NULL, - e_marshal_BOOLEAN__INT_POINTER_INT_OBJECT_INT_INT_UINT, - G_TYPE_BOOLEAN, 7, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_UINT); - - et_signals[TREE_DRAG_DROP] = g_signal_new ( - "tree_drag_drop", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_drop), - NULL, NULL, - e_marshal_BOOLEAN__INT_POINTER_INT_OBJECT_INT_INT_UINT, - G_TYPE_BOOLEAN, 7, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_UINT); - - et_signals[TREE_DRAG_DATA_RECEIVED] = g_signal_new ( - "tree_drag_data_received", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETreeClass, tree_drag_data_received), - NULL, NULL, - e_marshal_NONE__INT_POINTER_INT_OBJECT_INT_INT_BOXED_UINT_UINT, - G_TYPE_NONE, 9, - G_TYPE_INT, - G_TYPE_POINTER, - G_TYPE_INT, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_INT, - G_TYPE_INT, - GTK_TYPE_SELECTION_DATA, - G_TYPE_UINT, - G_TYPE_UINT); - - g_object_class_install_property ( - object_class, - PROP_LENGTH_THRESHOLD, - g_param_spec_int ( - "length_threshold", - "Length Threshold", - "Length Threshold", - 0, G_MAXINT, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_HORIZONTAL_DRAW_GRID, - g_param_spec_boolean ( - "horizontal_draw_grid", - "Horizontal Draw Grid", - "Horizontal Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_VERTICAL_DRAW_GRID, - g_param_spec_boolean ( - "vertical_draw_grid", - "Vertical Draw Grid", - "Vertical Draw Grid", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_DRAW_FOCUS, - g_param_spec_boolean ( - "drawfocus", - "Draw focus", - "Draw focus", - FALSE, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - object_class, - PROP_ETTA, - g_param_spec_object ( - "ETreeTableAdapter", - "ETree table adapter", - "ETree table adapter", - E_TYPE_TREE_TABLE_ADAPTER, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_UNIFORM_ROW_HEIGHT, - g_param_spec_boolean ( - "uniform_row_height", - "Uniform row height", - "Uniform row height", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ALWAYS_SEARCH, - g_param_spec_boolean ( - "always_search", - "Always search", - "Always search", - FALSE, - G_PARAM_READWRITE)); - - gtk_widget_class_install_style_property ( - widget_class, - g_param_spec_int ( - "expander_size", - "Expander Size", - "Size of the expander arrow", - 0, G_MAXINT, 10, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property ( - widget_class, - g_param_spec_int ( - "vertical-spacing", - "Vertical Row Spacing", - "Vertical space between rows. " - "It is added to top and to bottom of a row", - 0, G_MAXINT, 3, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /* Scrollable interface */ - g_object_class_override_property ( - object_class, PROP_HADJUSTMENT, "hadjustment"); - g_object_class_override_property ( - object_class, PROP_VADJUSTMENT, "vadjustment"); - g_object_class_override_property ( - object_class, PROP_HSCROLL_POLICY, "hscroll-policy"); - g_object_class_override_property ( - object_class, PROP_VSCROLL_POLICY, "vscroll-policy"); - - gal_a11y_e_tree_init (); -} - -static void -tree_size_allocate (GtkWidget *widget, - GtkAllocation *alloc, - ETree *tree) -{ - gdouble width; - - g_return_if_fail (tree != NULL); - g_return_if_fail (tree->priv != NULL); - g_return_if_fail (tree->priv->info_text != NULL); - - gnome_canvas_get_scroll_region ( - GNOME_CANVAS (tree->priv->table_canvas), - NULL, NULL, &width, NULL); - - width -= 60.0; - - g_object_set ( - tree->priv->info_text, "width", width, - "clip_width", width, NULL); -} - -/** - * e_tree_set_info_message: - * @tree: #ETree instance - * @info_message: Message to set. Can be NULL. - * - * Creates an info message in table area, or removes old. - **/ -void -e_tree_set_info_message (ETree *tree, - const gchar *info_message) -{ - GtkAllocation allocation; - GtkWidget *widget; - - g_return_if_fail (tree != NULL); - g_return_if_fail (tree->priv != NULL); - - if (!tree->priv->info_text && (!info_message || !*info_message)) - return; - - if (!info_message || !*info_message) { - g_signal_handler_disconnect (tree, tree->priv->info_text_resize_id); - g_object_run_dispose (G_OBJECT (tree->priv->info_text)); - tree->priv->info_text = NULL; - return; - } - - widget = GTK_WIDGET (tree->priv->table_canvas); - gtk_widget_get_allocation (widget, &allocation); - - if (!tree->priv->info_text) { - if (allocation.width > 60) { - tree->priv->info_text = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (gnome_canvas_root (tree->priv->table_canvas)), - e_text_get_type (), - "line_wrap", TRUE, - "clip", TRUE, - "justification", GTK_JUSTIFY_LEFT, - "text", info_message, - "width", (gdouble) allocation.width - 60.0, - "clip_width", (gdouble) allocation.width - 60.0, - NULL); - - e_canvas_item_move_absolute (tree->priv->info_text, 30, 30); - - tree->priv->info_text_resize_id = g_signal_connect ( - tree, "size_allocate", - G_CALLBACK (tree_size_allocate), tree); - } - } else - gnome_canvas_item_set (tree->priv->info_text, "text", info_message, NULL); -} - -void -e_tree_freeze_state_change (ETree *tree) -{ - g_return_if_fail (tree != NULL); - - tree->priv->state_change_freeze++; - if (tree->priv->state_change_freeze == 1) - tree->priv->state_changed = FALSE; - - g_return_if_fail (tree->priv->state_change_freeze != 0); -} - -void -e_tree_thaw_state_change (ETree *tree) -{ - g_return_if_fail (tree != NULL); - g_return_if_fail (tree->priv->state_change_freeze != 0); - - tree->priv->state_change_freeze--; - if (tree->priv->state_change_freeze == 0 && tree->priv->state_changed) { - tree->priv->state_changed = FALSE; - e_tree_state_change (tree); - } -} diff --git a/widgets/table/e-tree.h b/widgets/table/e-tree.h deleted file mode 100644 index f3d1f9f6a7..0000000000 --- a/widgets/table/e-tree.h +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TREE_H_ -#define _E_TREE_H_ - -#include <gtk/gtk.h> -#include <libxml/tree.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <misc/e-printable.h> - -#include <table/e-table-extras.h> -#include <table/e-table-specification.h> -#include <table/e-table-state.h> -#include <table/e-tree-model.h> -#include <table/e-tree-table-adapter.h> -#include <table/e-table-item.h> - -#define E_TREE_USE_TREE_SELECTION - -#ifdef E_TREE_USE_TREE_SELECTION -#include <table/e-tree-selection-model.h> -#endif - -/* Standard GObject macros */ -#define E_TYPE_TREE \ - (e_tree_get_type ()) -#define E_TREE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TREE, ETree)) -#define E_TREE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TREE, ETreeClass)) -#define E_IS_TREE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TREE)) -#define E_IS_TREE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TREE)) -#define E_TREE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TREE)) - -G_BEGIN_DECLS - -typedef struct _ETreeDragSourceSite ETreeDragSourceSite; - -typedef struct _ETree ETree; -typedef struct _ETreeClass ETreeClass; -typedef struct _ETreePrivate ETreePrivate; - -struct _ETree { - GtkTable parent; - ETreePrivate *priv; -}; - -struct _ETreeClass { - GtkTableClass parent_class; - - void (*cursor_change) (ETree *et, - gint row, - ETreePath path); - void (*cursor_activated) (ETree *et, - gint row, - ETreePath path); - void (*selection_change) (ETree *et); - void (*double_click) (ETree *et, - gint row, - ETreePath path, - gint col, - GdkEvent *event); - gboolean (*right_click) (ETree *et, - gint row, - ETreePath path, - gint col, - GdkEvent *event); - gboolean (*click) (ETree *et, - gint row, - ETreePath path, - gint col, - GdkEvent *event); - gboolean (*key_press) (ETree *et, - gint row, - ETreePath path, - gint col, - GdkEvent *event); - gboolean (*start_drag) (ETree *et, - gint row, - ETreePath path, - gint col, - GdkEvent *event); - void (*state_change) (ETree *et); - gboolean (*white_space_event) (ETree *et, - GdkEvent *event); - - /* Source side drag signals */ - void (*tree_drag_begin) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context); - void (*tree_drag_end) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context); - void (*tree_drag_data_get) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); - void (*tree_drag_data_delete) - (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context); - - /* Target side drag signals */ - void (*tree_drag_leave) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context, - guint time); - gboolean (*tree_drag_motion) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context, - gint x, - gint y, - guint time); - gboolean (*tree_drag_drop) (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context, - gint x, - gint y, - guint time); - void (*tree_drag_data_received) - (ETree *tree, - gint row, - ETreePath path, - gint col, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); -}; - -GType e_tree_get_type (void) G_GNUC_CONST; -gboolean e_tree_construct (ETree *e_tree, - ETreeModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state); -GtkWidget * e_tree_new (ETreeModel *etm, - ETableExtras *ete, - const gchar *spec, - const gchar *state); - -/* Create an ETree using files. */ -gboolean e_tree_construct_from_spec_file (ETree *e_tree, - ETreeModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn); -GtkWidget * e_tree_new_from_spec_file (ETreeModel *etm, - ETableExtras *ete, - const gchar *spec_fn, - const gchar *state_fn); - -/* To save the state */ -gchar * e_tree_get_state (ETree *e_tree); -void e_tree_save_state (ETree *e_tree, - const gchar *filename); -ETableState * e_tree_get_state_object (ETree *e_tree); -ETableSpecification * - e_tree_get_spec (ETree *e_tree); - -/* note that it is more efficient to provide the state at creation time */ -void e_tree_set_search_column (ETree *e_tree, - gint col); -void e_tree_set_state (ETree *e_tree, - const gchar *state); -void e_tree_set_state_object (ETree *e_tree, - ETableState *state); -void e_tree_load_state (ETree *e_tree, - const gchar *filename); -void e_tree_show_cursor_after_reflow (ETree *e_tree); - -void e_tree_set_cursor (ETree *e_tree, - ETreePath path); - -/* NULL means we don't have the cursor. */ -ETreePath e_tree_get_cursor (ETree *e_tree); -void e_tree_selected_row_foreach (ETree *e_tree, - EForeachFunc callback, - gpointer closure); -#ifdef E_TREE_USE_TREE_SELECTION -void e_tree_selected_path_foreach (ETree *e_tree, - ETreeForeachFunc callback, - gpointer closure); -void e_tree_path_foreach (ETree *e_tree, - ETreeForeachFunc callback, - gpointer closure); -#endif -EPrintable *e_tree_get_printable (ETree *e_tree); -gint e_tree_get_next_row (ETree *e_tree, - gint model_row); -gint e_tree_get_prev_row (ETree *e_tree, - gint model_row); -gint e_tree_model_to_view_row (ETree *e_tree, - gint model_row); -gint e_tree_view_to_model_row (ETree *e_tree, - gint view_row); -void e_tree_get_cell_at (ETree *tree, - gint x, - gint y, - gint *row_return, - gint *col_return); -void e_tree_get_cell_geometry (ETree *tree, - gint row, - gint col, - gint *x_return, - gint *y_return, - gint *width_return, - gint *height_return); - -/* Useful accessors */ -ETreeModel * e_tree_get_model (ETree *et); -ESelectionModel * - e_tree_get_selection_model (ETree *et); -ETreeTableAdapter * - e_tree_get_table_adapter (ETree *et); - -/* Drag & drop stuff. */ -/* Target */ -void e_tree_drag_get_data (ETree *tree, - gint row, - gint col, - GdkDragContext *context, - GdkAtom target, - guint32 time); -void e_tree_drag_highlight (ETree *tree, - gint row, - gint col); /* col == -1 to highlight entire row. */ -void e_tree_drag_unhighlight (ETree *tree); -void e_tree_drag_dest_set (ETree *tree, - GtkDestDefaults flags, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); -void e_tree_drag_dest_set_proxy (ETree *tree, - GdkWindow *proxy_window, - GdkDragProtocol protocol, - gboolean use_coordinates); - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ -void e_tree_drag_dest_unset (GtkWidget *widget); - -/* Source side */ -void e_tree_drag_source_set (ETree *tree, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); -void e_tree_drag_source_unset (ETree *tree); - -/* There probably should be functions for setting the targets - * as a GtkTargetList - */ -GdkDragContext *e_tree_drag_begin (ETree *tree, - gint row, - gint col, - GtkTargetList *targets, - GdkDragAction actions, - gint button, - GdkEvent *event); - -gboolean e_tree_is_dragging (ETree *tree); - -/* Adapter functions */ -gboolean e_tree_node_is_expanded (ETree *et, - ETreePath path); -void e_tree_node_set_expanded (ETree *et, - ETreePath path, - gboolean expanded); -void e_tree_node_set_expanded_recurse - (ETree *et, - ETreePath path, - gboolean expanded); -void e_tree_root_node_set_visible (ETree *et, - gboolean visible); -ETreePath e_tree_node_at_row (ETree *et, - gint row); -gint e_tree_row_of_node (ETree *et, - ETreePath path); -gboolean e_tree_root_node_is_visible (ETree *et); -void e_tree_show_node (ETree *et, - ETreePath path); -void e_tree_save_expanded_state (ETree *et, - gchar *filename); -void e_tree_load_expanded_state (ETree *et, - gchar *filename); - -xmlDoc * e_tree_save_expanded_state_xml (ETree *et); -void e_tree_load_expanded_state_xml (ETree *et, - xmlDoc *doc); - -gint e_tree_row_count (ETree *et); -GtkWidget * e_tree_get_tooltip (ETree *et); -void e_tree_force_expanded_state (ETree *et, - gint state); - -typedef enum { - E_TREE_FIND_NEXT_BACKWARD = 0, - E_TREE_FIND_NEXT_FORWARD = 1 << 0, - E_TREE_FIND_NEXT_WRAP = 1 << 1 -} ETreeFindNextParams; - -gboolean e_tree_find_next (ETree *et, - ETreeFindNextParams params, - ETreePathFunc func, - gpointer data); - -/* This function is only needed in single_selection_mode. */ -void e_tree_right_click_up (ETree *et); - -ETableItem * e_tree_get_item (ETree *et); - -GnomeCanvasItem * - e_tree_get_header_item (ETree *et); - -void e_tree_set_info_message (ETree *tree, - const gchar *info_message); - -void e_tree_freeze_state_change (ETree *table); -void e_tree_thaw_state_change (ETree *table); - -G_END_DECLS - -#endif /* _E_TREE_H_ */ - diff --git a/widgets/table/gal-a11y-e-cell-popup.c b/widgets/table/gal-a11y-e-cell-popup.c deleted file mode 100644 index 1c97ee3198..0000000000 --- a/widgets/table/gal-a11y-e-cell-popup.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yang Wu <yang.wu@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "a11y/gal-a11y-util.h" -#include "table/e-cell-popup.h" -#include <glib/gi18n.h> - -#include "gal-a11y-e-cell-popup.h" -#include "gal-a11y-e-cell-registry.h" - -static AtkObjectClass *parent_class = NULL; -#define PARENT_TYPE (gal_a11y_e_cell_get_type ()) - -static void gal_a11y_e_cell_popup_class_init (GalA11yECellPopupClass *class); -static void popup_cell_action (GalA11yECell *cell); - -/** - * gal_a11y_e_cell_popup_get_type: - * @void: - * - * Registers the &GalA11yECellPopup class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yECellPopup class. - **/ -GType -gal_a11y_e_cell_popup_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yECellPopupClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_cell_popup_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yECellPopup), - 0, - (GInstanceInitFunc) NULL, - NULL /* value_cell_popup */ - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yECellPopup", &info, 0); - gal_a11y_e_cell_type_add_action_interface (type); - } - - return type; -} - -static void -gal_a11y_e_cell_popup_class_init (GalA11yECellPopupClass *class) -{ - parent_class = g_type_class_ref (PARENT_TYPE); -} - -AtkObject * -gal_a11y_e_cell_popup_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - AtkObject *a11y; - GalA11yECell *cell; - ECellPopup *popupcell; - ECellView * child_view = NULL; - - popupcell= E_CELL_POPUP (cell_view->ecell); - - if (popupcell && popupcell->popup_cell_view) - child_view = popupcell->popup_cell_view->child_view; - - if (child_view && child_view->ecell) { - a11y = gal_a11y_e_cell_registry_get_object ( - NULL, - item, - child_view, - parent, - model_col, - view_col, - row); - } else { - a11y = g_object_new (GAL_A11Y_TYPE_E_CELL_POPUP, NULL); - gal_a11y_e_cell_construct ( - a11y, - item, - cell_view, - parent, - model_col, - view_col, - row); - } - g_return_val_if_fail (a11y != NULL, NULL); - cell = GAL_A11Y_E_CELL (a11y); - gal_a11y_e_cell_add_action ( - cell, - "popup", - /* Translators: description of a "popup" action */ - _("popup a child"), - "<Alt>Down", /* action keybinding */ - popup_cell_action); - - a11y->role = ATK_ROLE_TABLE_CELL; - return a11y; -} - -static void -popup_cell_action (GalA11yECell *cell) -{ - gint finished; - GdkEvent event; - GtkLayout *layout; - - layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (cell->item)->canvas); - - event.key.type = GDK_KEY_PRESS; - event.key.window = gtk_layout_get_bin_window (layout); - event.key.send_event = TRUE; - event.key.time = GDK_CURRENT_TIME; - event.key.state = GDK_MOD1_MASK; - event.key.keyval = GDK_KEY_Down; - - g_signal_emit_by_name (cell->item, "event", &event, &finished); -} diff --git a/widgets/table/gal-a11y-e-cell-popup.h b/widgets/table/gal-a11y-e-cell-popup.h deleted file mode 100644 index fdf20802a1..0000000000 --- a/widgets/table/gal-a11y-e-cell-popup.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yang Wu <yang.wu@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_CELL_POPUP_H__ -#define __GAL_A11Y_E_CELL_POPUP_H__ - -#include <table/e-table-item.h> -#include <table/gal-a11y-e-cell.h> -#include <atk/atkgobjectaccessible.h> - -#define GAL_A11Y_TYPE_E_CELL_POPUP (gal_a11y_e_cell_popup_get_type ()) -#define GAL_A11Y_E_CELL_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_POPUP, GalA11yECellPopup)) -#define GAL_A11Y_E_CELL_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_POPUP, GalA11yECellPopupClass)) -#define GAL_A11Y_IS_E_CELL_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_POPUP)) -#define GAL_A11Y_IS_E_CELL_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_POPUP)) - -typedef struct _GalA11yECellPopup GalA11yECellPopup; -typedef struct _GalA11yECellPopupClass GalA11yECellPopupClass; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yECellPopupPrivate comes right after the parent class structure. - **/ -struct _GalA11yECellPopup { - GalA11yECell object; -}; - -struct _GalA11yECellPopupClass { - GalA11yECellClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_cell_popup_get_type (void); -AtkObject *gal_a11y_e_cell_popup_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -#endif /* __GAL_A11Y_E_CELL_POPUP_H__ */ diff --git a/widgets/table/gal-a11y-e-cell-registry.c b/widgets/table/gal-a11y-e-cell-registry.c deleted file mode 100644 index db05ac05c1..0000000000 --- a/widgets/table/gal-a11y-e-cell-registry.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gal-a11y-e-cell.h" -#include "gal-a11y-e-cell-registry.h" - -static GObjectClass *parent_class; -static GalA11yECellRegistry *default_registry; -#define PARENT_TYPE (G_TYPE_OBJECT) - -struct _GalA11yECellRegistryPrivate { - GHashTable *table; -}; - -/* Static functions */ - -static void -gal_a11y_e_cell_registry_finalize (GObject *obj) -{ - GalA11yECellRegistry *registry = GAL_A11Y_E_CELL_REGISTRY (obj); - - g_hash_table_destroy (registry->priv->table); - g_free (registry->priv); - - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -gal_a11y_e_cell_registry_class_init (GalA11yECellRegistryClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->finalize = gal_a11y_e_cell_registry_finalize; -} - -static void -gal_a11y_e_cell_registry_init (GalA11yECellRegistry *registry) -{ - registry->priv = g_new (GalA11yECellRegistryPrivate, 1); - registry->priv->table = g_hash_table_new (NULL, NULL); -} - -/** - * gal_a11y_e_cell_registry_get_type: - * @void: - * - * Registers the &GalA11yECellRegistry class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yECellRegistry class. - **/ -GType -gal_a11y_e_cell_registry_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yECellRegistryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_cell_registry_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yECellRegistry), - 0, - (GInstanceInitFunc) gal_a11y_e_cell_registry_init, - NULL /* value_cell */ - }; - - type = g_type_register_static ( - PARENT_TYPE, "GalA11yECellRegistry", &info, 0); - } - - return type; -} - -static void -init_default_registry (void) -{ - if (default_registry == NULL) { - default_registry = g_object_new (gal_a11y_e_cell_registry_get_type (), NULL); - } -} - -AtkObject * -gal_a11y_e_cell_registry_get_object (GalA11yECellRegistry *registry, - ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - GalA11yECellRegistryFunc func = NULL; - GType type; - - if (registry == NULL) { - init_default_registry (); - registry = default_registry; - } - - type = G_OBJECT_TYPE (cell_view->ecell); - while (func == NULL && type != 0) { - func = g_hash_table_lookup (registry->priv->table, GINT_TO_POINTER (type)); - type = g_type_parent (type); - } - - if (func == NULL) - func = gal_a11y_e_cell_new; - - return func (item, cell_view, parent, model_col, view_col, row); -} - -void -gal_a11y_e_cell_registry_add_cell_type (GalA11yECellRegistry *registry, - GType type, - GalA11yECellRegistryFunc func) -{ - if (registry == NULL) { - init_default_registry (); - registry = default_registry; - } - - g_hash_table_insert (registry->priv->table, GINT_TO_POINTER (type), func); -} diff --git a/widgets/table/gal-a11y-e-cell-registry.h b/widgets/table/gal-a11y-e-cell-registry.h deleted file mode 100644 index de8b21b701..0000000000 --- a/widgets/table/gal-a11y-e-cell-registry.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_CELL_REGISTRY_H__ -#define __GAL_A11Y_E_CELL_REGISTRY_H__ - -#include <atk/atkobject.h> -#include <table/e-table-item.h> -#include <table/e-cell.h> - -#define GAL_A11Y_TYPE_E_CELL_REGISTRY (gal_a11y_e_cell_registry_get_type ()) -#define GAL_A11Y_E_CELL_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_REGISTRY, GalA11yECellRegistry)) -#define GAL_A11Y_E_CELL_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_REGISTRY, GalA11yECellRegistryClass)) -#define GAL_A11Y_IS_E_CELL_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_REGISTRY)) -#define GAL_A11Y_IS_E_CELL_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_REGISTRY)) - -typedef struct _GalA11yECellRegistry GalA11yECellRegistry; -typedef struct _GalA11yECellRegistryClass GalA11yECellRegistryClass; -typedef struct _GalA11yECellRegistryPrivate GalA11yECellRegistryPrivate; - -typedef AtkObject *(*GalA11yECellRegistryFunc) (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -struct _GalA11yECellRegistry { - GObject object; - - GalA11yECellRegistryPrivate *priv; -}; - -struct _GalA11yECellRegistryClass { - GObjectClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_cell_registry_get_type (void); -AtkObject *gal_a11y_e_cell_registry_get_object (GalA11yECellRegistry *registry, - ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); -void gal_a11y_e_cell_registry_add_cell_type (GalA11yECellRegistry *registry, - GType type, - GalA11yECellRegistryFunc func); - -#endif /* __GAL_A11Y_E_CELL_REGISTRY_H__ */ diff --git a/widgets/table/gal-a11y-e-cell-toggle.c b/widgets/table/gal-a11y-e-cell-toggle.c deleted file mode 100644 index 33d9e4fd32..0000000000 --- a/widgets/table/gal-a11y-e-cell-toggle.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "table/e-cell-toggle.h" -#include "table/e-table-model.h" -#include <glib/gi18n.h> - -#include "gal-a11y-e-cell-toggle.h" - -#define PARENT_TYPE (gal_a11y_e_cell_get_type ()) -static GObjectClass *parent_class; - -static void gal_a11y_e_cell_toggle_class_init (GalA11yECellToggleClass *class); - -static void -gal_a11y_e_cell_toggle_dispose (GObject *object) -{ - GalA11yECellToggle *a11y = GAL_A11Y_E_CELL_TOGGLE (object); - - ETableModel *e_table_model = GAL_A11Y_E_CELL (a11y)->item->table_model; - - if (e_table_model && a11y->model_id > 0) { - g_signal_handler_disconnect (e_table_model, a11y->model_id); - a11y->model_id = 0; - } - - if (parent_class->dispose) - parent_class->dispose (object); -} - -GType -gal_a11y_e_cell_toggle_get_type (void) -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo tinfo = - { - sizeof (GalA11yECellToggleClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) gal_a11y_e_cell_toggle_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (GalA11yECellToggle), /* instance size */ - 0, /* nb preallocs */ - NULL, /* instance init */ - NULL /* value table */ - }; - - type = g_type_register_static (GAL_A11Y_TYPE_E_CELL, - "GalA11yECellToggle", &tinfo, 0); - gal_a11y_e_cell_type_add_action_interface (type); - - } - return type; -} - -static void -gal_a11y_e_cell_toggle_class_init (GalA11yECellToggleClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = gal_a11y_e_cell_toggle_dispose; - parent_class = g_type_class_ref (PARENT_TYPE); -} - -static void -toggle_cell_action (GalA11yECell *cell) -{ - gint finished; - GtkLayout *layout; - GdkEventButton event; - gint x, y, width, height; - gint row, col; - - row = cell->row; - col = cell->view_col; - - layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (cell->item)->canvas); - - e_table_item_get_cell_geometry ( - cell->item, &row, &col, &x, &y, &width, &height); - - event.x = x + width / 2 + (gint)(GNOME_CANVAS_ITEM (cell->item)->x1); - event.y = y + height / 2 + (gint)(GNOME_CANVAS_ITEM (cell->item)->y1); - - event.type = GDK_BUTTON_PRESS; - event.window = gtk_layout_get_bin_window (layout); - event.button = 1; - event.send_event = TRUE; - event.time = GDK_CURRENT_TIME; - event.axes = NULL; - - g_signal_emit_by_name (cell->item, "event", &event, &finished); -} - -static void -model_change_cb (ETableModel *etm, - gint col, - gint row, - GalA11yECell *cell) -{ - gint value; - - if (col == cell->model_col && row == cell->row) { - - value = GPOINTER_TO_INT ( - e_table_model_value_at (cell->cell_view->e_table_model, - cell->model_col, cell->row)); - /* Cheat gnopernicus, or it will ignore the state change signal */ - atk_focus_tracker_notify (ATK_OBJECT (cell)); - - if (value) - gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, TRUE); - else - gal_a11y_e_cell_remove_state (cell, ATK_STATE_CHECKED, TRUE); - } -} - -AtkObject * -gal_a11y_e_cell_toggle_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - AtkObject *a11y; - GalA11yECell *cell; - GalA11yECellToggle *toggle_cell; - gint value; - - a11y = ATK_OBJECT (g_object_new (GAL_A11Y_TYPE_E_CELL_TOGGLE, NULL)); - - g_return_val_if_fail (a11y != NULL, NULL); - - cell = GAL_A11Y_E_CELL (a11y); - toggle_cell = GAL_A11Y_E_CELL_TOGGLE (a11y); - a11y->role = ATK_ROLE_TABLE_CELL; - - gal_a11y_e_cell_construct ( - a11y, - item, - cell_view, - parent, - model_col, - view_col, - row); - - gal_a11y_e_cell_add_action ( - cell, - "toggle", - /* Translators: description of a "toggle" action */ - _("toggle the cell"), - NULL, /* action keybinding */ - toggle_cell_action); - - toggle_cell->model_id = g_signal_connect ( - item->table_model, "model_cell_changed", - (GCallback) model_change_cb, a11y); - - value = GPOINTER_TO_INT ( - e_table_model_value_at ( - cell->cell_view->e_table_model, - cell->model_col, cell->row)); - if (value) - gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, FALSE); - else - gal_a11y_e_cell_remove_state (cell, ATK_STATE_CHECKED, FALSE); - - return a11y; -} diff --git a/widgets/table/gal-a11y-e-cell-toggle.h b/widgets/table/gal-a11y-e-cell-toggle.h deleted file mode 100644 index 3c29d777e3..0000000000 --- a/widgets/table/gal-a11y-e-cell-toggle.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_CELL_TOGGLE_H__ -#define __GAL_A11Y_E_CELL_TOGGLE_H__ - -#include <atk/atk.h> -#include "gal-a11y-e-cell.h" -#include "gal-a11y-e-cell-toggle.h" - -G_BEGIN_DECLS - -#define GAL_A11Y_TYPE_E_CELL_TOGGLE (gal_a11y_e_cell_toggle_get_type ()) -#define GAL_A11Y_E_CELL_TOGGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE, GalA11yECellToggle)) -#define GAL_A11Y_E_CELL_TOGGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_E_CELL_TOGGLE, GalA11yECellToggleClass)) -#define GAL_A11Y_IS_E_CELL_TOGGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE)) -#define GAL_A11Y_IS_E_CELL_TOGGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TOGGLE)) -#define GAL_A11Y_E_CELL_TOGGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE, GalA11yECellToggleClass)) - -typedef struct _GalA11yECellToggle GalA11yECellToggle; -typedef struct _GalA11yECellToggleClass GalA11yECellToggleClass; - -struct _GalA11yECellToggle -{ - GalA11yECell parent; - gint model_id; -}; - -GType gal_a11y_e_cell_toggle_get_type (void); - -struct _GalA11yECellToggleClass -{ - GalA11yECellClass parent_class; -}; - -AtkObject *gal_a11y_e_cell_toggle_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -G_END_DECLS - -#endif /* __GAL_A11Y_E_CELL_TOGGLE_H__ */ diff --git a/widgets/table/gal-a11y-e-cell-tree.c b/widgets/table/gal-a11y-e-cell-tree.c deleted file mode 100644 index 599b660ca5..0000000000 --- a/widgets/table/gal-a11y-e-cell-tree.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Tim Wo <tim.wo@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <atk/atk.h> - -#include "a11y/gal-a11y-util.h" -#include "table/e-cell-tree.h" -#include "table/e-table.h" -#include "table/e-tree-table-adapter.h" -#include <glib/gi18n.h> - -#include "gal-a11y-e-cell-tree.h" -#include "gal-a11y-e-cell-registry.h" - -#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTreeClass)) -static AtkObjectClass *a11y_parent_class; -#define A11Y_PARENT_TYPE (gal_a11y_e_cell_get_type ()) - -#define d(x) - -static void -ectr_model_row_changed_cb (ETableModel *etm, - gint row, - GalA11yECell *a11y) -{ - ETreePath node; - ETreeModel *tree_model; - ETreeTableAdapter *tree_table_adapter; - - g_return_if_fail (a11y); - if (a11y->row != row) - return; - - node = e_table_model_value_at (etm, -1, a11y->row); - tree_model = e_table_model_value_at (etm, -2, a11y->row); - tree_table_adapter = e_table_model_value_at (etm, -3, a11y->row); - - if (e_tree_model_node_is_expandable (tree_model, node)) { - gboolean is_exp = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node); - if (is_exp) - gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDED, TRUE); - else - gal_a11y_e_cell_remove_state (a11y, ATK_STATE_EXPANDED, TRUE); - } -} - -static void -kill_view_cb (ECellView *subcell_view, - gpointer psubcell_a11ies) -{ - GList *node; - GList *subcell_a11ies = (GList *) psubcell_a11ies; - GalA11yECell *subcell; - - for (node = subcell_a11ies; node != NULL; node = g_list_next (node)) - { - subcell = GAL_A11Y_E_CELL (node->data); - if (subcell && subcell->cell_view == subcell_view) - { - d (fprintf (stderr, "subcell_view %p deleted before the a11y object %p\n", subcell_view, subcell)); - subcell->cell_view = NULL; - } - } -} - -static void -ectr_subcell_weak_ref (GalA11yECellTree *a11y, - GalA11yECell *subcell_a11y) -{ - ECellView *subcell_view = subcell_a11y ? subcell_a11y->cell_view : NULL; - if (subcell_a11y && subcell_view && subcell_view->kill_view_cb_data) - subcell_view->kill_view_cb_data = g_list_remove (subcell_view->kill_view_cb_data, subcell_a11y); - - g_signal_handler_disconnect ( - GAL_A11Y_E_CELL (a11y)->item->table_model, - a11y->model_row_changed_id); - g_object_unref (a11y); -} - -static void -ectr_do_action_expand (AtkAction *action) -{ - GalA11yECell *a11y; - ETableModel *table_model; - ETreePath node; - ETreeModel *tree_model; - ETreeTableAdapter *tree_table_adapter; - - a11y = GAL_A11Y_E_CELL (action); - table_model = a11y->item->table_model; - node = e_table_model_value_at (table_model, -1, a11y->row); - tree_model = e_table_model_value_at (table_model, -2, a11y->row); - tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row); - - if (e_tree_model_node_is_expandable (tree_model, node)) { - e_tree_table_adapter_node_set_expanded ( - tree_table_adapter, node, TRUE); - gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDED, TRUE); - } -} - -static void -ectr_do_action_collapse (AtkAction *action) -{ - GalA11yECell *a11y; - ETableModel *table_model; - ETreePath node; - ETreeModel *tree_model; - ETreeTableAdapter *tree_table_adapter; - - a11y = GAL_A11Y_E_CELL (action); - table_model = a11y->item->table_model; - node = e_table_model_value_at (table_model, -1, a11y->row); - tree_model = e_table_model_value_at (table_model, -2, a11y->row); - tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row); - - if (e_tree_model_node_is_expandable (tree_model, node)) { - e_tree_table_adapter_node_set_expanded ( - tree_table_adapter, node, FALSE); - gal_a11y_e_cell_remove_state (a11y, ATK_STATE_EXPANDED, TRUE); - } -} - -static void -ectr_class_init (GalA11yECellTreeClass *class) -{ - a11y_parent_class = g_type_class_ref (A11Y_PARENT_TYPE); -} - -static void -ectr_init (GalA11yECellTree *a11y) -{ -} - -GType -gal_a11y_e_cell_tree_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yECellTreeClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) ectr_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yECellTree), - 0, - (GInstanceInitFunc) ectr_init, - NULL /* value_cell_text */ - }; - - type = g_type_register_static (A11Y_PARENT_TYPE, "GalA11yECellTree", &info, 0); - gal_a11y_e_cell_type_add_action_interface (type); - } - - return type; -} - -AtkObject * -gal_a11y_e_cell_tree_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - AtkObject *subcell_a11y; - GalA11yECellTree *a11y; - - ETreePath node; - ETreeModel *tree_model; - ETreeTableAdapter *tree_table_adapter; - - ECellView *subcell_view; - subcell_view = e_cell_tree_view_get_subcell_view (cell_view); - - if (subcell_view->ecell) { - subcell_a11y = gal_a11y_e_cell_registry_get_object ( - NULL, - item, - subcell_view, - parent, - model_col, - view_col, - row); - gal_a11y_e_cell_add_action ( - GAL_A11Y_E_CELL (subcell_a11y), - "expand", - /* Translators: description of an "expand" action */ - _("expands the row in the ETree containing this cell"), - NULL, - (ACTION_FUNC) ectr_do_action_expand); - - gal_a11y_e_cell_add_action ( - GAL_A11Y_E_CELL (subcell_a11y), - "collapse", - /* Translators: description of a "collapse" action */ - _("collapses the row in the ETree containing this cell"), - NULL, - (ACTION_FUNC) ectr_do_action_collapse); - - /* init AtkStates for the cell's a11y object */ - node = e_table_model_value_at (item->table_model, -1, row); - tree_model = e_table_model_value_at (item->table_model, -2, row); - tree_table_adapter = e_table_model_value_at (item->table_model, -3, row); - if (e_tree_model_node_is_expandable (tree_model, node)) { - gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (subcell_a11y), ATK_STATE_EXPANDABLE, FALSE); - if (e_tree_table_adapter_node_is_expanded (tree_table_adapter, node)) - gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (subcell_a11y), ATK_STATE_EXPANDED, FALSE); - } - } - else - subcell_a11y = NULL; - - /* create a companion a11y object, this object has type GalA11yECellTree - * and it connects to some signals to determine whether a tree cell is - * expanded or collapsed */ - a11y = g_object_new (gal_a11y_e_cell_tree_get_type (), NULL); - gal_a11y_e_cell_construct ( - ATK_OBJECT (a11y), - item, - cell_view, - parent, - model_col, - view_col, - row); - a11y->model_row_changed_id = g_signal_connect ( - item->table_model, "model_row_changed", - G_CALLBACK (ectr_model_row_changed_cb), subcell_a11y); - - if (subcell_a11y && subcell_view) - { - subcell_view->kill_view_cb = kill_view_cb; - if (!g_list_find (subcell_view->kill_view_cb_data, subcell_a11y)) - subcell_view->kill_view_cb_data = g_list_append (subcell_view->kill_view_cb_data, subcell_a11y); - } - - g_object_weak_ref (G_OBJECT (subcell_a11y), (GWeakNotify) ectr_subcell_weak_ref, a11y); - - return subcell_a11y; -} diff --git a/widgets/table/gal-a11y-e-cell-tree.h b/widgets/table/gal-a11y-e-cell-tree.h deleted file mode 100644 index 18ccf9c7bc..0000000000 --- a/widgets/table/gal-a11y-e-cell-tree.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Tim Wo <tim.wo@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_CELL_TREE_H__ -#define __GAL_A11Y_E_CELL_TREE_H__ - -#include <table/e-table-item.h> -#include <table/e-cell-tree.h> -#include "gal-a11y-e-cell.h" - -#define GAL_A11Y_TYPE_E_CELL_TREE (gal_a11y_e_cell_tree_get_type ()) -#define GAL_A11Y_E_CELL_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTree)) -#define GAL_A11Y_E_CELL_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTreeClass)) -#define GAL_A11Y_IS_E_CELL_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TREE)) -#define GAL_A11Y_IS_E_CELL_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TREE)) - -typedef struct _GalA11yECellTree GalA11yECellTree; -typedef struct _GalA11yECellTreeClass GalA11yECellTreeClass; -typedef struct _GalA11yECellTreePrivate GalA11yECellTreePrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yECellTreePrivate comes right after the parent class structure. - **/ -struct _GalA11yECellTree { - GalA11yECell object; - - gint model_row_changed_id; -}; - -struct _GalA11yECellTreeClass { - GalA11yECellClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_cell_tree_get_type (void); -AtkObject *gal_a11y_e_cell_tree_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -#endif /* __GAL_A11Y_E_CELL_TREE_H__ */ diff --git a/widgets/table/gal-a11y-e-cell-vbox.c b/widgets/table/gal-a11y-e-cell-vbox.c deleted file mode 100644 index d00547c877..0000000000 --- a/widgets/table/gal-a11y-e-cell-vbox.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Eric Zhao <eric.zhao@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2004 Sun Microsystem, Inc. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <atk/atk.h> - -#include "table/e-cell-vbox.h" - -#include "gal-a11y-e-cell-registry.h" -#include "gal-a11y-e-cell-vbox.h" - -static GObjectClass *parent_class; -static AtkComponentIface *component_parent_iface; -#define PARENT_TYPE (gal_a11y_e_cell_get_type ()) - -static gint -ecv_get_n_children (AtkObject *a11y) -{ - g_return_val_if_fail (GAL_A11Y_IS_E_CELL_VBOX (a11y), 0); - - return GAL_A11Y_E_CELL_VBOX (a11y)->a11y_subcell_count; -} - -static void -subcell_destroyed (gpointer data) -{ - GalA11yECell *cell; - AtkObject *parent; - GalA11yECellVbox *gaev; - - g_return_if_fail (GAL_A11Y_IS_E_CELL (data)); - cell = GAL_A11Y_E_CELL (data); - - parent = atk_object_get_parent (ATK_OBJECT (cell)); - g_return_if_fail (GAL_A11Y_IS_E_CELL_VBOX (parent)); - gaev = GAL_A11Y_E_CELL_VBOX (parent); - - if (cell->view_col < gaev->a11y_subcell_count) - gaev->a11y_subcells[cell->view_col] = NULL; -} - -static AtkObject * -ecv_ref_child (AtkObject *a11y, - gint i) -{ - GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y); - GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y); - ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view); - AtkObject *ret; - if (i < gaev->a11y_subcell_count) { - if (gaev->a11y_subcells[i] == NULL) { - ECellView *subcell_view; - gint model_col, row; - row = gaec->row; - model_col = ecvv->model_cols[i]; - subcell_view = ecvv->subcell_views[i]; - /* FIXME Should the view column use a fake - * one or the same as its parent? */ - ret = gal_a11y_e_cell_registry_get_object ( - NULL, - gaec->item, - subcell_view, - a11y, - model_col, - gaec->view_col, - row); - gaev->a11y_subcells[i] = ret; - g_object_ref (ret); - g_object_weak_ref ( - G_OBJECT (ret), - (GWeakNotify) subcell_destroyed, - ret); - } else { - ret = (AtkObject *) gaev->a11y_subcells[i]; - if (ATK_IS_OBJECT (ret)) - g_object_ref (ret); - else - ret = NULL; - } - } else { - ret = NULL; - } - - return ret; -} - -static void -ecv_dispose (GObject *object) -{ - GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (object); - if (gaev->a11y_subcells) - g_free (gaev->a11y_subcells); - - if (parent_class->dispose) - parent_class->dispose (object); -} - -/* AtkComponet interface */ -static AtkObject * -ecv_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - gint x0, y0, width, height; - gint subcell_height, i; - - GalA11yECell *gaec = GAL_A11Y_E_CELL (component); - ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view); - - atk_component_get_extents (component, &x0, &y0, &width, &height, coord_type); - x -= x0; - y -= y0; - if (x < 0 || x > width || y < 0 || y > height) - return NULL; - - for (i = 0; i < ecvv->subcell_view_count; i++) { - subcell_height = e_cell_height ( - ecvv->subcell_views[i], ecvv->model_cols[i], - gaec->view_col, gaec->row); - if (0 <= y && y <= subcell_height) { - return ecv_ref_child ((AtkObject *) component, i); - } else - y -= subcell_height; - } - - return NULL; -} - -static void -ecv_class_init (GalA11yECellVboxClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - AtkObjectClass *a11y_class = ATK_OBJECT_CLASS (class); - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->dispose = ecv_dispose; - - a11y_class->get_n_children = ecv_get_n_children; - a11y_class->ref_child = ecv_ref_child; -} - -static void -ecv_init (GalA11yECellVbox *a11y) -{ -} - -static void -ecv_atk_component_iface_init (AtkComponentIface *iface) -{ - component_parent_iface = g_type_interface_peek_parent (iface); - - iface->ref_accessible_at_point = ecv_ref_accessible_at_point; -} - -GType -gal_a11y_e_cell_vbox_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (GalA11yECellVboxClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) ecv_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yECellVbox), - 0, - (GInstanceInitFunc) ecv_init, - NULL /* value_cell */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) ecv_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yECellVbox", &info, 0); - gal_a11y_e_cell_type_add_action_interface (type); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); - } - - return type; -} - -AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - AtkObject *a11y; - GalA11yECell *gaec; - GalA11yECellVbox *gaev; - ECellVboxView *ecvv; - - a11y = g_object_new (gal_a11y_e_cell_vbox_get_type (), NULL); - - gal_a11y_e_cell_construct ( - a11y, item, cell_view, parent, model_col, view_col, row); - - gaec = GAL_A11Y_E_CELL (a11y); - gaev = GAL_A11Y_E_CELL_VBOX (a11y); - ecvv = (ECellVboxView *) (gaec->cell_view); - gaev->a11y_subcell_count = ecvv->subcell_view_count; - gaev->a11y_subcells = g_malloc0 (sizeof (AtkObject *) * gaev->a11y_subcell_count); - return a11y; -} diff --git a/widgets/table/gal-a11y-e-cell-vbox.h b/widgets/table/gal-a11y-e-cell-vbox.h deleted file mode 100644 index 657cb5d9a5..0000000000 --- a/widgets/table/gal-a11y-e-cell-vbox.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Eric Zhao <eric.zhao@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2004 Sun Microsystem, Inc. - * - */ - -#ifndef __GAL_A11Y_E_CELL_VBOX_H__ -#define __GAL_A11Y_E_CELL_VBOX_H__ - -#include "gal-a11y-e-cell.h" - -G_BEGIN_DECLS - -#define GAL_A11Y_TYPE_E_CELL_VBOX (gal_a11y_e_cell_vbox_get_type ()) -#define GAL_A11Y_E_CELL_VBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_VBOX, GalA11yECellVbox)) -#define GAL_A11Y_E_CELL_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_E_CELL_VBOX, GalA11yECellVboxClass)) -#define GAL_A11Y_IS_E_CELL_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_VBOX)) -#define GAL_A11Y_IS_E_CELL_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_VBOX)) -#define GAL_A11Y_E_CELL_VBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAL_A11Y_TYPE_E_CELL_VBOX, GalA11yECellVboxClass)) - -typedef struct _GalA11yECellVbox GalA11yECellVbox; -typedef struct _GalA11yECellVboxClass GalA11yECellVboxClass; - -struct _GalA11yECellVbox -{ - GalA11yECell object; - gint a11y_subcell_count; - gpointer *a11y_subcells; -}; - -struct _GalA11yECellVboxClass -{ - GalA11yECellClass parent_class; -}; - -GType gal_a11y_e_cell_vbox_get_type (void); -AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -G_END_DECLS -#endif /* __GAL_A11Y_E_CELL_VBOX_H__ */ diff --git a/widgets/table/gal-a11y-e-cell.c b/widgets/table/gal-a11y-e-cell.c deleted file mode 100644 index 3972c2de16..0000000000 --- a/widgets/table/gal-a11y-e-cell.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> - -#include "a11y/gal-a11y-util.h" -#include "table/e-table.h" -#include "table/e-tree.h" -#include <glib/gi18n.h> - -#include "gal-a11y-e-cell.h" -#include "gal-a11y-e-cell-vbox.h" -#include "gal-a11y-e-table-item.h" - -static GObjectClass *parent_class; -#define PARENT_TYPE (atk_object_get_type ()) - -#if 0 -static void -unref_item (gpointer user_data, - GObject *obj_loc) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (user_data); - a11y->item = NULL; - g_object_unref (a11y); -} - -static void -unref_cell (gpointer user_data, - GObject *obj_loc) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (user_data); - a11y->cell_view = NULL; - g_object_unref (a11y); -} -#endif - -static gboolean -is_valid (AtkObject *cell) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (cell); - GalA11yETableItem *a11yItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent); - AtkStateSet *item_ss; - gboolean ret = TRUE; - - item_ss = atk_object_ref_state_set (ATK_OBJECT (a11yItem)); - if (atk_state_set_contains_state (item_ss, ATK_STATE_DEFUNCT)) - ret = FALSE; - - g_object_unref (item_ss); - - if (ret && atk_state_set_contains_state (a11y->state_set, ATK_STATE_DEFUNCT)) - ret = FALSE; - - return ret; -} - -static void -gal_a11y_e_cell_dispose (GObject *object) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (object); - -#if 0 - if (a11y->item) - g_object_unref (a11y->item); /*, unref_item, a11y); */ - if (a11y->cell_view) - g_object_unref (a11y->cell_view); /*, unref_cell, a11y); */ - if (a11y->parent) - g_object_unref (a11y->parent); -#endif - - if (a11y->state_set) { - g_object_unref (a11y->state_set); - a11y->state_set = NULL; - } - - if (parent_class->dispose) - parent_class->dispose (object); - -} - -/* Static functions */ -static const gchar * -gal_a11y_e_cell_get_name (AtkObject *a11y) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (a11y); - ETableCol *ecol; - - if (a11y->name != NULL && strcmp (a11y->name, "")) - return a11y->name; - - if (cell->item != NULL) { - ecol = e_table_header_get_column (cell->item->header, cell->view_col); - if (ecol != NULL) - return ecol->text; - } - - return _("Table Cell"); -} - -static AtkStateSet * -gal_a11y_e_cell_ref_state_set (AtkObject *accessible) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (accessible); - - g_return_val_if_fail (cell->state_set, NULL); - - g_object_ref (cell->state_set); - - return cell->state_set; -} - -static AtkObject * -gal_a11y_e_cell_get_parent (AtkObject *accessible) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible); - return a11y->parent; -} - -static gint -gal_a11y_e_cell_get_index_in_parent (AtkObject *accessible) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible); - - if (!is_valid (accessible)) - return -1; - - return (a11y->row + 1) * a11y->item->cols + a11y->view_col; -} - -/* Component IFace */ -static void -gal_a11y_e_cell_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (component); - GtkWidget *tableOrTree; - gint row; - gint col; - gint xval; - gint yval; - - row = a11y->row; - col = a11y->view_col; - - tableOrTree = gtk_widget_get_parent (GTK_WIDGET (a11y->item->parent.canvas)); - if (E_IS_TREE (tableOrTree)) { - e_tree_get_cell_geometry ( - E_TREE (tableOrTree), - row, col, &xval, &yval, - width, height); - } else { - e_table_get_cell_geometry ( - E_TABLE (tableOrTree), - row, col, &xval, &yval, - width, height); - } - - atk_component_get_position ( - ATK_COMPONENT (a11y->parent), - x, y, coord_type); - if (x && *x != G_MININT) - *x += xval; - if (y && *y != G_MININT) - *y += yval; -} - -static gboolean -gal_a11y_e_cell_grab_focus (AtkComponent *component) -{ - GalA11yECell *a11y; - gint index; - GtkWidget *toplevel; - GalA11yETableItem *a11yTableItem; - - a11y = GAL_A11Y_E_CELL (component); - - /* for e_cell_vbox's children, we just grab the e_cell_vbox */ - if (GAL_A11Y_IS_E_CELL_VBOX (a11y->parent)) { - return atk_component_grab_focus (ATK_COMPONENT (a11y->parent)); - } - - a11yTableItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent); - index = atk_object_get_index_in_parent (ATK_OBJECT (a11y)); - - atk_selection_clear_selection (ATK_SELECTION (a11yTableItem)); - atk_selection_add_selection (ATK_SELECTION (a11yTableItem), index); - - gtk_widget_grab_focus ( - GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas)); - toplevel = gtk_widget_get_toplevel ( - GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas)); - if (toplevel && gtk_widget_is_toplevel (toplevel)) - gtk_window_present (GTK_WINDOW (toplevel)); - - return TRUE; -} - -/* Table IFace */ - -static void -gal_a11y_e_cell_atk_component_iface_init (AtkComponentIface *iface) -{ - iface->get_extents = gal_a11y_e_cell_get_extents; - iface->grab_focus = gal_a11y_e_cell_grab_focus; -} - -static void -gal_a11y_e_cell_class_init (GalA11yECellClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->dispose = gal_a11y_e_cell_dispose; - - atk_object_class->get_parent = gal_a11y_e_cell_get_parent; - atk_object_class->get_index_in_parent = gal_a11y_e_cell_get_index_in_parent; - atk_object_class->ref_state_set = gal_a11y_e_cell_ref_state_set; - atk_object_class->get_name = gal_a11y_e_cell_get_name; -} - -static void -gal_a11y_e_cell_init (GalA11yECell *a11y) -{ - a11y->item = NULL; - a11y->cell_view = NULL; - a11y->parent = NULL; - a11y->model_col = -1; - a11y->view_col = -1; - a11y->row = -1; - - a11y->state_set = atk_state_set_new (); - atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); - atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); - atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_VISIBLE); -} - -static ActionInfo * -_gal_a11y_e_cell_get_action_info (GalA11yECell *cell, - gint index) -{ - GList *list_node; - - g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), NULL); - if (cell->action_list == NULL) - return NULL; - list_node = g_list_nth (cell->action_list, index); - if (!list_node) - return NULL; - return (ActionInfo *) (list_node->data); -} - -static void -_gal_a11y_e_cell_destroy_action_info (gpointer action_info, - gpointer user_data) -{ - ActionInfo *info = (ActionInfo *) action_info; - - g_return_if_fail (info != NULL); - g_free (info->name); - g_free (info->description); - g_free (info->keybinding); - g_free (info); -} - -gboolean -gal_a11y_e_cell_add_action (GalA11yECell *cell, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - ACTION_FUNC action_func) -{ - ActionInfo *info; - g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE); - info = g_new (ActionInfo, 1); - - if (action_name != NULL) - info->name = g_strdup (action_name); - else - info->name = NULL; - - if (action_description != NULL) - info->description = g_strdup (action_description); - else - info->description = NULL; - if (action_keybinding != NULL) - info->keybinding = g_strdup (action_keybinding); - else - info->keybinding = NULL; - info->do_action_func = action_func; - - cell->action_list = g_list_append (cell->action_list, (gpointer) info); - return TRUE; -} - -gboolean -gal_a11y_e_cell_remove_action (GalA11yECell *cell, - gint action_index) -{ - GList *list_node; - - g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE); - list_node = g_list_nth (cell->action_list, action_index); - if (!list_node) - return FALSE; - g_return_val_if_fail (list_node->data != NULL, FALSE); - _gal_a11y_e_cell_destroy_action_info (list_node->data, NULL); - cell->action_list = g_list_remove_link (cell->action_list, list_node); - - return TRUE; -} - -gboolean -gal_a11y_e_cell_remove_action_by_name (GalA11yECell *cell, - const gchar *action_name) -{ - GList *list_node; - - g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE); - - for (list_node = cell->action_list; list_node; list_node = list_node->next) { - if (!g_ascii_strcasecmp (((ActionInfo *)(list_node->data))->name, action_name)) { - break; - } - } - - g_return_val_if_fail (list_node != NULL, FALSE); - - _gal_a11y_e_cell_destroy_action_info (list_node->data, NULL); - cell->action_list = g_list_remove_link (cell->action_list, list_node); - - return TRUE; -} - -static gint -gal_a11y_e_cell_action_get_n_actions (AtkAction *action) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - if (cell->action_list != NULL) - return g_list_length (cell->action_list); - else - return 0; -} - -static const gchar * -gal_a11y_e_cell_action_get_name (AtkAction *action, - gint index) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index); - - if (info == NULL) - return NULL; - return info->name; -} - -static const gchar * -gal_a11y_e_cell_action_get_description (AtkAction *action, - gint index) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index); - - if (info == NULL) - return NULL; - return info->description; -} - -static gboolean -gal_a11y_e_cell_action_set_description (AtkAction *action, - gint index, - const gchar *desc) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index); - - if (info == NULL) - return FALSE; - g_free (info->description); - info->description = g_strdup (desc); - return TRUE; -} - -static const gchar * -gal_a11y_e_cell_action_get_keybinding (AtkAction *action, - gint index) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index); - if (info == NULL) - return NULL; - - return info->keybinding; -} - -static gboolean -idle_do_action (gpointer data) -{ - GalA11yECell *cell; - - cell = GAL_A11Y_E_CELL (data); - - if (!is_valid (ATK_OBJECT (cell))) - return FALSE; - - cell->action_idle_handler = 0; - cell->action_func (cell); - g_object_unref (cell); - - return FALSE; -} - -static gboolean -gal_a11y_e_cell_action_do_action (AtkAction *action, - gint index) -{ - GalA11yECell *cell = GAL_A11Y_E_CELL (action); - ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index); - - if (!is_valid (ATK_OBJECT (action))) - return FALSE; - - if (info == NULL) - return FALSE; - g_return_val_if_fail (info->do_action_func, FALSE); - if (cell->action_idle_handler) - return FALSE; - cell->action_func = info->do_action_func; - g_object_ref (cell); - cell->action_idle_handler = g_idle_add (idle_do_action, cell); - - return TRUE; -} - -static void -gal_a11y_e_cell_atk_action_interface_init (AtkActionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_n_actions = gal_a11y_e_cell_action_get_n_actions; - iface->do_action = gal_a11y_e_cell_action_do_action; - iface->get_name = gal_a11y_e_cell_action_get_name; - iface->get_description = gal_a11y_e_cell_action_get_description; - iface->set_description = gal_a11y_e_cell_action_set_description; - iface->get_keybinding = gal_a11y_e_cell_action_get_keybinding; -} - -void -gal_a11y_e_cell_type_add_action_interface (GType type) -{ - static const GInterfaceInfo atk_action_info = - { - (GInterfaceInitFunc) gal_a11y_e_cell_atk_action_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - g_type_add_interface_static ( - type, ATK_TYPE_ACTION, - &atk_action_info); -} - -gboolean -gal_a11y_e_cell_add_state (GalA11yECell *cell, - AtkStateType state_type, - gboolean emit_signal) -{ - if (!atk_state_set_contains_state (cell->state_set, state_type)) { - gboolean rc; - - rc = atk_state_set_add_state (cell->state_set, state_type); - /* - * The signal should only be generated if the value changed, - * not when the cell is set up. So states that are set - * initially should pass FALSE as the emit_signal argument. - */ - - if (emit_signal) { - atk_object_notify_state_change (ATK_OBJECT (cell), state_type, TRUE); - /* If state_type is ATK_STATE_VISIBLE, additional - * notification */ - if (state_type == ATK_STATE_VISIBLE) - g_signal_emit_by_name (cell, "visible_data_changed"); - } - - return rc; - } - else - return FALSE; -} - -gboolean -gal_a11y_e_cell_remove_state (GalA11yECell *cell, - AtkStateType state_type, - gboolean emit_signal) -{ - if (atk_state_set_contains_state (cell->state_set, state_type)) { - gboolean rc; - - rc = atk_state_set_remove_state (cell->state_set, state_type); - /* - * The signal should only be generated if the value changed, - * not when the cell is set up. So states that are set - * initially should pass FALSE as the emit_signal argument. - */ - - if (emit_signal) { - atk_object_notify_state_change (ATK_OBJECT (cell), state_type, FALSE); - /* If state_type is ATK_STATE_VISIBLE, additional notification */ - if (state_type == ATK_STATE_VISIBLE) - g_signal_emit_by_name (cell, "visible_data_changed"); - } - - return rc; - } - else - return FALSE; -} - -/** - * gal_a11y_e_cell_get_type: - * @void: - * - * Registers the &GalA11yECell class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yECell class. - **/ -GType -gal_a11y_e_cell_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yECellClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_cell_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yECell), - 0, - (GInstanceInitFunc) gal_a11y_e_cell_init, - NULL /* value_cell */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) gal_a11y_e_cell_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yECell", &info, 0); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); - } - - return type; -} - -AtkObject * -gal_a11y_e_cell_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - AtkObject *a11y; - - a11y = g_object_new (gal_a11y_e_cell_get_type (), NULL); - - gal_a11y_e_cell_construct ( - a11y, - item, - cell_view, - parent, - model_col, - view_col, - row); - return a11y; -} - -void -gal_a11y_e_cell_construct (AtkObject *object, - ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row) -{ - GalA11yECell *a11y = GAL_A11Y_E_CELL (object); - a11y->item = item; - a11y->cell_view = cell_view; - a11y->parent = parent; - a11y->model_col = model_col; - a11y->view_col = view_col; - a11y->row = row; - ATK_OBJECT (a11y) ->role = ATK_ROLE_TABLE_CELL; - - if (item) - g_object_ref (item); - -#if 0 - if (parent) - g_object_ref (parent); - - if (cell_view) - g_object_ref (cell_view); - -#endif -} diff --git a/widgets/table/gal-a11y-e-cell.h b/widgets/table/gal-a11y-e-cell.h deleted file mode 100644 index 48c7d2bec8..0000000000 --- a/widgets/table/gal-a11y-e-cell.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_CELL_H__ -#define __GAL_A11Y_E_CELL_H__ - -#include <table/e-table-item.h> -#include <table/e-cell.h> - -#define GAL_A11Y_TYPE_E_CELL (gal_a11y_e_cell_get_type ()) -#define GAL_A11Y_E_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL, GalA11yECell)) -#define GAL_A11Y_E_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL, GalA11yECellClass)) -#define GAL_A11Y_IS_E_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL)) -#define GAL_A11Y_IS_E_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL)) - -typedef struct _GalA11yECell GalA11yECell; -typedef struct _GalA11yECellClass GalA11yECellClass; -typedef struct _GalA11yECellPrivate GalA11yECellPrivate; -typedef struct _ActionInfo ActionInfo; -typedef void (*ACTION_FUNC) (GalA11yECell *cell); - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yECellPrivate comes right after the parent class structure. - **/ -struct _GalA11yECell { - AtkObject object; - - ETableItem *item; - ECellView *cell_view; - AtkObject *parent; - gint model_col; - gint view_col; - gint row; - AtkStateSet *state_set; - GList *action_list; - gint action_idle_handler; - ACTION_FUNC action_func; -}; - -struct _GalA11yECellClass { - AtkObjectClass parent_class; -}; - -struct _ActionInfo { - gchar *name; - gchar *description; - gchar *keybinding; - ACTION_FUNC do_action_func; -}; - -/* Standard Glib function */ -GType gal_a11y_e_cell_get_type (void); -AtkObject *gal_a11y_e_cell_new (ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); -void gal_a11y_e_cell_construct (AtkObject *object, - ETableItem *item, - ECellView *cell_view, - AtkObject *parent, - gint model_col, - gint view_col, - gint row); - -void gal_a11y_e_cell_type_add_action_interface (GType type); - -gboolean gal_a11y_e_cell_add_action (GalA11yECell *cell, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - ACTION_FUNC action_func); - -gboolean gal_a11y_e_cell_remove_action (GalA11yECell *cell, - gint action_id); - -gboolean gal_a11y_e_cell_remove_action_by_name (GalA11yECell *cell, - const gchar *action_name); - -gboolean gal_a11y_e_cell_add_state (GalA11yECell *cell, - AtkStateType state_type, - gboolean emit_signal); - -gboolean gal_a11y_e_cell_remove_state (GalA11yECell *cell, - AtkStateType state_type, - gboolean emit_signal); - -#endif /* __GAL_A11Y_E_CELL_H__ */ diff --git a/widgets/table/gal-a11y-e-table-click-to-add-factory.c b/widgets/table/gal-a11y-e-table-click-to-add-factory.c deleted file mode 100644 index 1a4b418adf..0000000000 --- a/widgets/table/gal-a11y-e-table-click-to-add-factory.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <atk/atk.h> - -#include "table/e-table.h" -#include "table/e-table-click-to-add.h" - -#include "gal-a11y-e-table.h" -#include "gal-a11y-e-table-click-to-add.h" -#include "gal-a11y-e-table-click-to-add-factory.h" - -#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETableClickToAddFactoryClass)) -static AtkObjectFactoryClass *parent_class; -#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY) - -/* Static functions */ - -static GType -gal_a11y_e_table_click_to_add_factory_get_accessible_type (void) -{ - return GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD; -} - -static AtkObject * -gal_a11y_e_table_click_to_add_factory_create_accessible (GObject *obj) -{ - AtkObject * atk_object; - - g_return_val_if_fail (E_IS_TABLE_CLICK_TO_ADD (obj), NULL); - - atk_object = gal_a11y_e_table_click_to_add_new (obj); - - return atk_object; -} - -static void -gal_a11y_e_table_click_to_add_factory_class_init (GalA11yETableClickToAddFactoryClass *class) -{ - AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - factory_class->create_accessible = gal_a11y_e_table_click_to_add_factory_create_accessible; - factory_class->get_accessible_type = gal_a11y_e_table_click_to_add_factory_get_accessible_type; -} - -static void -gal_a11y_e_table_click_to_add_factory_init (GalA11yETableClickToAddFactory *factory) -{ -} - -/** - * gal_a11y_e_table_factory_get_type: - * @void: - * - * Registers the &GalA11yETableFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETableFactory class. - **/ -GType -gal_a11y_e_table_click_to_add_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETableClickToAddFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_table_click_to_add_factory_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETableClickToAddFactory), - 0, - (GInstanceInitFunc) gal_a11y_e_table_click_to_add_factory_init, - NULL /* value_table */ - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yETableClickToAddFactory", &info, 0); - } - - return type; -} diff --git a/widgets/table/gal-a11y-e-table-click-to-add-factory.h b/widgets/table/gal-a11y-e-table-click-to-add-factory.h deleted file mode 100644 index c7b2cf8e6a..0000000000 --- a/widgets/table/gal-a11y-e-table-click-to-add-factory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_H__ -#define __GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_H__ - -#include <atk/atkobjectfactory.h> - -#define GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY (gal_a11y_e_table_item_click_to_add_factory_get_type ()) -#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY, GalA11yETableClickToAddFactory)) -#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY, GalA11yETableClickToAddFactoryClass)) -#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY)) -#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY)) - -typedef struct _GalA11yETableClickToAddFactory GalA11yETableClickToAddFactory; -typedef struct _GalA11yETableClickToAddFactoryClass GalA11yETableClickToAddFactoryClass; - -struct _GalA11yETableClickToAddFactory { - AtkObject object; -}; - -struct _GalA11yETableClickToAddFactoryClass { - AtkObjectClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_click_to_add_factory_get_type (void); - -#endif diff --git a/widgets/table/gal-a11y-e-table-click-to-add.c b/widgets/table/gal-a11y-e-table-click-to-add.c deleted file mode 100644 index 52466cd7cb..0000000000 --- a/widgets/table/gal-a11y-e-table-click-to-add.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <atk/atk.h> - -#include "a11y/gal-a11y-util.h" -#include "table/e-table-click-to-add.h" -#include "table/e-table-group.h" -#include "table/e-table-group-leaf.h" -#include <glib/gi18n.h> - -#include "gal-a11y-e-table-click-to-add.h" -#include "gal-a11y-e-table-click-to-add-factory.h" - -static AtkObjectClass *parent_class; -static GType parent_type; -static gint priv_offset; -#define GET_PRIVATE(object) \ - ((GalA11yETableClickToAddPrivate *) \ - (((gchar *) object) + priv_offset)) -#define PARENT_TYPE (parent_type) - -struct _GalA11yETableClickToAddPrivate { - gpointer rect; - gpointer row; -}; - -static gint -etcta_get_n_actions (AtkAction *action) -{ - return 1; -} - -static const gchar * -etcta_get_description (AtkAction *action, - gint i) -{ - if (i == 0) - return _("click to add"); - - return NULL; -} - -static const gchar * -etcta_action_get_name (AtkAction *action, - gint i) -{ - if (i == 0) - return _("click"); - - return NULL; -} - -static gboolean -idle_do_action (gpointer data) -{ - GtkLayout *layout; - GdkEventButton event; - ETableClickToAdd * etcta; - gint finished; - - g_return_val_if_fail (data!= NULL, FALSE); - - etcta = E_TABLE_CLICK_TO_ADD ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (data))); - g_return_val_if_fail (etcta, FALSE); - - layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (etcta)->canvas); - - event.x = 0; - event.y = 0; - event.type = GDK_BUTTON_PRESS; - event.window = gtk_layout_get_bin_window (layout); - event.button = 1; - event.send_event = TRUE; - event.time = GDK_CURRENT_TIME; - event.axes = NULL; - - g_signal_emit_by_name (etcta, "event", &event, &finished); - - return FALSE; -} - -static gboolean -etcta_do_action (AtkAction *action, - gint i) -{ - g_return_val_if_fail (i == 0, FALSE); - - g_idle_add (idle_do_action, action); - - return TRUE; -} - -static void -atk_action_interface_init (AtkActionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->do_action = etcta_do_action; - iface->get_n_actions = etcta_get_n_actions; - iface->get_description = etcta_get_description; - iface->get_name = etcta_action_get_name; -} - -static const gchar * -etcta_get_name (AtkObject *obj) -{ - ETableClickToAdd * etcta; - - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (obj), NULL); - - etcta = E_TABLE_CLICK_TO_ADD ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (obj))); - if (etcta && etcta->message != NULL) - return etcta->message; - - return _("click to add"); -} - -static gint -etcta_get_n_children (AtkObject *accessible) -{ - return 1; -} - -static AtkObject * -etcta_ref_child (AtkObject *accessible, - gint i) -{ - AtkObject * atk_obj = NULL; - ETableClickToAdd * etcta; - - if (i != 0) - return NULL; - - etcta = E_TABLE_CLICK_TO_ADD ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (accessible))); - - g_return_val_if_fail (etcta, NULL); - - if (etcta->rect) { - atk_obj = atk_gobject_accessible_for_object ( - G_OBJECT (etcta->rect)); - } else if (etcta->row) { - atk_obj = atk_gobject_accessible_for_object ( - G_OBJECT (etcta->row)); - } - - g_object_ref (atk_obj); - - return atk_obj; -} - -static AtkStateSet * -etcta_ref_state_set (AtkObject *accessible) -{ - AtkStateSet * state_set = NULL; - - state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible); - if (state_set != NULL) { - atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (state_set, ATK_STATE_SHOWING); - } - - return state_set; -} - -static void -etcta_class_init (GalA11yETableClickToAddClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - atk_object_class->get_name = etcta_get_name; - atk_object_class->get_n_children = etcta_get_n_children; - atk_object_class->ref_child = etcta_ref_child; - atk_object_class->ref_state_set = etcta_ref_state_set; -} - -static void -etcta_init (GalA11yETableClickToAdd *a11y) -{ -} - -GType -gal_a11y_e_table_click_to_add_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - - GTypeInfo info = { - sizeof (GalA11yETableClickToAddClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) etcta_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETableClickToAdd), - 0, - (GInstanceInitFunc) etcta_init, - NULL /* value_table */ - }; - - static const GInterfaceInfo atk_action_info = { - (GInterfaceInitFunc) atk_action_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - factory = atk_registry_get_factory ( - atk_get_default_registry (), - GNOME_TYPE_CANVAS_ITEM); - - parent_type = atk_object_factory_get_accessible_type (factory); - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yETableClickToAdd", &info, 0, - sizeof (GalA11yETableClickToAddPrivate), &priv_offset); - - g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info); - - } - - return type; -} - -static gboolean -etcta_event (GnomeCanvasItem *item, - GdkEvent *e, - gpointer data) -{ - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item); - GalA11yETableClickToAdd *a11y; - GalA11yETableClickToAddPrivate *priv; - - g_return_val_if_fail (item, TRUE); - - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (data), FALSE); - a11y = GAL_A11Y_E_TABLE_CLICK_TO_ADD (data); - - priv = GET_PRIVATE (a11y); - - /* rect replaced by row. */ - if (etcta->rect == NULL && priv->rect != NULL) { - g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL); - - } - /* row inserted, and/or replaced by a new row. */ - if (etcta->row != NULL && priv->row == NULL) { - g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL); - } else if (etcta->row != NULL && priv->row != NULL && etcta->row != priv->row) { - g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL); - g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL); - } - - priv->rect = etcta->rect; - priv->row = etcta->row; - - return FALSE; -} - -static void -etcta_selection_cursor_changed (ESelectionModel *esm, - gint row, - gint col, - GalA11yETableClickToAdd *a11y) -{ - ETableClickToAdd *etcta; - AtkObject *row_a11y; - - etcta = E_TABLE_CLICK_TO_ADD ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (a11y))); - - if (etcta == NULL || etcta->row == NULL) - return; - - row_a11y = atk_gobject_accessible_for_object (G_OBJECT (etcta->row)); - if (row_a11y) { - AtkObject *cell_a11y; - - cell_a11y = g_object_get_data ( - G_OBJECT (row_a11y), "gail-focus-object"); - if (cell_a11y) { - atk_focus_tracker_notify (cell_a11y); - } - } -} - -AtkObject * -gal_a11y_e_table_click_to_add_new (GObject *widget) -{ - GalA11yETableClickToAdd *a11y; - ETableClickToAdd * etcta; - GalA11yETableClickToAddPrivate *priv; - - g_return_val_if_fail (widget != NULL, NULL); - - a11y = g_object_new (gal_a11y_e_table_click_to_add_get_type (), NULL); - priv = GET_PRIVATE (a11y); - - etcta = E_TABLE_CLICK_TO_ADD (widget); - - atk_object_initialize (ATK_OBJECT (a11y), etcta); - - priv->rect = etcta->rect; - priv->row = etcta->row; - - g_signal_connect_after ( - widget, "event", - G_CALLBACK (etcta_event), a11y); - - g_signal_connect ( - etcta->selection, "cursor_changed", - G_CALLBACK (etcta_selection_cursor_changed), a11y); - - return ATK_OBJECT (a11y); -} - -void -gal_a11y_e_table_click_to_add_init (void) -{ - if (atk_get_root ()) - atk_registry_set_factory_type ( - atk_get_default_registry (), - E_TYPE_TABLE_CLICK_TO_ADD, - gal_a11y_e_table_click_to_add_factory_get_type ()); -} - diff --git a/widgets/table/gal-a11y-e-table-click-to-add.h b/widgets/table/gal-a11y-e-table-click-to-add.h deleted file mode 100644 index 8d95a00baa..0000000000 --- a/widgets/table/gal-a11y-e-table-click-to-add.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__ -#define __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__ - -#include <table/e-table-item.h> -#include <atk/atkgobjectaccessible.h> - -#define GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD (gal_a11y_e_table_click_to_add_get_type ()) -#define GAL_A11Y_E_TABLE_CLICK_TO_ADD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD, GalA11yETableClickToAdd)) -#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD, GalA11yETableClickToAddClass)) -#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD)) -#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD)) - -typedef struct _GalA11yETableClickToAdd GalA11yETableClickToAdd; -typedef struct _GalA11yETableClickToAddClass GalA11yETableClickToAddClass; -typedef struct _GalA11yETableClickToAddPrivate GalA11yETableClickToAddPrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yETableClickToAddPrivate comes right after the parent class structure. - **/ -struct _GalA11yETableClickToAdd { - AtkGObjectAccessible parent; -}; - -struct _GalA11yETableClickToAddClass { - AtkGObjectAccessibleClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_click_to_add_get_type (void); -AtkObject *gal_a11y_e_table_click_to_add_new (GObject *widget); - -void gal_a11y_e_table_click_to_add_init (void); -#endif /* __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__ */ diff --git a/widgets/table/gal-a11y-e-table-column-header.c b/widgets/table/gal-a11y-e-table-column-header.c deleted file mode 100644 index 05a99e381b..0000000000 --- a/widgets/table/gal-a11y-e-table-column-header.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Li Yuan <li.yuan@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib/gi18n.h> -#include <atk/atkobject.h> -#include <atk/atkregistry.h> -#include "table/e-table-header-item.h" -#include "a11y/gal-a11y-util.h" -#include "gal-a11y-e-table-column-header.h" - -static GObjectClass *parent_class; -static gint priv_offset; - -#define GET_PRIVATE(object) \ - ((GalA11yETableColumnHeaderPrivate *) \ - (((gchar *) object) + priv_offset)) -#define PARENT_TYPE (atk_gobject_accessible_get_type ()) - -struct _GalA11yETableColumnHeaderPrivate { - ETableItem *item; - AtkObject *parent; - AtkStateSet *state_set; -}; - -static void -etch_init (GalA11yETableColumnHeader *a11y) -{ - GET_PRIVATE (a11y)->item = NULL; - GET_PRIVATE (a11y)->parent = NULL; - GET_PRIVATE (a11y)->state_set = NULL; -} - -static AtkStateSet * -gal_a11y_e_table_column_header_ref_state_set (AtkObject *accessible) -{ - GalA11yETableColumnHeaderPrivate *priv = GET_PRIVATE (accessible); - - g_return_val_if_fail (priv->state_set, NULL); - - g_object_ref (priv->state_set); - - return priv->state_set; -} - -static void -gal_a11y_e_table_column_header_real_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (parent_class)->initialize (obj, data); -} - -static void -gal_a11y_e_table_column_header_dispose (GObject *object) -{ - GalA11yETableColumnHeader *a11y = GAL_A11Y_E_TABLE_COLUMN_HEADER (object); - GalA11yETableColumnHeaderPrivate *priv = GET_PRIVATE (a11y); - - if (priv->state_set) { - g_object_unref (priv->state_set); - priv->state_set = NULL; - } - - if (parent_class->dispose) - parent_class->dispose (object); - -} - -static void -etch_class_init (GalA11yETableColumnHeaderClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->dispose = gal_a11y_e_table_column_header_dispose; - - atk_object_class->ref_state_set = gal_a11y_e_table_column_header_ref_state_set; - atk_object_class->initialize = gal_a11y_e_table_column_header_real_initialize; -} - -inline static GObject * -etch_a11y_get_gobject (AtkGObjectAccessible *accessible) -{ - return atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); -} - -static gboolean -gal_a11y_e_table_column_header_do_action (AtkAction *action, - gint i) -{ - gboolean return_value = TRUE; - GtkWidget *widget; - GalA11yETableColumnHeader *a11y; - ETableHeaderItem *ethi; - ETableItem *item; - ETableCol *col; - - switch (i) { - case 0: - a11y = GAL_A11Y_E_TABLE_COLUMN_HEADER (action); - col = E_TABLE_COL (etch_a11y_get_gobject ( - ATK_GOBJECT_ACCESSIBLE (a11y))); - item = GET_PRIVATE (a11y)->item; - widget = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas)); - if (E_IS_TREE (widget)) { - ethi = E_TABLE_HEADER_ITEM ( - e_tree_get_header_item (E_TREE (widget))); - } - else if (E_IS_TABLE (widget)) - ethi = E_TABLE_HEADER_ITEM ( - E_TABLE (widget)->header_item); - else - break; - ethi_change_sort_state (ethi, col); - default: - return_value = FALSE; - break; - } - return return_value; -} - -static gint -gal_a11y_e_table_column_header_get_n_actions (AtkAction *action) -{ - return 1; -} - -static const gchar * -gal_a11y_e_table_column_header_action_get_name (AtkAction *action, - gint i) -{ - const gchar *return_value; - - switch (i) { - case 0: - return_value = _("sort"); - break; - default: - return_value = NULL; - break; - } - return return_value; -} - -static void -atk_action_interface_init (AtkActionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->do_action = gal_a11y_e_table_column_header_do_action; - iface->get_n_actions = gal_a11y_e_table_column_header_get_n_actions; - iface->get_name = gal_a11y_e_table_column_header_action_get_name; -} - -GType -gal_a11y_e_table_column_header_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETableColumnHeaderClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) etch_class_init, - (GClassFinalizeFunc) NULL, - NULL, - sizeof (GalA11yETableColumnHeader), - 0, - (GInstanceInitFunc) etch_init, - NULL - }; - static const GInterfaceInfo atk_action_info = { - (GInterfaceInitFunc) atk_action_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yETableColumnHeader", &info, 0, - sizeof (GalA11yETableColumnHeaderPrivate), &priv_offset); - - g_type_add_interface_static ( - type, ATK_TYPE_ACTION, &atk_action_info); - } - - return type; -} - -AtkObject * -gal_a11y_e_table_column_header_new (ETableCol *ecol, - ETableItem *item) -{ - GalA11yETableColumnHeader *a11y; - AtkObject *accessible; - - g_return_val_if_fail (E_IS_TABLE_COL (ecol), NULL); - - a11y = g_object_new (gal_a11y_e_table_column_header_get_type (), NULL); - accessible = ATK_OBJECT (a11y); - atk_object_initialize (accessible, ecol); - - GET_PRIVATE (a11y)->item = item; - GET_PRIVATE (a11y)->state_set = atk_state_set_new (); - - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_VISIBLE); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_SHOWING); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_ENABLED); - - if (ecol->text) - atk_object_set_name (accessible, ecol->text); - atk_object_set_role (accessible, ATK_ROLE_TABLE_COLUMN_HEADER); - - return ATK_OBJECT (a11y); -} diff --git a/widgets/table/gal-a11y-e-table-column-header.h b/widgets/table/gal-a11y-e-table-column-header.h deleted file mode 100644 index 20d41004f2..0000000000 --- a/widgets/table/gal-a11y-e-table-column-header.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Li Yuan <li.yuan@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__ -#define __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__ - -#include <atk/atkgobjectaccessible.h> - -#define GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER (gal_a11y_e_table_column_header_get_type ()) -#define GAL_A11Y_E_TABLE_COLUMN_HEADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER, GalA11yETableColumnHeader)) -#define GAL_A11Y_E_TABLE_COLUMN_HEADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER, GalA11yETableColumnHeaderClass)) -#define GAL_A11Y_IS_E_TABLE_COLUMN_HEADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER)) -#define GAL_A11Y_IS_E_TABLE_COLUMN_HEADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER)) - -typedef struct _GalA11yETableColumnHeader GalA11yETableColumnHeader; -typedef struct _GalA11yETableColumnHeaderClass GalA11yETableColumnHeaderClass; -typedef struct _GalA11yETableColumnHeaderPrivate GalA11yETableColumnHeaderPrivate; - -struct _GalA11yETableColumnHeader { - AtkGObjectAccessible parent; -}; - -struct _GalA11yETableColumnHeaderClass { - AtkGObjectAccessibleClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_column_header_get_type (void); -AtkObject *gal_a11y_e_table_column_header_new (ETableCol *etc, ETableItem *item); -void gal_a11y_e_table_column_header_init (void); - -#endif /* __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__ */ diff --git a/widgets/table/gal-a11y-e-table-factory.c b/widgets/table/gal-a11y-e-table-factory.c deleted file mode 100644 index a3905ab393..0000000000 --- a/widgets/table/gal-a11y-e-table-factory.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gal-a11y-e-table.h" -#include "gal-a11y-e-table-factory.h" - -static AtkObjectFactoryClass *parent_class; -#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY) - -/* Static functions */ - -static GType -gal_a11y_e_table_factory_get_accessible_type (void) -{ - return GAL_A11Y_TYPE_E_TABLE; -} - -static AtkObject * -gal_a11y_e_table_factory_create_accessible (GObject *obj) -{ - AtkObject *accessible; - - accessible = gal_a11y_e_table_new (obj); - - return accessible; -} - -static void -gal_a11y_e_table_factory_class_init (GalA11yETableFactoryClass *class) -{ - AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - factory_class->create_accessible = gal_a11y_e_table_factory_create_accessible; - factory_class->get_accessible_type = gal_a11y_e_table_factory_get_accessible_type; -} - -static void -gal_a11y_e_table_factory_init (GalA11yETableFactory *factory) -{ -} - -/** - * gal_a11y_e_table_factory_get_type: - * @void: - * - * Registers the &GalA11yETableFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETableFactory class. - **/ -GType -gal_a11y_e_table_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETableFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_table_factory_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETableFactory), - 0, - (GInstanceInitFunc) gal_a11y_e_table_factory_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - PARENT_TYPE, "GalA11yETableFactory", &info, 0); - } - - return type; -} diff --git a/widgets/table/gal-a11y-e-table-factory.h b/widgets/table/gal-a11y-e-table-factory.h deleted file mode 100644 index 6f66e6b82a..0000000000 --- a/widgets/table/gal-a11y-e-table-factory.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_FACTORY_H__ -#define __GAL_A11Y_E_TABLE_FACTORY_H__ - -#include <atk/atkobjectfactory.h> - -#define GAL_A11Y_TYPE_E_TABLE_FACTORY (gal_a11y_e_table_factory_get_type ()) -#define GAL_A11Y_E_TABLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_FACTORY, GalA11yETableFactory)) -#define GAL_A11Y_E_TABLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_FACTORY, GalA11yETableFactoryClass)) -#define GAL_A11Y_IS_E_TABLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_FACTORY)) -#define GAL_A11Y_IS_E_TABLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_FACTORY)) - -typedef struct _GalA11yETableFactory GalA11yETableFactory; -typedef struct _GalA11yETableFactoryClass GalA11yETableFactoryClass; - -struct _GalA11yETableFactory { - AtkObject object; -}; - -struct _GalA11yETableFactoryClass { - AtkObjectClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_factory_get_type (void); - -#endif /* __GAL_A11Y_E_TABLE_FACTORY_H__ */ diff --git a/widgets/table/gal-a11y-e-table-item-factory.c b/widgets/table/gal-a11y-e-table-item-factory.c deleted file mode 100644 index a38269bd81..0000000000 --- a/widgets/table/gal-a11y-e-table-item-factory.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <atk/atk.h> - -#include "table/e-table.h" -#include "table/e-tree.h" - -#include "gal-a11y-e-table.h" -#include "gal-a11y-e-table-item.h" -#include "gal-a11y-e-table-item-factory.h" - -#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETableItemFactoryClass)) -static AtkObjectFactoryClass *parent_class; -#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY) - -/* Static functions */ - -static GType -gal_a11y_e_table_item_factory_get_accessible_type (void) -{ - return GAL_A11Y_TYPE_E_TABLE_ITEM; -} - -static AtkObject * -gal_a11y_e_table_item_factory_create_accessible (GObject *obj) -{ - AtkObject *accessible; - - g_return_val_if_fail (E_IS_TABLE_ITEM (obj), NULL); - accessible = gal_a11y_e_table_item_new (E_TABLE_ITEM (obj)); - - return accessible; -} - -static void -gal_a11y_e_table_item_factory_class_init (GalA11yETableItemFactoryClass *class) -{ - AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - factory_class->create_accessible = gal_a11y_e_table_item_factory_create_accessible; - factory_class->get_accessible_type = gal_a11y_e_table_item_factory_get_accessible_type; -} - -static void -gal_a11y_e_table_item_factory_init (GalA11yETableItemFactory *factory) -{ -} - -/** - * gal_a11y_e_table_factory_get_type: - * @void: - * - * Registers the &GalA11yETableFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETableFactory class. - **/ -GType -gal_a11y_e_table_item_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETableItemFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_table_item_factory_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETableItemFactory), - 0, - (GInstanceInitFunc) gal_a11y_e_table_item_factory_init, - NULL /* value_table */ - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yETableItemFactory", &info, 0); - } - - return type; -} diff --git a/widgets/table/gal-a11y-e-table-item-factory.h b/widgets/table/gal-a11y-e-table-item-factory.h deleted file mode 100644 index c2995eaaf0..0000000000 --- a/widgets/table/gal-a11y-e-table-item-factory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_ITEM_FACTORY_H__ -#define __GAL_A11Y_E_TABLE_ITEM_FACTORY_H__ - -#include <atk/atkobjectfactory.h> - -#define GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY (gal_a11y_e_table_item_factory_get_type ()) -#define GAL_A11Y_E_TABLE_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY, GalA11yETableItemFactory)) -#define GAL_A11Y_E_TABLE_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY, GalA11yETableItemFactoryClass)) -#define GAL_A11Y_IS_E_TABLE_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY)) -#define GAL_A11Y_IS_E_TABLE_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY)) - -typedef struct _GalA11yETableItemFactory GalA11yETableItemFactory; -typedef struct _GalA11yETableItemFactoryClass GalA11yETableItemFactoryClass; - -struct _GalA11yETableItemFactory { - AtkObject object; -}; - -struct _GalA11yETableItemFactoryClass { - AtkObjectClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_item_factory_get_type (void); - -#endif /* __GAL_A11Y_E_TABLE_FACTORY_H__ */ diff --git a/widgets/table/gal-a11y-e-table-item.c b/widgets/table/gal-a11y-e-table-item.c deleted file mode 100644 index d5a0edefdc..0000000000 --- a/widgets/table/gal-a11y-e-table-item.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * Bolian Yin <bolian.yin@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <atk/atk.h> - -#include "a11y/gal-a11y-util.h" -#include "table/e-table-click-to-add.h" -#include "table/e-table-subset.h" -#include "table/e-table.h" -#include "table/e-tree.h" -#include "misc/e-canvas.h" -#include "misc/e-selection-model.h" - -#include "gal-a11y-e-table-item.h" -#include "gal-a11y-e-table-item-factory.h" -#include "gal-a11y-e-table-click-to-add.h" -#include "gal-a11y-e-cell-registry.h" -#include "gal-a11y-e-cell.h" -#include "gal-a11y-e-table-column-header.h" - -static GObjectClass *parent_class; -static AtkComponentIface *component_parent_iface; -static GType parent_type; -static gint priv_offset; -static GQuark quark_accessible_object = 0; -#define GET_PRIVATE(object) \ - ((GalA11yETableItemPrivate *) (((gchar *) object) + priv_offset)) -#define PARENT_TYPE (parent_type) - -struct _GalA11yETableItemPrivate { - ETableItem *item; - gint cols; - gint rows; - gint selection_change_id; - gint cursor_change_id; - ETableCol ** columns; - ESelectionModel *selection; - AtkStateSet *state_set; - GtkWidget *widget; -}; - -static gboolean gal_a11y_e_table_item_ref_selection (GalA11yETableItem *a11y, - ESelectionModel *selection); -static gboolean gal_a11y_e_table_item_unref_selection (GalA11yETableItem *a11y); - -static AtkObject * eti_ref_at (AtkTable *table, gint row, gint column); - -static void -free_columns (ETableCol **columns) -{ - gint ii; - - if (!columns) - return; - - for (ii = 0; columns[ii]; ii++) { - g_object_unref (columns[ii]); - } - - g_free (columns); -} - -static void -item_finalized (gpointer user_data, - GObject *gone_item) -{ - GalA11yETableItem *a11y; - GalA11yETableItemPrivate *priv; - - a11y = GAL_A11Y_E_TABLE_ITEM (user_data); - priv = GET_PRIVATE (a11y); - - priv->item = NULL; - - atk_state_set_add_state (priv->state_set, ATK_STATE_DEFUNCT); - atk_object_notify_state_change (ATK_OBJECT (a11y), ATK_STATE_DEFUNCT, TRUE); - - if (priv->selection) - gal_a11y_e_table_item_unref_selection (a11y); - - g_object_unref (a11y); -} - -static AtkStateSet * -eti_ref_state_set (AtkObject *accessible) -{ - GalA11yETableItemPrivate *priv = GET_PRIVATE (accessible); - - g_object_ref (priv->state_set); - - return priv->state_set; -} - -inline static gint -view_to_model_row (ETableItem *eti, - gint row) -{ - if (eti->uses_source_model) { - ETableSubset *etss = E_TABLE_SUBSET (eti->table_model); - if (row >= 0 && row < etss->n_map) { - eti->row_guess = row; - return etss->map_table[row]; - } else - return -1; - } else - return row; -} - -inline static gint -view_to_model_col (ETableItem *eti, - gint col) -{ - ETableCol *ecol = e_table_header_get_column (eti->header, col); - return ecol ? ecol->col_idx : -1; -} - -inline static gint -model_to_view_row (ETableItem *eti, - gint row) -{ - gint i; - if (row == -1) - return -1; - if (eti->uses_source_model) { - ETableSubset *etss = E_TABLE_SUBSET (eti->table_model); - if (eti->row_guess >= 0 && eti->row_guess < etss->n_map) { - if (etss->map_table[eti->row_guess] == row) { - return eti->row_guess; - } - } - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] == row) - return i; - } - return -1; - } else - return row; -} - -inline static gint -model_to_view_col (ETableItem *eti, - gint col) -{ - gint i; - if (col == -1) - return -1; - for (i = 0; i < eti->cols; i++) { - ETableCol *ecol = e_table_header_get_column (eti->header, i); - if (ecol->col_idx == col) - return i; - } - return -1; -} - -inline static GObject * -eti_a11y_get_gobject (AtkObject *accessible) -{ - return atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); -} - -static void -eti_a11y_reset_focus_object (GalA11yETableItem *a11y, - ETableItem *item, - gboolean notify) -{ - ESelectionModel * esm; - gint cursor_row, cursor_col, view_row, view_col; - AtkObject *cell, *old_cell; - - esm = item->selection; - g_return_if_fail (esm); - - cursor_row = e_selection_model_cursor_row (esm); - cursor_col = e_selection_model_cursor_col (esm); - - view_row = model_to_view_row (item, cursor_row); - view_col = model_to_view_col (item, cursor_col); - - if (view_row == -1) - view_row = 0; - if (view_col == -1) - view_col = 0; - - old_cell = (AtkObject *) g_object_get_data (G_OBJECT (a11y), "gail-focus-object"); - if (old_cell && GAL_A11Y_IS_E_CELL (old_cell)) - gal_a11y_e_cell_remove_state ( - GAL_A11Y_E_CELL (old_cell), ATK_STATE_FOCUSED, FALSE); - if (old_cell) - g_object_unref (old_cell); - - cell = eti_ref_at (ATK_TABLE (a11y), view_row, view_col); - - if (cell != NULL) { - g_object_set_data (G_OBJECT (a11y), "gail-focus-object", cell); - gal_a11y_e_cell_add_state ( - GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE); - } else - g_object_set_data (G_OBJECT (a11y), "gail-focus-object", NULL); - - if (notify && cell) - atk_focus_tracker_notify (cell); -} - -static void -eti_dispose (GObject *object) -{ - GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (object); - GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); - - if (priv->columns) { - free_columns (priv->columns); - priv->columns = NULL; - } - - if (priv->item) { - g_object_weak_unref (G_OBJECT (priv->item), item_finalized, a11y); - priv->item = NULL; - } - - if (parent_class->dispose) - parent_class->dispose (object); -} - -/* Static functions */ -static gint -eti_get_n_children (AtkObject *accessible) -{ - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), 0); - if (!eti_a11y_get_gobject (accessible)) - return 0; - - return atk_table_get_n_columns (ATK_TABLE (accessible)) * - (atk_table_get_n_rows (ATK_TABLE (accessible)) + 1); -} - -static AtkObject * -eti_ref_child (AtkObject *accessible, - gint index) -{ - ETableItem *item; - gint col, row; - - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), NULL); - item = E_TABLE_ITEM (eti_a11y_get_gobject (accessible)); - if (!item) - return NULL; - - if (index < item->cols) { - ETableCol *ecol; - AtkObject *child; - - ecol = e_table_header_get_column (item->header, index); - child = gal_a11y_e_table_column_header_new (ecol, item); - return child; - } - index -= item->cols; - - col = index % item->cols; - row = index / item->cols; - - return eti_ref_at (ATK_TABLE (accessible), row, col); -} - -static void -eti_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - ETableItem *item; - AtkObject *parent; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component))); - if (!item) - return; - - parent = ATK_OBJECT (component)->accessible_parent; - if (parent && ATK_IS_COMPONENT (parent)) - atk_component_get_extents ( - ATK_COMPONENT (parent), - x, y, - width, height, - coord_type); - - if (parent && GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (parent)) { - ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (parent))); - if (etcta) { - *width = etcta->width; - *height = etcta->height; - } - } -} - -static AtkObject * -eti_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - gint row = -1; - gint col = -1; - gint x_origin, y_origin; - ETableItem *item; - GtkWidget *tableOrTree; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component))); - if (!item) - return NULL; - - atk_component_get_position ( - component, - &x_origin, - &y_origin, - coord_type); - x -= x_origin; - y -= y_origin; - - tableOrTree = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas)); - - if (E_IS_TREE (tableOrTree)) - e_tree_get_cell_at (E_TREE (tableOrTree), x, y, &row, &col); - else - e_table_get_cell_at (E_TABLE (tableOrTree), x, y, &row, &col); - - if (row != -1 && col != -1) { - return eti_ref_at (ATK_TABLE (component), row, col); - } else { - return NULL; - } -} - -static void -cell_destroyed (gpointer data) -{ - GalA11yECell * cell; - - g_return_if_fail (GAL_A11Y_IS_E_CELL (data)); - cell = GAL_A11Y_E_CELL (data); - - g_return_if_fail (cell->item && G_IS_OBJECT (cell->item)); - - if (cell->item) { - g_object_unref (cell->item); - cell->item = NULL; - } - -} - -/* atk table */ -static AtkObject * -eti_ref_at (AtkTable *table, - gint row, - gint column) -{ - ETableItem *item; - AtkObject * ret; - GalA11yETableItemPrivate *priv = GET_PRIVATE (table); - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return NULL; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return NULL; - - if (column >= 0 && - column < item->cols && - row >= 0 && - row < item->rows && - item->cell_views_realized) { - ECellView *cell_view = item->cell_views[column]; - ETableCol *ecol = e_table_header_get_column (item->header, column); - ret = gal_a11y_e_cell_registry_get_object ( - NULL, - item, - cell_view, - ATK_OBJECT (table), - ecol->col_idx, - column, - row); - if (ATK_IS_OBJECT (ret)) { - g_object_weak_ref ( - G_OBJECT (ret), - (GWeakNotify) cell_destroyed, - ret); - /* if current cell is focused, add FOCUSED state */ - if (e_selection_model_cursor_row (item->selection) == - GAL_A11Y_E_CELL (ret)->row && - e_selection_model_cursor_col (item->selection) == - GAL_A11Y_E_CELL (ret)->model_col) - gal_a11y_e_cell_add_state ( - GAL_A11Y_E_CELL (ret), - ATK_STATE_FOCUSED, FALSE); - } else - ret = NULL; - - return ret; - } - - return NULL; -} - -static gint -eti_get_index_at (AtkTable *table, - gint row, - gint column) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - return column + (row + 1) * item->cols; -} - -static gint -eti_get_column_at_index (AtkTable *table, - gint index) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - return index % item->cols; -} - -static gint -eti_get_row_at_index (AtkTable *table, - gint index) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - return index / item->cols - 1; -} - -static gint -eti_get_n_columns (AtkTable *table) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - return item->cols; -} - -static gint -eti_get_n_rows (AtkTable *table) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - return item->rows; -} - -static gint -eti_get_column_extent_at (AtkTable *table, - gint row, - gint column) -{ - ETableItem *item; - gint width; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - e_table_item_get_cell_geometry ( - item, - &row, - &column, - NULL, - NULL, - &width, - NULL); - - return width; -} - -static gint -eti_get_row_extent_at (AtkTable *table, - gint row, - gint column) -{ - ETableItem *item; - gint height; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return -1; - - e_table_item_get_cell_geometry ( - item, - &row, - &column, - NULL, - NULL, - NULL, - &height); - - return height; -} - -static AtkObject * -eti_get_caption (AtkTable *table) -{ - /* Unimplemented */ - return NULL; -} - -static const gchar * -eti_get_column_description (AtkTable *table, - gint column) -{ - ETableItem *item; - ETableCol *ecol; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return NULL; - - ecol = e_table_header_get_column (item->header, column); - - return ecol->text; -} - -static AtkObject * -eti_get_column_header (AtkTable *table, - gint column) -{ - ETableItem *item; - ETableCol *ecol; - AtkObject *atk_obj = NULL; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return NULL; - - ecol = e_table_header_get_column (item->header, column); - if (ecol) { - atk_obj = gal_a11y_e_table_column_header_new (ecol, item); - } - - return atk_obj; -} - -static const gchar * -eti_get_row_description (AtkTable *table, - gint row) -{ - /* Unimplemented */ - return NULL; -} - -static AtkObject * -eti_get_row_header (AtkTable *table, - gint row) -{ - /* Unimplemented */ - return NULL; -} - -static AtkObject * -eti_get_summary (AtkTable *table) -{ - /* Unimplemented */ - return NULL; -} - -static gboolean -table_is_row_selected (AtkTable *table, - gint row) -{ - ETableItem *item; - GalA11yETableItemPrivate *priv = GET_PRIVATE (table); - - if (row < 0) - return FALSE; - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return FALSE; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return FALSE; - - return e_selection_model_is_row_selected ( - item->selection, view_to_model_row (item, row)); -} - -static gboolean -table_is_selected (AtkTable *table, - gint row, - gint column) -{ - return table_is_row_selected (table, row); -} - -static gint -table_get_selected_rows (AtkTable *table, - gint **rows_selected) -{ - ETableItem *item; - gint n_selected, row, index_selected; - GalA11yETableItemPrivate *priv = GET_PRIVATE (table); - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return 0; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return 0; - - n_selected = e_selection_model_selected_count (item->selection); - if (rows_selected) { - *rows_selected = (gint *) g_malloc (n_selected * sizeof (gint)); - - index_selected = 0; - for (row = 0; row < item->rows && index_selected < n_selected; ++row) { - if (atk_table_is_row_selected (table, row)) { - (*rows_selected)[index_selected] = row; - ++index_selected; - } - } - } - return n_selected; -} - -static gboolean -table_add_row_selection (AtkTable *table, - gint row) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return FALSE; - - if (table_is_row_selected (table, row)) - return TRUE; - e_selection_model_toggle_single_row ( - item->selection, - view_to_model_row (item, row)); - - return TRUE; -} - -static gboolean -table_remove_row_selection (AtkTable *table, - gint row) -{ - ETableItem *item; - GalA11yETableItemPrivate *priv = GET_PRIVATE (table); - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return FALSE; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); - if (!item) - return FALSE; - - if (!atk_table_is_row_selected (table, row)) - return TRUE; - - e_selection_model_toggle_single_row ( - item->selection, view_to_model_row (item, row)); - - return TRUE; -} - -static void -eti_atk_table_iface_init (AtkTableIface *iface) -{ - iface->ref_at = eti_ref_at; - iface->get_index_at = eti_get_index_at; - iface->get_column_at_index = eti_get_column_at_index; - iface->get_row_at_index = eti_get_row_at_index; - iface->get_n_columns = eti_get_n_columns; - iface->get_n_rows = eti_get_n_rows; - iface->get_column_extent_at = eti_get_column_extent_at; - iface->get_row_extent_at = eti_get_row_extent_at; - iface->get_caption = eti_get_caption; - iface->get_column_description = eti_get_column_description; - iface->get_column_header = eti_get_column_header; - iface->get_row_description = eti_get_row_description; - iface->get_row_header = eti_get_row_header; - iface->get_summary = eti_get_summary; - - iface->is_row_selected = table_is_row_selected; - iface->is_selected = table_is_selected; - iface->get_selected_rows = table_get_selected_rows; - iface->add_row_selection = table_add_row_selection; - iface->remove_row_selection = table_remove_row_selection; -} - -static void -eti_atk_component_iface_init (AtkComponentIface *iface) -{ - component_parent_iface = g_type_interface_peek_parent (iface); - - iface->ref_accessible_at_point = eti_ref_accessible_at_point; - iface->get_extents = eti_get_extents; -} - -static void -eti_rows_inserted (ETableModel *model, - gint row, - gint count, - AtkObject *table_item) -{ - gint n_cols,n_rows,i,j; - GalA11yETableItem * item_a11y; - gint old_nrows; - - g_return_if_fail (table_item); - item_a11y = GAL_A11Y_E_TABLE_ITEM (table_item); - - n_cols = atk_table_get_n_columns (ATK_TABLE (table_item)); - n_rows = atk_table_get_n_rows (ATK_TABLE (table_item)); - - old_nrows = GET_PRIVATE (item_a11y)->rows; - - g_return_if_fail (n_cols > 0 && n_rows > 0); - g_return_if_fail (old_nrows == n_rows - count); - - GET_PRIVATE (table_item)->rows = n_rows; - - g_signal_emit_by_name ( - table_item, "row-inserted", row, - count, NULL); - - for (i = row; i < (row + count); i++) { - for (j = 0; j < n_cols; j++) { - g_signal_emit_by_name ( - table_item, - "children_changed::add", - (((i + 1) * n_cols) + j), NULL, NULL); - } - } - - g_signal_emit_by_name (table_item, "visible-data-changed"); -} - -static void -eti_rows_deleted (ETableModel *model, - gint row, - gint count, - AtkObject *table_item) -{ - gint i,j, n_rows, n_cols, old_nrows; - ETableItem *item = E_TABLE_ITEM ( - atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (table_item))); - - n_rows = atk_table_get_n_rows (ATK_TABLE (table_item)); - n_cols = atk_table_get_n_columns (ATK_TABLE (table_item)); - - old_nrows = GET_PRIVATE (table_item)->rows; - - g_return_if_fail (row + count <= old_nrows); - g_return_if_fail (old_nrows == n_rows + count); - GET_PRIVATE (table_item)->rows = n_rows; - - g_signal_emit_by_name ( - table_item, "row-deleted", row, - count, NULL); - - for (i = row; i < (row + count); i++) { - for (j = 0; j < n_cols; j++) { - g_signal_emit_by_name ( - table_item, - "children_changed::remove", - (((i + 1) * n_cols) + j), NULL, NULL); - } - } - g_signal_emit_by_name (table_item, "visible-data-changed"); - eti_a11y_reset_focus_object ((GalA11yETableItem *) table_item, item, TRUE); -} - -static void -eti_tree_model_node_changed_cb (ETreeModel *model, - ETreePath node, - ETableItem *eti) -{ - AtkObject *atk_obj; - GalA11yETableItem *a11y; - - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti)); - a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj); - - /* we can't figure out which rows are changed, so just send out a signal ... */ - if (GET_PRIVATE (a11y)->rows > 0) - g_signal_emit_by_name (a11y, "visible-data-changed"); -} - -enum { - ETI_HEADER_UNCHANGED = 0, - ETI_HEADER_REORDERED, - ETI_HEADER_NEW_ADDED, - ETI_HEADER_REMOVED -}; - -/* - * 1. Check what actually happened: column reorder, remove or add - * 2. Update cache - * 3. Emit signals - */ -static void -eti_header_structure_changed (ETableHeader *eth, - AtkObject *a11y) -{ - - gboolean reorder_found = FALSE, added_found = FALSE, removed_found = FALSE; - GalA11yETableItem * a11y_item; - ETableCol ** cols, **prev_cols; - GalA11yETableItemPrivate *priv; - gint *state = NULL, *prev_state = NULL, *reorder = NULL; - gint i,j,n_rows,n_cols, prev_n_cols; - - a11y_item = GAL_A11Y_E_TABLE_ITEM (a11y); - priv = GET_PRIVATE (a11y_item); - - /* Assume rows do not changed. */ - n_rows = priv->rows; - - prev_n_cols = priv->cols; - prev_cols = priv->columns; - - cols = e_table_header_get_columns (eth); - n_cols = eth->col_count; - - g_return_if_fail (cols && prev_cols && n_cols > 0); - - /* Init to ETI_HEADER_UNCHANGED. */ - state = g_malloc0 (sizeof (gint) * n_cols); - prev_state = g_malloc0 (sizeof (gint) * prev_n_cols); - reorder = g_malloc0 (sizeof (gint) * n_cols); - - /* Compare with previously saved column headers. */ - for (i = 0; i < n_cols && cols[i]; i++) { - for (j = 0; j < prev_n_cols && prev_cols[j]; j++) { - if (prev_cols[j] == cols[i] && i != j) { - - reorder_found = TRUE; - state[i] = ETI_HEADER_REORDERED; - reorder[i] = j; - - break; - } else if (prev_cols[j] == cols[i]) { - /* OK, this column is not changed. */ - break; - } - } - - /* cols[i] is new added column. */ - if (j == prev_n_cols) { - added_found = TRUE; - state[i] = ETI_HEADER_NEW_ADDED; - } - } - - /* Now try to find if there are removed columns. */ - for (i = 0; i < prev_n_cols && prev_cols[i]; i++) { - for (j = 0; j < n_cols && cols[j]; j++) - if (prev_cols[j] == cols[i]) - break; - - /* Removed columns found. */ - if (j == n_cols) { - removed_found = TRUE; - prev_state[j] = ETI_HEADER_REMOVED; - } - } - - /* If nothing interesting just return. */ - if (!reorder_found && !added_found && !removed_found) - return; - - /* Emit signals */ - if (reorder_found) - g_signal_emit_by_name (a11y_item, "column_reordered"); - - if (removed_found) { - for (i = 0; i < prev_n_cols; i++) { - if (prev_state[i] == ETI_HEADER_REMOVED) { - g_signal_emit_by_name ( - a11y_item, "column-deleted", i, 1); - for (j = 0; j < n_rows; j++) - g_signal_emit_by_name ( - a11y_item, - "children_changed::remove", - ((j + 1) * prev_n_cols + i), - NULL, NULL); - } - } - } - - if (added_found) { - for (i = 0; i < n_cols; i++) { - if (state[i] == ETI_HEADER_NEW_ADDED) { - g_signal_emit_by_name ( - a11y_item, "column-inserted", i, 1); - for (j = 0; j < n_rows; j++) - g_signal_emit_by_name ( - a11y_item, - "children_changed::add", - ((j + 1) * n_cols + i), - NULL, NULL); - } - } - } - - priv->cols = n_cols; - - g_free (state); - g_free (reorder); - g_free (prev_state); - - free_columns (priv->columns); - priv->columns = cols; -} - -static void -eti_real_initialize (AtkObject *obj, - gpointer data) -{ - ETableItem * eti; - ETableModel * model; - - ATK_OBJECT_CLASS (parent_class)->initialize (obj, data); - eti = E_TABLE_ITEM (data); - - model = eti->table_model; - - g_signal_connect ( - model, "model-rows-inserted", - G_CALLBACK (eti_rows_inserted), obj); - g_signal_connect ( - model, "model-rows-deleted", - G_CALLBACK (eti_rows_deleted), obj); - g_signal_connect ( - eti->header, "structure_change", - G_CALLBACK (eti_header_structure_changed), obj); - -} - -static void -eti_class_init (GalA11yETableItemClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - quark_accessible_object = - g_quark_from_static_string ("gtk-accessible-object"); - - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->dispose = eti_dispose; - - atk_object_class->get_n_children = eti_get_n_children; - atk_object_class->ref_child = eti_ref_child; - atk_object_class->initialize = eti_real_initialize; - atk_object_class->ref_state_set = eti_ref_state_set; -} - -static void -eti_init (GalA11yETableItem *a11y) -{ - GalA11yETableItemPrivate *priv; - - priv = GET_PRIVATE (a11y); - - priv->selection_change_id = 0; - priv->cursor_change_id = 0; - priv->selection = NULL; -} - -/* atk selection */ - -static void atk_selection_interface_init (AtkSelectionIface *iface); -static gboolean selection_add_selection (AtkSelection *selection, - gint i); -static gboolean selection_clear_selection (AtkSelection *selection); -static AtkObject * - selection_ref_selection (AtkSelection *selection, - gint i); -static gint selection_get_selection_count (AtkSelection *selection); -static gboolean selection_is_child_selected (AtkSelection *selection, - gint i); - -/* callbacks */ -static void eti_a11y_selection_model_removed_cb (ETableItem *eti, - ESelectionModel *selection, - gpointer data); -static void eti_a11y_selection_model_added_cb (ETableItem *eti, - ESelectionModel *selection, - gpointer data); -static void eti_a11y_selection_changed_cb (ESelectionModel *selection, - GalA11yETableItem *a11y); -static void eti_a11y_cursor_changed_cb (ESelectionModel *selection, - gint row, gint col, - GalA11yETableItem *a11y); - -/** - * gal_a11y_e_table_item_get_type: - * @void: - * - * Registers the &GalA11yETableItem class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETableItem class. - **/ -GType -gal_a11y_e_table_item_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - - GTypeInfo info = { - sizeof (GalA11yETableItemClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) eti_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETableItem), - 0, - (GInstanceInitFunc) eti_init, - NULL /* value_table_item */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) eti_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - static const GInterfaceInfo atk_table_info = { - (GInterfaceInitFunc) eti_atk_table_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - static const GInterfaceInfo atk_selection_info = { - (GInterfaceInitFunc) atk_selection_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - factory = atk_registry_get_factory ( - atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM); - parent_type = atk_object_factory_get_accessible_type (factory); - - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yETableItem", &info, 0, - sizeof (GalA11yETableItemPrivate), &priv_offset); - - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); - g_type_add_interface_static (type, ATK_TYPE_TABLE, &atk_table_info); - g_type_add_interface_static (type, ATK_TYPE_SELECTION, &atk_selection_info); - } - - return type; -} - -AtkObject * -gal_a11y_e_table_item_new (ETableItem *item) -{ - GalA11yETableItem *a11y; - AtkObject *accessible; - ESelectionModel * esm; - AtkObject *parent; - const gchar *name; - - g_return_val_if_fail (item && item->cols >= 0 && item->rows >= 0, NULL); - a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL); - - atk_object_initialize (ATK_OBJECT (a11y), item); - - GET_PRIVATE (a11y)->state_set = atk_state_set_new (); - - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_TRANSIENT); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_SHOWING); - atk_state_set_add_state (GET_PRIVATE (a11y)->state_set, ATK_STATE_VISIBLE); - - accessible = ATK_OBJECT (a11y); - - GET_PRIVATE (a11y)->item = item; - /* Initialize cell data. */ - GET_PRIVATE (a11y)->cols = item->cols; - GET_PRIVATE (a11y)->rows = item->rows; - - GET_PRIVATE (a11y)->columns = e_table_header_get_columns (item->header); - if (GET_PRIVATE (a11y)->columns == NULL) - return NULL; - - if (item) { - g_signal_connect ( - item, "selection_model_removed", - G_CALLBACK (eti_a11y_selection_model_removed_cb), NULL); - g_signal_connect ( - item, "selection_model_added", - G_CALLBACK (eti_a11y_selection_model_added_cb), NULL); - if (item->selection) - gal_a11y_e_table_item_ref_selection ( - a11y, - item->selection); - - /* find the TableItem's parent: table or tree */ - GET_PRIVATE (a11y)->widget = gtk_widget_get_parent ( - GTK_WIDGET (item->parent.canvas)); - parent = gtk_widget_get_accessible (GET_PRIVATE (a11y)->widget); - name = atk_object_get_name (parent); - if (name) - atk_object_set_name (accessible, name); - atk_object_set_parent (accessible, parent); - - if (E_IS_TREE (GET_PRIVATE (a11y)->widget)) { - ETreeModel *model; - model = e_tree_get_model (E_TREE (GET_PRIVATE (a11y)->widget)); - g_signal_connect ( - model, "node_changed", - G_CALLBACK (eti_tree_model_node_changed_cb), item); - accessible->role = ATK_ROLE_TREE_TABLE; - } else if (E_IS_TABLE (GET_PRIVATE (a11y)->widget)) { - accessible->role = ATK_ROLE_TABLE; - } - } - - if (item) - g_object_weak_ref (G_OBJECT (item), item_finalized, g_object_ref (a11y)); - - esm = item->selection; - - if (esm != NULL) { - eti_a11y_reset_focus_object (a11y, item, FALSE); - } - - return ATK_OBJECT (a11y); -} - -static gboolean -gal_a11y_e_table_item_ref_selection (GalA11yETableItem *a11y, - ESelectionModel *selection) -{ - GalA11yETableItemPrivate *priv; - - g_return_val_if_fail (a11y && selection, FALSE); - - priv = GET_PRIVATE (a11y); - priv->selection_change_id = g_signal_connect ( - selection, "selection_changed", - G_CALLBACK (eti_a11y_selection_changed_cb), a11y); - priv->cursor_change_id = g_signal_connect ( - selection, "cursor_changed", - G_CALLBACK (eti_a11y_cursor_changed_cb), a11y); - - priv->selection = selection; - g_object_ref (selection); - - return TRUE; -} - -static gboolean -gal_a11y_e_table_item_unref_selection (GalA11yETableItem *a11y) -{ - GalA11yETableItemPrivate *priv; - - g_return_val_if_fail (a11y, FALSE); - - priv = GET_PRIVATE (a11y); - - g_return_val_if_fail (priv->selection_change_id != 0, FALSE); - g_return_val_if_fail (priv->cursor_change_id != 0, FALSE); - - g_signal_handler_disconnect ( - priv->selection, - priv->selection_change_id); - g_signal_handler_disconnect ( - priv->selection, - priv->cursor_change_id); - priv->cursor_change_id = 0; - priv->selection_change_id = 0; - - g_object_unref (priv->selection); - priv->selection = NULL; - - return TRUE; -} - -/* callbacks */ - -static void -eti_a11y_selection_model_removed_cb (ETableItem *eti, - ESelectionModel *selection, - gpointer data) -{ - AtkObject *atk_obj; - GalA11yETableItem *a11y; - - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti)); - a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj); - - if (selection == GET_PRIVATE (a11y)->selection) - gal_a11y_e_table_item_unref_selection (a11y); -} - -static void -eti_a11y_selection_model_added_cb (ETableItem *eti, - ESelectionModel *selection, - gpointer data) -{ - AtkObject *atk_obj; - GalA11yETableItem *a11y; - - g_return_if_fail (E_IS_TABLE_ITEM (eti)); - g_return_if_fail (E_IS_SELECTION_MODEL (selection)); - - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti)); - a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj); - - if (GET_PRIVATE (a11y)->selection) - gal_a11y_e_table_item_unref_selection (a11y); - gal_a11y_e_table_item_ref_selection (a11y, selection); -} - -static void -eti_a11y_selection_changed_cb (ESelectionModel *selection, - GalA11yETableItem *a11y) -{ - GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return; - - g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y)); - - g_signal_emit_by_name (a11y, "selection_changed"); -} - -static void -eti_a11y_cursor_changed_cb (ESelectionModel *selection, - gint row, - gint col, - GalA11yETableItem *a11y) -{ - ETableItem *item; - GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); - - g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y)); - - if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) - return; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (a11y))); - - g_return_if_fail (item); - - if (row == -1 && col == -1) - return; - eti_a11y_reset_focus_object (a11y, item, TRUE); -} - -/* atk selection */ - -static void atk_selection_interface_init (AtkSelectionIface *iface) -{ - g_return_if_fail (iface != NULL); - iface->add_selection = selection_add_selection; - iface->clear_selection = selection_clear_selection; - iface->ref_selection = selection_ref_selection; - iface->get_selection_count = selection_get_selection_count; - iface->is_child_selected = selection_is_child_selected; -} - -static gboolean -selection_add_selection (AtkSelection *selection, - gint index) -{ - AtkTable *table; - gint row, col, cursor_row, cursor_col, model_row, model_col; - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (selection))); - if (!item) - return FALSE; - - table = ATK_TABLE (selection); - - row = atk_table_get_row_at_index (table, index); - col = atk_table_get_column_at_index (table, index); - - model_row = view_to_model_row (item, row); - model_col = view_to_model_col (item, col); - - cursor_row = e_selection_model_cursor_row (item->selection); - cursor_col = e_selection_model_cursor_col (item->selection); - - /* check whether is selected already */ - if (model_row == cursor_row && model_col == cursor_col) - return TRUE; - - if (model_row != cursor_row) { - /* we need to make the item get focus */ - e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (item), TRUE); - - /* FIXME, currently we only support single row selection */ - atk_selection_clear_selection (selection); - atk_table_add_row_selection (table, row); - } - - e_selection_model_change_cursor ( - item->selection, - model_row, - model_col); - e_selection_model_cursor_changed ( - item->selection, - model_row, - model_col); - e_selection_model_cursor_activated ( - item->selection, - model_row, - model_col); - return TRUE; -} - -static gboolean -selection_clear_selection (AtkSelection *selection) -{ - ETableItem *item; - - item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (selection))); - if (!item) - return FALSE; - - e_selection_model_clear (item->selection); - return TRUE; -} - -static AtkObject * -selection_ref_selection (AtkSelection *selection, - gint index) -{ - AtkTable *table; - gint row, col; - - table = ATK_TABLE (selection); - row = atk_table_get_row_at_index (table, index); - col = atk_table_get_column_at_index (table, index); - if (!atk_table_is_row_selected (table, row)) - return NULL; - - return eti_ref_at (table, row, col); -} - -static gint -selection_get_selection_count (AtkSelection *selection) -{ - AtkTable *table; - gint n_selected; - - table = ATK_TABLE (selection); - n_selected = atk_table_get_selected_rows (table, NULL); - if (n_selected > 0) - n_selected *= atk_table_get_n_columns (table); - return n_selected; -} - -static gboolean -selection_is_child_selected (AtkSelection *selection, - gint i) -{ - gint row; - - row = atk_table_get_row_at_index (ATK_TABLE (selection), i); - return atk_table_is_row_selected (ATK_TABLE (selection), row); -} - -void -gal_a11y_e_table_item_init (void) -{ - if (atk_get_root ()) - atk_registry_set_factory_type ( - atk_get_default_registry (), - E_TYPE_TABLE_ITEM, - gal_a11y_e_table_item_factory_get_type ()); -} - diff --git a/widgets/table/gal-a11y-e-table-item.h b/widgets/table/gal-a11y-e-table-item.h deleted file mode 100644 index b77c5c3e93..0000000000 --- a/widgets/table/gal-a11y-e-table-item.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_ITEM_H__ -#define __GAL_A11Y_E_TABLE_ITEM_H__ - -#include <table/e-table-item.h> -#include <atk/atkgobjectaccessible.h> - -#define GAL_A11Y_TYPE_E_TABLE_ITEM (gal_a11y_e_table_item_get_type ()) -#define GAL_A11Y_E_TABLE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM, GalA11yETableItem)) -#define GAL_A11Y_E_TABLE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM, GalA11yETableItemClass)) -#define GAL_A11Y_IS_E_TABLE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM)) -#define GAL_A11Y_IS_E_TABLE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM)) - -typedef struct _GalA11yETableItem GalA11yETableItem; -typedef struct _GalA11yETableItemClass GalA11yETableItemClass; -typedef struct _GalA11yETableItemPrivate GalA11yETableItemPrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yETableItemPrivate comes right after the parent class structure. - **/ -struct _GalA11yETableItem { - AtkGObjectAccessible parent; -}; - -struct _GalA11yETableItemClass { - AtkGObjectAccessibleClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_item_get_type (void); -AtkObject *gal_a11y_e_table_item_new (ETableItem *item); - -void gal_a11y_e_table_item_init (void); - -#endif /* __GAL_A11Y_E_TABLE_ITEM_H__ */ diff --git a/widgets/table/gal-a11y-e-table.c b/widgets/table/gal-a11y-e-table.c deleted file mode 100644 index ec0025c6b8..0000000000 --- a/widgets/table/gal-a11y-e-table.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "a11y/gal-a11y-util.h" -#include "table/e-table.h" -#include "table/e-table-click-to-add.h" -#include "table/e-table-group.h" -#include "table/e-table-group-container.h" -#include "table/e-table-group-leaf.h" - -#include "gal-a11y-e-table.h" -#include "gal-a11y-e-table-factory.h" -#include "gal-a11y-e-table-item.h" - -#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETableClass)) -static AtkObjectClass *parent_class; -static GType parent_type; -static gint priv_offset; -#define GET_PRIVATE(object) ((GalA11yETablePrivate *) (((gchar *) object) + priv_offset)) -#define PARENT_TYPE (parent_type) - -struct _GalA11yETablePrivate { - AtkObject *child_item; -}; - -/* Static functions */ -static ETableItem * -find_first_table_item (ETableGroup *group) -{ - GnomeCanvasGroup *cgroup; - GList *l; - - cgroup = GNOME_CANVAS_GROUP (group); - - for (l = cgroup->item_list; l; l = l->next) { - GnomeCanvasItem *i; - - i = GNOME_CANVAS_ITEM (l->data); - - if (E_IS_TABLE_GROUP (i)) - return find_first_table_item (E_TABLE_GROUP (i)); - else if (E_IS_TABLE_ITEM (i)) { - return E_TABLE_ITEM (i); - } - } - - return NULL; -} - -static AtkObject * -eti_get_accessible (ETableItem *eti, - AtkObject *parent) -{ - AtkObject *a11y = NULL; - - g_return_val_if_fail (eti, NULL); - - a11y = atk_gobject_accessible_for_object (G_OBJECT (eti)); - g_return_val_if_fail (a11y, NULL); - - return a11y; -} - -static gboolean -init_child_item (GalA11yETable *a11y) -{ - ETable *table; - - if (!a11y || !GTK_IS_ACCESSIBLE (a11y)) - return FALSE; - - table = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y))); - if (table && gtk_widget_get_mapped (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) { - ETableGroupContainer *etgc = (ETableGroupContainer *) table->group; - GList *list; - - for (list = etgc->children; list; list = g_list_next (list)) { - ETableGroupContainerChildNode *child_node = list->data; - ETableGroup *child = child_node->child; - ETableItem *eti = find_first_table_item (child); - - eti_get_accessible (eti, ATK_OBJECT (a11y)); - } - } - g_object_unref (a11y); - g_object_unref (table); - - return FALSE; -} - -static AtkObject * -et_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - GalA11yETable *a11y = GAL_A11Y_E_TABLE (component); - if (GET_PRIVATE (a11y)->child_item) - g_object_ref (GET_PRIVATE (a11y)->child_item); - return GET_PRIVATE (a11y)->child_item; -} - -static gint -et_get_n_children (AtkObject *accessible) -{ - GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible); - ETable * et; - gint n = 0; - - et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y))); - - if (et && et->group) { - if (E_IS_TABLE_GROUP_LEAF (et->group)) - n = 1; - else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) { - ETableGroupContainer *etgc = (ETableGroupContainer *) et->group; - n = g_list_length (etgc->children); - } - } - - if (et && et->use_click_to_add && et->click_to_add) { - n++; - } - return n; -} - -static AtkObject * -et_ref_child (AtkObject *accessible, - gint i) -{ - GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible); - ETable * et; - gint child_no; - - et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y))); - if (!et) - return NULL; - - child_no = et_get_n_children (accessible); - if (i == 0 || i < child_no - 1) { - if (E_IS_TABLE_GROUP_LEAF (et->group)) { - ETableItem *eti = find_first_table_item (et->group); - AtkObject *aeti = eti_get_accessible (eti, accessible); - if (aeti) - g_object_ref (aeti); - return aeti; - - } else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) { - ETableGroupContainer *etgc = (ETableGroupContainer *) et->group; - ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i); - if (child_node) { - ETableGroup *child = child_node->child; - ETableItem * eti = find_first_table_item (child); - AtkObject *aeti = eti_get_accessible (eti, accessible); - if (aeti) - g_object_ref (aeti); - return aeti; - } - } - } else if (i == child_no -1) { - ETableClickToAdd * etcta; - - if (et && et->use_click_to_add && et->click_to_add) { - etcta = E_TABLE_CLICK_TO_ADD (et->click_to_add); - accessible = atk_gobject_accessible_for_object (G_OBJECT (etcta)); - if (accessible) - g_object_ref (accessible); - return accessible; - } - } - - return NULL; -} - -static AtkLayer -et_get_layer (AtkComponent *component) -{ - return ATK_LAYER_WIDGET; -} - -static void -et_class_init (GalA11yETableClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - atk_object_class->get_n_children = et_get_n_children; - atk_object_class->ref_child = et_ref_child; -} - -static void -et_atk_component_iface_init (AtkComponentIface *iface) -{ - iface->ref_accessible_at_point = et_ref_accessible_at_point; - iface->get_layer = et_get_layer; -} - -static void -et_init (GalA11yETable *a11y) -{ - GalA11yETablePrivate *priv; - - priv = GET_PRIVATE (a11y); - - priv->child_item = NULL; -} - -/** - * gal_a11y_e_table_get_type: - * @void: - * - * Registers the &GalA11yETable class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETable class. - **/ -GType -gal_a11y_e_table_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - - GTypeInfo info = { - sizeof (GalA11yETableClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) et_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETable), - 0, - (GInstanceInitFunc) et_init, - NULL /* value_table */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) et_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET); - parent_type = atk_object_factory_get_accessible_type (factory); - - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yETable", &info, 0, - sizeof (GalA11yETablePrivate), &priv_offset); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); - } - - return type; -} - -AtkObject * -gal_a11y_e_table_new (GObject *widget) -{ - GalA11yETable *a11y; - ETable *table; - - table = E_TABLE (widget); - - a11y = g_object_new (gal_a11y_e_table_get_type (), NULL); - - gtk_accessible_set_widget (GTK_ACCESSIBLE (a11y), GTK_WIDGET (widget)); - - /* we need to init all the children for multiple table items */ - if (table && gtk_widget_get_mapped (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) { - /* Ref it here so that it is still valid in the idle function */ - /* It will be unrefed in the idle function */ - g_object_ref (a11y); - g_object_ref (widget); - - g_idle_add ((GSourceFunc) init_child_item, a11y); - } - - return ATK_OBJECT (a11y); -} - -void -gal_a11y_e_table_init (void) -{ - if (atk_get_root ()) - atk_registry_set_factory_type ( - atk_get_default_registry (), - E_TYPE_TABLE, - gal_a11y_e_table_factory_get_type ()); - -} - diff --git a/widgets/table/gal-a11y-e-table.h b/widgets/table/gal-a11y-e-table.h deleted file mode 100644 index f5dba40c7e..0000000000 --- a/widgets/table/gal-a11y-e-table.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TABLE_H__ -#define __GAL_A11Y_E_TABLE_H__ - -#include <gtk/gtk.h> -#include <atk/atkobject.h> -#include <atk/atkcomponent.h> - -#define GAL_A11Y_TYPE_E_TABLE (gal_a11y_e_table_get_type ()) -#define GAL_A11Y_E_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE, GalA11yETable)) -#define GAL_A11Y_E_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE, GalA11yETableClass)) -#define GAL_A11Y_IS_E_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE)) -#define GAL_A11Y_IS_E_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE)) - -typedef struct _GalA11yETable GalA11yETable; -typedef struct _GalA11yETableClass GalA11yETableClass; -typedef struct _GalA11yETablePrivate GalA11yETablePrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yETablePrivate comes right after the parent class structure. - **/ -struct _GalA11yETable { - GtkAccessible object; -}; - -struct _GalA11yETableClass { - GtkAccessibleClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_table_get_type (void); -AtkObject *gal_a11y_e_table_new (GObject *table); - -void gal_a11y_e_table_init (void); - -#endif /* __GAL_A11Y_E_TABLE_H__ */ diff --git a/widgets/table/gal-a11y-e-tree-factory.c b/widgets/table/gal-a11y-e-tree-factory.c deleted file mode 100644 index 00ce55c8c0..0000000000 --- a/widgets/table/gal-a11y-e-tree-factory.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gal-a11y-e-tree.h" -#include "gal-a11y-e-tree-factory.h" - -static AtkObjectFactoryClass *parent_class; -#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY) - -/* Static functions */ - -static GType -gal_a11y_e_tree_factory_get_accessible_type (void) -{ - return GAL_A11Y_TYPE_E_TREE; -} - -static AtkObject * -gal_a11y_e_tree_factory_create_accessible (GObject *obj) -{ - AtkObject *accessible; - - accessible = gal_a11y_e_tree_new (obj); - - return accessible; -} - -static void -gal_a11y_e_tree_factory_class_init (GalA11yETreeFactoryClass *class) -{ - AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - factory_class->create_accessible = gal_a11y_e_tree_factory_create_accessible; - factory_class->get_accessible_type = gal_a11y_e_tree_factory_get_accessible_type; -} - -static void -gal_a11y_e_tree_factory_init (GalA11yETreeFactory *factory) -{ -} - -/** - * gal_a11y_e_tree_factory_get_type: - * @void: - * - * Registers the &GalA11yETreeFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETreeFactory class. - **/ -GType -gal_a11y_e_tree_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETreeFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_tree_factory_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETreeFactory), - 0, - (GInstanceInitFunc) gal_a11y_e_tree_factory_init, - NULL /* value_tree */ - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yETreeFactory", &info, 0); - } - - return type; -} diff --git a/widgets/table/gal-a11y-e-tree-factory.h b/widgets/table/gal-a11y-e-tree-factory.h deleted file mode 100644 index a2e44445a0..0000000000 --- a/widgets/table/gal-a11y-e-tree-factory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TREE_FACTORY_H__ -#define __GAL_A11Y_E_TREE_FACTORY_H__ - -#include <atk/atkobjectfactory.h> - -#define GAL_A11Y_TYPE_E_TREE_FACTORY (gal_a11y_e_table_factory_get_type ()) -#define GAL_A11Y_E_TREE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TREE_FACTORY, GalA11yETreeFactory)) -#define GAL_A11Y_E_TREE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TREE_FACTORY, GalA11yETreeFactoryClass)) -#define GAL_A11Y_IS_E_TREE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TREE_FACTORY)) -#define GAL_A11Y_IS_E_TREE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TREE_FACTORY)) - -typedef struct _GalA11yETreeFactory GalA11yETreeFactory; -typedef struct _GalA11yETreeFactoryClass GalA11yETreeFactoryClass; - -struct _GalA11yETreeFactory { - AtkObject object; -}; - -struct _GalA11yETreeFactoryClass { - AtkObjectClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_tree_factory_get_type (void); - -#endif /* __GAL_A11Y_E_TREE_FACTORY_H__ */ diff --git a/widgets/table/gal-a11y-e-tree.c b/widgets/table/gal-a11y-e-tree.c deleted file mode 100644 index 26d2f24e7b..0000000000 --- a/widgets/table/gal-a11y-e-tree.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "a11y/gal-a11y-util.h" -#include "table/e-table-item.h" -#include "table/e-tree.h" - -#include "gal-a11y-e-table-item.h" -#include "gal-a11y-e-tree.h" -#include "gal-a11y-e-tree-factory.h" - -#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETreeClass)) -static AtkObjectClass *parent_class; -static GType parent_type; -static gint priv_offset; -#define GET_PRIVATE(object) ((GalA11yETreePrivate *) (((gchar *) object) + priv_offset)) -#define PARENT_TYPE (parent_type) - -struct _GalA11yETreePrivate { - AtkObject *child_item; -}; - -/* Static functions */ - -static void -init_child_item (GalA11yETree *a11y) -{ - GalA11yETreePrivate *priv = GET_PRIVATE (a11y); - ETree *tree; - ETableItem * eti; - - tree = E_TREE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y))); - g_return_if_fail (tree); - - eti = e_tree_get_item (tree); - if (priv->child_item == NULL) { - priv->child_item = atk_gobject_accessible_for_object (G_OBJECT (eti)); - } -} - -static AtkObject * -et_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - GalA11yETree *a11y = GAL_A11Y_E_TREE (component); - init_child_item (a11y); - return GET_PRIVATE (a11y)->child_item; -} - -static gint -et_get_n_children (AtkObject *accessible) -{ - return 1; -} - -static AtkObject * -et_ref_child (AtkObject *accessible, - gint i) -{ - GalA11yETree *a11y = GAL_A11Y_E_TREE (accessible); - if (i != 0) - return NULL; - init_child_item (a11y); - g_object_ref (GET_PRIVATE (a11y)->child_item); - return GET_PRIVATE (a11y)->child_item; -} - -static AtkLayer -et_get_layer (AtkComponent *component) -{ - return ATK_LAYER_WIDGET; -} - -static void -et_class_init (GalA11yETreeClass *class) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - atk_object_class->get_n_children = et_get_n_children; - atk_object_class->ref_child = et_ref_child; -} - -static void -et_atk_component_iface_init (AtkComponentIface *iface) -{ - iface->ref_accessible_at_point = et_ref_accessible_at_point; - iface->get_layer = et_get_layer; -} - -static void -et_init (GalA11yETree *a11y) -{ - GalA11yETreePrivate *priv; - - priv = GET_PRIVATE (a11y); - - priv->child_item = NULL; -} - -/** - * gal_a11y_e_tree_get_type: - * @void: - * - * Registers the &GalA11yETree class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETree class. - **/ -GType -gal_a11y_e_tree_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - - GTypeInfo info = { - sizeof (GalA11yETreeClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) et_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETree), - 0, - (GInstanceInitFunc) et_init, - NULL /* value_tree */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) et_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET); - parent_type = atk_object_factory_get_accessible_type (factory); - - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yETree", &info, 0, - sizeof (GalA11yETreePrivate), &priv_offset); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); - } - - return type; -} - -AtkObject * -gal_a11y_e_tree_new (GObject *widget) -{ - GalA11yETree *a11y; - - a11y = g_object_new (gal_a11y_e_tree_get_type (), NULL); - - gtk_accessible_set_widget (GTK_ACCESSIBLE (a11y), GTK_WIDGET (widget)); - - return ATK_OBJECT (a11y); -} - -void -gal_a11y_e_tree_init (void) -{ - if (atk_get_root ()) - atk_registry_set_factory_type ( - atk_get_default_registry (), - E_TYPE_TREE, - gal_a11y_e_tree_factory_get_type ()); -} - diff --git a/widgets/table/gal-a11y-e-tree.h b/widgets/table/gal-a11y-e-tree.h deleted file mode 100644 index 61799e1b93..0000000000 --- a/widgets/table/gal-a11y-e-tree.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Yuedong Du <yuedong.du@sun.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TREE_H__ -#define __GAL_A11Y_E_TREE_H__ - -#include <gtk/gtk.h> -#include <atk/atkobject.h> -#include <atk/atkcomponent.h> - -#define GAL_A11Y_TYPE_E_TREE (gal_a11y_e_tree_get_type ()) -#define GAL_A11Y_E_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TREE, GalA11yETree)) -#define GAL_A11Y_E_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TREE, GalA11yETreeClass)) -#define GAL_A11Y_IS_E_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TREE)) -#define GAL_A11Y_IS_E_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TREE)) - -typedef struct _GalA11yETree GalA11yETree; -typedef struct _GalA11yETreeClass GalA11yETreeClass; -typedef struct _GalA11yETreePrivate GalA11yETreePrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yETablePrivate comes right after the parent class structure. - **/ -struct _GalA11yETree { - GtkAccessible object; -}; - -struct _GalA11yETreeClass { - GtkAccessibleClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_tree_get_type (void); -AtkObject *gal_a11y_e_tree_new (GObject *tree); - -void gal_a11y_e_tree_init (void); - -#endif /* __GAL_A11Y_E_TREE_H__ */ diff --git a/widgets/table/sample.table b/widgets/table/sample.table deleted file mode 100644 index e1909a2bf7..0000000000 --- a/widgets/table/sample.table +++ /dev/null @@ -1,45 +0,0 @@ -Col1 Col2 Address Title Dorks -c1.a c2.a a.a tit-1 DorkA -c1.b c2.b a.b tit-2 DDork -c1.c c2.c a.c tit-1 DorkB -c1.d c2.d a.d tit-2 ADork -c1.e c2.e a.e tit-1 DorkC -c1.f c2.f a.f tit-2 UDork -c1.g c2.g a.g tit-3 Dork--- -j k k tit-1 DorkA -aaa1 bbb ccc ddd eee -aaa2 bbb ccc ddd eee -aaa3 bbb ccc ddd eee -aaa4 bbb ccc ddd eee -aaa5 bbb ccc ddd eee -aaa6 bbb ccc ddd eee -aaa7 bbb ccc ddd eee -aaa8 bbb ccc ddd eee -aaa9 bbb ccc ddd eee -aaa10 bbb ccc ddd eee -aaa11 bbb ccc ddd eee -aaa12 bbb ccc ddd eee -aaa13 bbb ccc ddd eee -aaa14 bbb ccc ddd eee -aaa15 bbb ccc ddd eee -aaa16 bbb ccc ddd eee -aaa17 bbb ccc ddd eee -aaa18 bbb ccc ddd eee -aaa19 bbb ccc ddd eee -aaa20 bbb ccc ddd eee -aaa21 bbb ccc ddd eee -aaa22 bbb ccc ddd eee -aaa23 bbb ccc ddd eee -aaa24 bbb ccc ddd eee -aaa25 bbb ccc ddd eee -aaa26 bbb ccc ddd eee -aaa27 bbb ccc ddd eee -aaa28 bbb ccc ddd eee -aaa29 bbb ccc ddd eee -aaa30 bbb ccc ddd eee -aaa31 bbb ccc ddd eee -aaa32 bbb ccc ddd eee -aaa33 bbb ccc ddd eee -aaa34 bbb ccc ddd eee -aaa35 bbb ccc ddd eee -aaa36 bbb ccc ddd eee diff --git a/widgets/table/spec.xml b/widgets/table/spec.xml deleted file mode 100644 index a8e524484c..0000000000 --- a/widgets/table/spec.xml +++ /dev/null @@ -1,21 +0,0 @@ -<ETableSpecification no-headers="false" click-to-add="false" - draw-grid="true" cursor-mode="simple" - _click-to-add-message=""> - <ETableColumn model_col="0" _title="Email" expansion="1.0" minimum_width="20" resizable="true" cell="cell_left_just" compare="string"/> - <ETableColumn model_col="1" _title="Full Name" expansion="1.0" minimum_width="20" resizable="true" cell="cell_left_just" compare="string"/> - <ETableColumn model_col="2" _title="Address" expansion="1.0" minimum_width="20" resizable="true" cell="cell_left_just" compare="string"/> - <ETableColumn model_col="3" _title="Phone" expansion="1.0" minimum_width="20" resizable="true" cell="cell_left_just" compare="string"/> - <ETableState> - <column source="0"/> - <column source="3"/> - <column source="1"/> - <column source="2"/> - <grouping> - <group column="2" ascending="true"> - <leaf column="1" ascending="true"/> - </group> - </grouping> - <!-- Column that's been added by hand. Not implemented yet. - <ETableColumn model_col="custom-string" _title="Custom" expansion="1.0" minimum_widgth="20" resizable="true" cell="string" compare="string"/> --> - </ETableState> -</ETableSpecification> diff --git a/widgets/table/tree-expanded.xpm b/widgets/table/tree-expanded.xpm deleted file mode 100644 index 94d162d40b..0000000000 --- a/widgets/table/tree-expanded.xpm +++ /dev/null @@ -1,23 +0,0 @@ -/* XPM */ -static const gchar *tree_expanded_xpm[] = { -"16 16 4 1", -" c None", -". c #FFFFFF", -"* c #000000", -"+ c #666666", -" ", -" ", -" ", -" ", -" +++++++++ ", -" +.......+ ", -" +.......+ ", -" +.......+ ", -" +.*****.+ ", -" +.......+ ", -" +.......+ ", -" +.......+ ", -" +++++++++ ", -" ", -" ", -" "}; diff --git a/widgets/table/tree-unexpanded.xpm b/widgets/table/tree-unexpanded.xpm deleted file mode 100644 index d20ec5aa33..0000000000 --- a/widgets/table/tree-unexpanded.xpm +++ /dev/null @@ -1,23 +0,0 @@ -/* XPM */ -static const gchar *tree_unexpanded_xpm[] = { -"16 16 4 1", -" c None", -". c #FFFFFF", -"* c #000000", -"+ c #666666", -" ", -" ", -" ", -" ", -" +++++++++ ", -" +.......+ ", -" +...*...+ ", -" +...*...+ ", -" +.*****.+ ", -" +...*...+ ", -" +...*...+ ", -" +.......+ ", -" +++++++++ ", -" ", -" ", -" "}; diff --git a/widgets/text/Makefile.am b/widgets/text/Makefile.am deleted file mode 100644 index 9f8e852dd0..0000000000 --- a/widgets/text/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -privsolib_LTLIBRARIES = libetext.la - -libetext_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - -DG_LOG_DOMAIN=\"e-text\" - -libetext_la_SOURCES = \ - e-text-model-repos.c \ - e-text-model.c \ - e-text.c \ - e-reflow.c \ - e-reflow-model.c \ - gal-a11y-e-text-factory.c \ - gal-a11y-e-text.c - -libetextincludedir = $(privincludedir)/text - -libetextinclude_HEADERS = \ - e-text-model-repos.h \ - e-text-model.h \ - e-text.h \ - e-reflow.h \ - e-reflow-model.h \ - gal-a11y-e-text-factory.h \ - gal-a11y-e-text.h - -libetext_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libetext_la_LIBADD = \ - $(top_builddir)/a11y/libevolution-a11y.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/libgnomecanvas/libgnomecanvas.la \ - $(top_builddir)/libemail-utils/libemail-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(REGEX_LIBS) \ - $(MATH_LIB) - --include $(top_srcdir)/git.mk diff --git a/widgets/text/e-reflow-model.c b/widgets/text/e-reflow-model.c deleted file mode 100644 index 1f7aa5e105..0000000000 --- a/widgets/text/e-reflow-model.c +++ /dev/null @@ -1,411 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-util/e-util.h" - -#include "e-reflow-model.h" - -G_DEFINE_TYPE (EReflowModel, e_reflow_model, G_TYPE_OBJECT) - -#define d(x) - -d (static gint depth = 0;) - -enum { - MODEL_CHANGED, - COMPARISON_CHANGED, - MODEL_ITEMS_INSERTED, - MODEL_ITEM_CHANGED, - MODEL_ITEM_REMOVED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -/** - * e_reflow_model_set_width: - * @e_reflow_model: The e-reflow-model to operate on - * @width: The new value for the width of each item. - */ -void -e_reflow_model_set_width (EReflowModel *e_reflow_model, - gint width) -{ - EReflowModelClass *class; - - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_if_fail (class->set_width != NULL); - - class->set_width (e_reflow_model, width); -} - -/** - * e_reflow_model_count: - * @e_reflow_model: The e-reflow-model to operate on - * - * Returns: the number of items in the reflow model. - */ -gint -e_reflow_model_count (EReflowModel *e_reflow_model) -{ - EReflowModelClass *class; - - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_val_if_fail (class->count != NULL, 0); - - return class->count (e_reflow_model); -} - -/** - * e_reflow_model_height: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item number to get the height of. - * @parent: The parent GnomeCanvasItem. - * - * Returns: the height of the nth item. - */ -gint -e_reflow_model_height (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasGroup *parent) -{ - EReflowModelClass *class; - - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_val_if_fail (class->height != NULL, 0); - - return class->height (e_reflow_model, n, parent); -} - -/** - * e_reflow_model_incarnate: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item to create. - * @parent: The parent GnomeCanvasItem to create a child of. - * - * Create a GnomeCanvasItem to represent the nth piece of data. - * - * Returns: the new GnomeCanvasItem. - */ -GnomeCanvasItem * -e_reflow_model_incarnate (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasGroup *parent) -{ - EReflowModelClass *class; - - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), NULL); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_val_if_fail (class->incarnate != NULL, NULL); - - return class->incarnate (e_reflow_model, n, parent); -} - -/** - * e_reflow_model_create_cmp_cache: - * @e_reflow_model: The e-reflow-model to operate on - * - * Creates a compare cache for quicker sorting. The sorting function - * may not depend on the cache, but it should benefit from it if available. - * - * Returns: Newly created GHashTable with cached compare values. This will be - * automatically freed with g_hash_table_destroy() when no longer needed. - **/ -GHashTable * -e_reflow_model_create_cmp_cache (EReflowModel *e_reflow_model) -{ - EReflowModelClass *class; - - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), NULL); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - - if (class->create_cmp_cache == NULL) - return NULL; - - return class->create_cmp_cache (e_reflow_model); -} - -/** - * e_reflow_model_compare: - * @e_reflow_model: The e-reflow-model to operate on - * @n1: The first item to compare - * @n2: The second item to compare - * @cmp_cache: #GHashTable of cached compare values, created by - * e_reflow_model_create_cmp_cache(). This can be NULL, when - * caching is not available, even when @e_reflow_model defines - * the create_cmp_cache function. - * - * Compares item n1 and item n2 to see which should come first. - * - * Returns: strcmp like semantics for the comparison value. - */ -gint -e_reflow_model_compare (EReflowModel *e_reflow_model, - gint n1, - gint n2, - GHashTable *cmp_cache) -{ - EReflowModelClass *class; - - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_val_if_fail (class->compare != NULL, 0); - - return class->compare (e_reflow_model, n1, n2, cmp_cache); -} - -/** - * e_reflow_model_reincarnate: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item to create. - * @item: The item to reuse. - * - * Update item to represent the nth piece of data. - */ -void -e_reflow_model_reincarnate (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasItem *item) -{ - EReflowModelClass *class; - - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - class = E_REFLOW_MODEL_GET_CLASS (e_reflow_model); - g_return_if_fail (class->reincarnate != NULL); - - class->reincarnate (e_reflow_model, n, item); -} - -static void -e_reflow_model_class_init (EReflowModelClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - class->set_width = NULL; - class->count = NULL; - class->height = NULL; - class->incarnate = NULL; - class->reincarnate = NULL; - - class->model_changed = NULL; - class->comparison_changed = NULL; - class->model_items_inserted = NULL; - class->model_item_removed = NULL; - class->model_item_changed = NULL; - - signals[MODEL_CHANGED] = g_signal_new ( - "model_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[COMPARISON_CHANGED] = g_signal_new ( - "comparison_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, comparison_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[MODEL_ITEMS_INSERTED] = g_signal_new ( - "model_items_inserted", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_items_inserted), - NULL, NULL, - e_marshal_NONE__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - - signals[MODEL_ITEM_CHANGED] = g_signal_new ( - "model_item_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_item_changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - signals[MODEL_ITEM_REMOVED] = g_signal_new ( - "model_item_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_item_removed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); -} - -static void -e_reflow_model_init (EReflowModel *e_reflow_model) -{ -} - -#if d(!)0 -static void -print_tabs (void) -{ - gint i; - for (i = 0; i < depth; i++) - g_print ("\t"); -} -#endif - -/** - * e_reflow_model_changed: - * @e_reflow_model: the reflow model to notify of the change - * - * Use this function to notify any views of this reflow model that - * the contents of the reflow model have changed. This will emit - * the signal "model_changed" on the @e_reflow_model object. - * - * It is preferable to use the e_reflow_model_item_changed() signal to - * notify of smaller changes than to invalidate the entire model, as - * the views might have ways of caching the information they render - * from the model. - */ -void -e_reflow_model_changed (EReflowModel *e_reflow_model) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d (print_tabs ()); - d (g_print ("Emitting model_changed on model 0x%p.\n", e_reflow_model)); - d (depth++); - g_signal_emit (e_reflow_model, signals[MODEL_CHANGED], 0); - d (depth--); -} - -/** - * e_reflow_model_comparison_changed: - * @e_reflow_model: the reflow model to notify of the change - * - * Use this function to notify any views of this reflow model that the - * sorting has changed. The actual contents of the items hasn't, so - * there's no need to re-query the model for the heights of the - * individual items. - */ -void -e_reflow_model_comparison_changed (EReflowModel *e_reflow_model) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d (print_tabs ()); - d (g_print ( - "Emitting comparison_changed on model 0x%p.\n", - e_reflow_model)); - d (depth++); - g_signal_emit (e_reflow_model, signals[COMPARISON_CHANGED], 0); - d (depth--); -} - -/** - * e_reflow_model_items_inserted: - * @e_reflow_model: The model changed. - * @position: The position the items were insert in. - * @count: The number of items inserted. - * - * Use this function to notify any views of the reflow model that a number - * of items have been inserted. - **/ -void -e_reflow_model_items_inserted (EReflowModel *e_reflow_model, - gint position, - gint count) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d (print_tabs ()); - d (depth++); - g_signal_emit ( - e_reflow_model, - signals[MODEL_ITEMS_INSERTED], 0, - position, count); - d (depth--); -} - -/** - * e_reflow_model_item_removed: - * @e_reflow_model: The model changed. - * @n: The position from which the items were removed. - * - * Use this function to notify any views of the reflow model that an - * item has been removed. - **/ -void -e_reflow_model_item_removed (EReflowModel *e_reflow_model, - gint n) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d (print_tabs ()); - d (depth++); - g_signal_emit (e_reflow_model, signals[MODEL_ITEM_REMOVED], 0, n); - d (depth--); -} - -/** - * e_reflow_model_item_changed: - * @e_reflow_model: the reflow model to notify of the change - * @item: the item that was changed in the model. - * - * Use this function to notify any views of the reflow model that the - * contents of item @item have changed in model such that the height - * has changed or the item needs to be reincarnated. This function - * will emit the "model_item_changed" signal on the @e_reflow_model - * object - */ -void -e_reflow_model_item_changed (EReflowModel *e_reflow_model, - gint n) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d (print_tabs ()); - d (g_print ("Emitting item_changed on model 0x%p, n=%d.\n", e_reflow_model, n)); - d (depth++); - g_signal_emit (e_reflow_model, signals[MODEL_ITEM_CHANGED], 0, n); - d (depth--); -} diff --git a/widgets/text/e-reflow-model.h b/widgets/text/e-reflow-model.h deleted file mode 100644 index 33cad68da0..0000000000 --- a/widgets/text/e-reflow-model.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_REFLOW_MODEL_H_ -#define _E_REFLOW_MODEL_H_ - -#include <libgnomecanvas/libgnomecanvas.h> - -/* Standard GObject macros */ -#define E_TYPE_REFLOW_MODEL \ - (e_reflow_model_get_type ()) -#define E_REFLOW_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_REFLOW_MODEL, EReflowModel)) -#define E_REFLOW_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_REFLOW_MODEL, EReflowModelClass)) -#define E_IS_REFLOW_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_REFLOW_MODEL)) -#define E_IS_REFLOW_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_REFLOW_MODEL)) -#define E_REFLOW_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_REFLOW_MODEL, EReflowModelClass)) - -G_BEGIN_DECLS - -typedef struct _EReflowModel EReflowModel; -typedef struct _EReflowModelClass EReflowModelClass; - -struct _EReflowModel { - GObject parent; -}; - -struct _EReflowModelClass { - GObjectClass parent_class; - - /* - * Virtual methods - */ - void (*set_width) (EReflowModel *etm, gint width); - - gint (*count) (EReflowModel *etm); - gint (*height) (EReflowModel *etm, gint n, GnomeCanvasGroup *parent); - GnomeCanvasItem *(*incarnate) (EReflowModel *etm, gint n, GnomeCanvasGroup *parent); - GHashTable * (*create_cmp_cache) (EReflowModel *etm); - gint (*compare) (EReflowModel *etm, gint n1, gint n2, GHashTable *cmp_cache); - void (*reincarnate) (EReflowModel *etm, gint n, GnomeCanvasItem *item); - - /* - * Signals - */ - - /* - * These all come after the change has been made. - * Major structural changes: model_changed - * Changes to the sorting of elements: comparison_changed - * Changes only in an item: item_changed - */ - void (*model_changed) (EReflowModel *etm); - void (*comparison_changed) (EReflowModel *etm); - void (*model_items_inserted) (EReflowModel *etm, gint position, gint count); - void (*model_item_removed) (EReflowModel *etm, gint position); - void (*model_item_changed) (EReflowModel *etm, gint n); -}; - -GType e_reflow_model_get_type (void); - -/**/ -void e_reflow_model_set_width (EReflowModel *e_reflow_model, - gint width); -gint e_reflow_model_count (EReflowModel *e_reflow_model); -gint e_reflow_model_height (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasGroup *parent); -GnomeCanvasItem *e_reflow_model_incarnate (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasGroup *parent); -GHashTable * e_reflow_model_create_cmp_cache (EReflowModel *e_reflow_model); -gint e_reflow_model_compare (EReflowModel *e_reflow_model, - gint n1, - gint n2, - GHashTable *cmp_cache); -void e_reflow_model_reincarnate (EReflowModel *e_reflow_model, - gint n, - GnomeCanvasItem *item); - -/* - * Routines for emitting signals on the e_reflow - */ -void e_reflow_model_changed (EReflowModel *e_reflow_model); -void e_reflow_model_comparison_changed (EReflowModel *e_reflow_model); -void e_reflow_model_items_inserted (EReflowModel *e_reflow_model, - gint position, - gint count); -void e_reflow_model_item_removed (EReflowModel *e_reflow_model, - gint n); -void e_reflow_model_item_changed (EReflowModel *e_reflow_model, - gint n); - -G_END_DECLS - -#endif /* _E_REFLOW_MODEL_H_ */ diff --git a/widgets/text/e-reflow.c b/widgets/text/e-reflow.c deleted file mode 100644 index faad196c83..0000000000 --- a/widgets/text/e-reflow.c +++ /dev/null @@ -1,1732 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "text/e-text.h" -#include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-unicode.h" - -#include "misc/e-canvas.h" -#include "misc/e-canvas-utils.h" -#include "e-reflow.h" -#include "misc/e-selection-model-simple.h" - -static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event); -static void e_reflow_realize (GnomeCanvasItem *item); -static void e_reflow_unrealize (GnomeCanvasItem *item); -static void e_reflow_draw (GnomeCanvasItem *item, cairo_t *cr, - gint x, gint y, gint width, gint height); -static void e_reflow_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags); -static GnomeCanvasItem *e_reflow_point (GnomeCanvasItem *item, gdouble x, gdouble y, gint cx, gint cy); -static void e_reflow_reflow (GnomeCanvasItem *item, gint flags); -static void set_empty (EReflow *reflow); - -static void e_reflow_resize_children (GnomeCanvasItem *item); - -#define E_REFLOW_DIVIDER_WIDTH 2 -#define E_REFLOW_BORDER_WIDTH 7 -#define E_REFLOW_FULL_GUTTER (E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH * 2) - -G_DEFINE_TYPE (EReflow, e_reflow, GNOME_TYPE_CANVAS_GROUP) - -enum { - PROP_0, - PROP_MINIMUM_WIDTH, - PROP_WIDTH, - PROP_HEIGHT, - PROP_EMPTY_MESSAGE, - PROP_MODEL, - PROP_COLUMN_WIDTH -}; - -enum { - SELECTION_EVENT, - COLUMN_WIDTH_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0, }; - -static GHashTable * -er_create_cmp_cache (gpointer user_data) -{ - EReflow *reflow = user_data; - return e_reflow_model_create_cmp_cache (reflow->model); -} - -static gint -er_compare (gint i1, - gint i2, - GHashTable *cmp_cache, - gpointer user_data) -{ - EReflow *reflow = user_data; - return e_reflow_model_compare (reflow->model, i1, i2, cmp_cache); -} - -static gint -e_reflow_pick_line (EReflow *reflow, - gdouble x) -{ - x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - x /= reflow->column_width + E_REFLOW_FULL_GUTTER; - return x; -} - -static gint -er_find_item (EReflow *reflow, - GnomeCanvasItem *item) -{ - gint i; - for (i = 0; i < reflow->count; i++) { - if (reflow->items[i] == item) - return i; - } - return -1; -} - -static void -e_reflow_resize_children (GnomeCanvasItem *item) -{ - EReflow *reflow; - gint i; - gint count; - - reflow = E_REFLOW (item); - - count = reflow->count; - for (i = 0; i < count; i++) { - if (reflow->items[i]) - gnome_canvas_item_set ( - reflow->items[i], - "width", (gdouble) reflow->column_width, - NULL); - } -} - -static inline void -e_reflow_update_selection_row (EReflow *reflow, - gint row) -{ - if (reflow->items[row]) { - g_object_set ( - reflow->items[row], - "selected", e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row), - NULL); - } else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row)) { - reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); - g_object_set ( - reflow->items[row], - "selected", e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row), - "width", (gdouble) reflow->column_width, - NULL); - } -} - -static void -e_reflow_update_selection (EReflow *reflow) -{ - gint i; - gint count; - - count = reflow->count; - for (i = 0; i < count; i++) { - e_reflow_update_selection_row (reflow, i); - } -} - -static void -selection_changed (ESelectionModel *selection, - EReflow *reflow) -{ - e_reflow_update_selection (reflow); -} - -static void -selection_row_changed (ESelectionModel *selection, - gint row, - EReflow *reflow) -{ - e_reflow_update_selection_row (reflow, row); -} - -static gboolean -do_adjustment (gpointer user_data) -{ - gint row; - GtkLayout *layout; - GtkAdjustment *adjustment; - gdouble page_size; - gdouble value, min_value, max_value; - EReflow *reflow = user_data; - - row = reflow->cursor_row; - if (row == -1) - return FALSE; - - layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - - value = gtk_adjustment_get_value (adjustment); - page_size = gtk_adjustment_get_page_size (adjustment); - - if ((!reflow->items) || (!reflow->items[row])) - return TRUE; - min_value = reflow->items[row]->x2 - page_size; - max_value = reflow->items[row]->x1; - - if (value < min_value) - value = min_value; - - if (value > max_value) - value = max_value; - - if (value != gtk_adjustment_get_value (adjustment)) - gtk_adjustment_set_value (adjustment, value); - - reflow->do_adjustment_idle_id = 0; - - return FALSE; -} - -static void -cursor_changed (ESelectionModel *selection, - gint row, - gint col, - EReflow *reflow) -{ - gint count = reflow->count; - gint old_cursor = reflow->cursor_row; - - if (old_cursor < count && old_cursor >= 0) { - if (reflow->items[old_cursor]) { - g_object_set ( - reflow->items[old_cursor], - "has_cursor", FALSE, - NULL); - } - } - - reflow->cursor_row = row; - - if (row < count && row >= 0) { - if (reflow->items[row]) { - g_object_set ( - reflow->items[row], - "has_cursor", TRUE, - NULL); - } else { - reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); - g_object_set ( - reflow->items[row], - "has_cursor", TRUE, - "width", (gdouble) reflow->column_width, - NULL); - } - } - - if (reflow->do_adjustment_idle_id == 0) - reflow->do_adjustment_idle_id = g_idle_add (do_adjustment, reflow); - -} - -static void -incarnate (EReflow *reflow) -{ - gint column_width; - gint first_column; - gint last_column; - gint first_cell; - gint last_cell; - gint i; - GtkLayout *layout; - GtkAdjustment *adjustment; - gdouble value; - gdouble page_size; - - layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - - value = gtk_adjustment_get_value (adjustment); - page_size = gtk_adjustment_get_page_size (adjustment); - - column_width = reflow->column_width; - - first_column = value - 1 + E_REFLOW_BORDER_WIDTH; - first_column /= column_width + E_REFLOW_FULL_GUTTER; - - last_column = value + page_size + 1 - E_REFLOW_BORDER_WIDTH - E_REFLOW_DIVIDER_WIDTH; - last_column /= column_width + E_REFLOW_FULL_GUTTER; - last_column++; - - if (first_column >= 0 && first_column < reflow->column_count) - first_cell = reflow->columns[first_column]; - else - first_cell = 0; - - if (last_column >= 0 && last_column < reflow->column_count) - last_cell = reflow->columns[last_column]; - else - last_cell = reflow->count; - - for (i = first_cell; i < last_cell; i++) { - gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (reflow->items[unsorted] == NULL) { - if (reflow->model) { - reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); - g_object_set ( - reflow->items[unsorted], - "selected", e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), unsorted), - "width", (gdouble) reflow->column_width, - NULL); - } - } - } - reflow->incarnate_idle_id = 0; -} - -static gboolean -invoke_incarnate (gpointer user_data) -{ - EReflow *reflow = user_data; - incarnate (reflow); - return FALSE; -} - -static void -queue_incarnate (EReflow *reflow) -{ - if (reflow->incarnate_idle_id == 0) - reflow->incarnate_idle_id = - g_idle_add_full (25, invoke_incarnate, reflow, NULL); -} - -static void -reflow_columns (EReflow *reflow) -{ - GSList *list; - gint count; - gint start; - gint i; - gint column_count, column_start; - gdouble running_height; - - if (reflow->reflow_from_column <= 1) { - start = 0; - column_count = 1; - column_start = 0; - } - else { - /* we start one column before the earliest new entry, - * so we can handle the case where the new entry is - * inserted at the start of the column */ - column_start = reflow->reflow_from_column - 1; - start = reflow->columns[column_start]; - column_count = column_start + 1; - } - - list = NULL; - - running_height = E_REFLOW_BORDER_WIDTH; - - count = reflow->count - start; - for (i = start; i < count; i++) { - gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (i != 0 && running_height + reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH > reflow->height) { - list = g_slist_prepend (list, GINT_TO_POINTER (i)); - column_count++; - running_height = E_REFLOW_BORDER_WIDTH * 2 + reflow->heights[unsorted]; - } else - running_height += reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH; - } - - reflow->column_count = column_count; - reflow->columns = g_renew (int, reflow->columns, column_count); - column_count--; - - for (; list && column_count > column_start; column_count--) { - GSList *to_free; - reflow->columns[column_count] = GPOINTER_TO_INT (list->data); - to_free = list; - list = list->next; - g_slist_free_1 (to_free); - } - reflow->columns[column_start] = start; - - queue_incarnate (reflow); - - reflow->need_reflow_columns = FALSE; - reflow->reflow_from_column = -1; -} - -static void -item_changed (EReflowModel *model, - gint i, - EReflow *reflow) -{ - if (i < 0 || i >= reflow->count) - return; - - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - if (reflow->items[i] != NULL) - e_reflow_model_reincarnate (model, i, reflow->items[i]); - e_sorter_array_clean (reflow->sorter); - reflow->reflow_from_column = -1; - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (reflow)); -} - -static void -item_removed (EReflowModel *model, - gint i, - EReflow *reflow) -{ - gint c; - gint sorted; - - if (i < 0 || i >= reflow->count) - return; - - sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); - for (c = reflow->column_count - 1; c >= 0; c--) { - gint start_of_column = reflow->columns[c]; - - if (start_of_column <= sorted) { - if (reflow->reflow_from_column == -1 - || reflow->reflow_from_column > c) { - reflow->reflow_from_column = c; - } - break; - } - } - - if (reflow->items[i]) - g_object_run_dispose (G_OBJECT (reflow->items[i])); - - memmove (reflow->heights + i, reflow->heights + i + 1, (reflow->count - i - 1) * sizeof (gint)); - memmove (reflow->items + i, reflow->items + i + 1, (reflow->count - i - 1) * sizeof (GnomeCanvasItem *)); - - reflow->count--; - - reflow->heights[reflow->count] = 0; - reflow->items[reflow->count] = NULL; - - reflow->need_reflow_columns = TRUE; - set_empty (reflow); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (reflow)); - - e_sorter_array_set_count (reflow->sorter, reflow->count); - - e_selection_model_simple_delete_rows (E_SELECTION_MODEL_SIMPLE (reflow->selection), i, 1); -} - -static void -items_inserted (EReflowModel *model, - gint position, - gint count, - EReflow *reflow) -{ - gint i, oldcount; - - if (position < 0 || position > reflow->count) - return; - - oldcount = reflow->count; - - reflow->count += count; - - if (reflow->count > reflow->allocated_count) { - while (reflow->count > reflow->allocated_count) - reflow->allocated_count += 256; - reflow->heights = g_renew (int, reflow->heights, reflow->allocated_count); - reflow->items = g_renew (GnomeCanvasItem *, reflow->items, reflow->allocated_count); - } - memmove (reflow->heights + position + count, reflow->heights + position, (reflow->count - position - count) * sizeof (gint)); - memmove (reflow->items + position + count, reflow->items + position, (reflow->count - position - count) * sizeof (GnomeCanvasItem *)); - for (i = position; i < position + count; i++) { - reflow->items[i] = NULL; - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - } - - e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), reflow->count); - if (position == oldcount) - e_sorter_array_append (reflow->sorter, count); - else - e_sorter_array_set_count (reflow->sorter, reflow->count); - - for (i = position; i < position + count; i++) { - gint sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); - gint c; - - for (c = reflow->column_count - 1; c >= 0; c--) { - gint start_of_column = reflow->columns[c]; - - if (start_of_column <= sorted) { - if (reflow->reflow_from_column == -1 - || reflow->reflow_from_column > c) { - reflow->reflow_from_column = c; - } - break; - } - } - } - - reflow->need_reflow_columns = TRUE; - set_empty (reflow); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (reflow)); -} - -static void -model_changed (EReflowModel *model, - EReflow *reflow) -{ - gint i; - gint count; - gint oldcount; - - count = reflow->count; - oldcount = count; - - for (i = 0; i < count; i++) { - if (reflow->items[i]) - g_object_run_dispose (G_OBJECT (reflow->items[i])); - } - g_free (reflow->items); - g_free (reflow->heights); - reflow->count = e_reflow_model_count (model); - reflow->allocated_count = reflow->count; - reflow->items = g_new (GnomeCanvasItem *, reflow->count); - reflow->heights = g_new (int, reflow->count); - - count = reflow->count; - for (i = 0; i < count; i++) { - reflow->items[i] = NULL; - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - } - - e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), count); - e_sorter_array_set_count (reflow->sorter, reflow->count); - - reflow->need_reflow_columns = TRUE; - if (oldcount > reflow->count) - reflow_columns (reflow); - set_empty (reflow); - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (reflow)); -} - -static void -comparison_changed (EReflowModel *model, - EReflow *reflow) -{ - e_sorter_array_clean (reflow->sorter); - reflow->reflow_from_column = -1; - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (reflow)); -} - -static void -set_empty (EReflow *reflow) -{ - if (reflow->count == 0) { - if (reflow->empty_text) { - if (reflow->empty_message) { - gnome_canvas_item_set ( - reflow->empty_text, - "width", reflow->minimum_width, - "text", reflow->empty_message, - NULL); - e_canvas_item_move_absolute ( - reflow->empty_text, - reflow->minimum_width / 2, - 0); - } else { - g_object_run_dispose (G_OBJECT (reflow->empty_text)); - reflow->empty_text = NULL; - } - } else { - if (reflow->empty_message) { - reflow->empty_text = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (reflow), - e_text_get_type (), - "width", reflow->minimum_width, - "clip", TRUE, - "use_ellipsis", TRUE, - "justification", GTK_JUSTIFY_CENTER, - "text", reflow->empty_message, - NULL); - e_canvas_item_move_absolute ( - reflow->empty_text, - reflow->minimum_width / 2, - 0); - } - } - } else { - if (reflow->empty_text) { - g_object_run_dispose (G_OBJECT (reflow->empty_text)); - reflow->empty_text = NULL; - } - } -} - -static void -disconnect_model (EReflow *reflow) -{ - if (reflow->model == NULL) - return; - - g_signal_handler_disconnect ( - reflow->model, - reflow->model_changed_id); - g_signal_handler_disconnect ( - reflow->model, - reflow->comparison_changed_id); - g_signal_handler_disconnect ( - reflow->model, - reflow->model_items_inserted_id); - g_signal_handler_disconnect ( - reflow->model, - reflow->model_item_removed_id); - g_signal_handler_disconnect ( - reflow->model, - reflow->model_item_changed_id); - g_object_unref (reflow->model); - - reflow->model_changed_id = 0; - reflow->comparison_changed_id = 0; - reflow->model_items_inserted_id = 0; - reflow->model_item_removed_id = 0; - reflow->model_item_changed_id = 0; - reflow->model = NULL; -} - -static void -disconnect_selection (EReflow *reflow) -{ - if (reflow->selection == NULL) - return; - - g_signal_handler_disconnect ( - reflow->selection, - reflow->selection_changed_id); - g_signal_handler_disconnect ( - reflow->selection, - reflow->selection_row_changed_id); - g_signal_handler_disconnect ( - reflow->selection, - reflow->cursor_changed_id); - g_object_unref (reflow->selection); - - reflow->selection_changed_id = 0; - reflow->selection_row_changed_id = 0; - reflow->cursor_changed_id = 0; - reflow->selection = NULL; -} - -static void -connect_model (EReflow *reflow, - EReflowModel *model) -{ - if (reflow->model != NULL) - disconnect_model (reflow); - - if (model == NULL) - return; - - reflow->model = g_object_ref (model); - - reflow->model_changed_id = g_signal_connect ( - reflow->model, "model_changed", - G_CALLBACK (model_changed), reflow); - - reflow->comparison_changed_id = g_signal_connect ( - reflow->model, "comparison_changed", - G_CALLBACK (comparison_changed), reflow); - - reflow->model_items_inserted_id = g_signal_connect ( - reflow->model, "model_items_inserted", - G_CALLBACK (items_inserted), reflow); - - reflow->model_item_removed_id = g_signal_connect ( - reflow->model, "model_item_removed", - G_CALLBACK (item_removed), reflow); - - reflow->model_item_changed_id = g_signal_connect ( - reflow->model, "model_item_changed", - G_CALLBACK (item_changed), reflow); - - model_changed (model, reflow); -} - -static void -adjustment_changed (GtkAdjustment *adjustment, - EReflow *reflow) -{ - queue_incarnate (reflow); -} - -static void -disconnect_adjustment (EReflow *reflow) -{ - if (reflow->adjustment == NULL) - return; - - g_signal_handler_disconnect ( - reflow->adjustment, - reflow->adjustment_changed_id); - g_signal_handler_disconnect ( - reflow->adjustment, - reflow->adjustment_value_changed_id); - - g_object_unref (reflow->adjustment); - - reflow->adjustment_changed_id = 0; - reflow->adjustment_value_changed_id = 0; - reflow->adjustment = NULL; -} - -static void -connect_adjustment (EReflow *reflow, - GtkAdjustment *adjustment) -{ - if (reflow->adjustment != NULL) - disconnect_adjustment (reflow); - - if (adjustment == NULL) - return; - - reflow->adjustment = g_object_ref (adjustment); - - reflow->adjustment_changed_id = g_signal_connect ( - adjustment, "changed", - G_CALLBACK (adjustment_changed), reflow); - - reflow->adjustment_value_changed_id = g_signal_connect ( - adjustment, "value_changed", - G_CALLBACK (adjustment_changed), reflow); -} - -#if 0 -static void -set_scroll_adjustments (GtkLayout *layout, - GtkAdjustment *hadj, - GtkAdjustment *vadj, - EReflow *reflow) -{ - connect_adjustment (reflow, hadj); -} - -static void -connect_set_adjustment (EReflow *reflow) -{ - reflow->set_scroll_adjustments_id = g_signal_connect ( - GNOME_CANVAS_ITEM (reflow)->canvas, "set_scroll_adjustments", - G_CALLBACK (set_scroll_adjustments), reflow); -} -#endif - -static void -disconnect_set_adjustment (EReflow *reflow) -{ - if (reflow->set_scroll_adjustments_id != 0) { - g_signal_handler_disconnect ( - GNOME_CANVAS_ITEM (reflow)->canvas, - reflow->set_scroll_adjustments_id); - reflow->set_scroll_adjustments_id = 0; - } -} - -static void -column_width_changed (EReflow *reflow) -{ - g_signal_emit (reflow, signals[COLUMN_WIDTH_CHANGED], 0, reflow->column_width); -} - -/* Virtual functions */ -static void -e_reflow_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - EReflow *reflow; - - item = GNOME_CANVAS_ITEM (object); - reflow = E_REFLOW (object); - - switch (property_id) { - case PROP_HEIGHT: - reflow->height = g_value_get_double (value); - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow (item); - break; - case PROP_MINIMUM_WIDTH: - reflow->minimum_width = g_value_get_double (value); - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) - set_empty (reflow); - e_canvas_item_request_reflow (item); - break; - case PROP_EMPTY_MESSAGE: - g_free (reflow->empty_message); - reflow->empty_message = g_strdup (g_value_get_string (value)); - if (item->flags & GNOME_CANVAS_ITEM_REALIZED) - set_empty (reflow); - break; - case PROP_MODEL: - connect_model (reflow, (EReflowModel *) g_value_get_object (value)); - break; - case PROP_COLUMN_WIDTH: - if (reflow->column_width != g_value_get_double (value)) { - GtkLayout *layout; - GtkAdjustment *adjustment; - gdouble old_width = reflow->column_width; - gdouble step_increment; - gdouble page_size; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - page_size = gtk_adjustment_get_page_size (adjustment); - - reflow->column_width = g_value_get_double (value); - step_increment = (reflow->column_width + - E_REFLOW_FULL_GUTTER) / 2; - gtk_adjustment_set_step_increment ( - adjustment, step_increment); - gtk_adjustment_set_page_increment ( - adjustment, page_size - step_increment); - e_reflow_resize_children (item); - e_canvas_item_request_reflow (item); - - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update (item); - - if (old_width != reflow->column_width) - column_width_changed (reflow); - } - break; - } -} - -static void -e_reflow_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EReflow *reflow; - - reflow = E_REFLOW (object); - - switch (property_id) { - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, reflow->minimum_width); - break; - case PROP_WIDTH: - g_value_set_double (value, reflow->width); - break; - case PROP_HEIGHT: - g_value_set_double (value, reflow->height); - break; - case PROP_EMPTY_MESSAGE: - g_value_set_string (value, reflow->empty_message); - break; - case PROP_MODEL: - g_value_set_object (value, reflow->model); - break; - case PROP_COLUMN_WIDTH: - g_value_set_double (value, reflow->column_width); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_reflow_dispose (GObject *object) -{ - EReflow *reflow = E_REFLOW (object); - - g_free (reflow->items); - g_free (reflow->heights); - g_free (reflow->columns); - - reflow->items = NULL; - reflow->heights = NULL; - reflow->columns = NULL; - reflow->count = 0; - reflow->allocated_count = 0; - - if (reflow->incarnate_idle_id) - g_source_remove (reflow->incarnate_idle_id); - reflow->incarnate_idle_id = 0; - - if (reflow->do_adjustment_idle_id) - g_source_remove (reflow->do_adjustment_idle_id); - reflow->do_adjustment_idle_id = 0; - - disconnect_model (reflow); - disconnect_selection (reflow); - - g_free (reflow->empty_message); - reflow->empty_message = NULL; - - if (reflow->sorter) { - g_object_unref (reflow->sorter); - reflow->sorter = NULL; - } - - G_OBJECT_CLASS (e_reflow_parent_class)->dispose (object); -} - -static void -e_reflow_realize (GnomeCanvasItem *item) -{ - EReflow *reflow; - GtkAdjustment *adjustment; - gdouble page_increment; - gdouble step_increment; - gdouble page_size; - gint count; - gint i; - - reflow = E_REFLOW (item); - - if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->realize) (item); - - reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); - - count = reflow->count; - for (i = 0; i < count; i++) { - if (reflow->items[i]) - gnome_canvas_item_set ( - reflow->items[i], - "width", reflow->column_width, - NULL); - } - - set_empty (reflow); - - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow (item); - - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (item->canvas)); - -#if 0 - connect_set_adjustment (reflow); -#endif - connect_adjustment (reflow, adjustment); - - page_size = gtk_adjustment_get_page_size (adjustment); - step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2; - page_increment = page_size - step_increment; - gtk_adjustment_set_step_increment (adjustment, step_increment); - gtk_adjustment_set_page_increment (adjustment, page_increment); -} - -static void -e_reflow_unrealize (GnomeCanvasItem *item) -{ - EReflow *reflow; - - reflow = E_REFLOW (item); - - g_object_unref (reflow->arrow_cursor); - g_object_unref (reflow->default_cursor); - reflow->arrow_cursor = NULL; - reflow->default_cursor = NULL; - - g_free (reflow->columns); - reflow->columns = NULL; - - disconnect_set_adjustment (reflow); - disconnect_adjustment (reflow); - - if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->unrealize) - (* GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->unrealize) (item); -} - -static gboolean -e_reflow_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - EReflow *reflow; - gint return_val = FALSE; - - reflow = E_REFLOW (item); - - switch (event->type) - { - case GDK_KEY_PRESS: - return_val = e_selection_model_key_press (reflow->selection, (GdkEventKey *) event); - break; -#if 0 - if (event->key.keyval == GDK_Tab || - event->key.keyval == GDK_KEY_KP_Tab || - event->key.keyval == GDK_ISO_Left_Tab) { - gint i; - gint count; - count = reflow->count; - for (i = 0; i < count; i++) { - gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - GnomeCanvasItem *item = reflow->items[unsorted]; - EFocus has_focus; - if (item) { - g_object_get ( - item, - "has_focus", &has_focus, - NULL); - if (has_focus) { - if (event->key.state & GDK_SHIFT_MASK) { - if (i == 0) - return FALSE; - i--; - } else { - if (i == count - 1) - return FALSE; - i++; - } - - unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (reflow->items[unsorted] == NULL) { - reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); - } - - item = reflow->items[unsorted]; - gnome_canvas_item_set ( - item, - "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START, - NULL); - return TRUE; - } - } - } - } -#endif - case GDK_BUTTON_PRESS: - switch (event->button.button) - { - case 1: - { - GdkEventButton *button = (GdkEventButton *) event; - gdouble n_x; - n_x = button->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod (n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - if (button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER) { - /* don't allow to drag the first line*/ - if (e_reflow_pick_line (reflow, button->x) == 0) - return TRUE; - reflow->which_column_dragged = e_reflow_pick_line (reflow, button->x); - reflow->start_x = reflow->which_column_dragged * (reflow->column_width + E_REFLOW_FULL_GUTTER) - E_REFLOW_DIVIDER_WIDTH / 2; - reflow->temp_column_width = reflow->column_width; - reflow->column_drag = TRUE; - - gnome_canvas_item_grab ( - item, - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - reflow->arrow_cursor, - button->device, - button->time); - - reflow->previous_temp_column_width = -1; - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update (item); - return TRUE; - } - } - break; - case 4: - { - GtkLayout *layout; - GtkAdjustment *adjustment; - gdouble new_value; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - new_value = gtk_adjustment_get_value (adjustment); - new_value -= gtk_adjustment_get_step_increment (adjustment); - gtk_adjustment_set_value (adjustment, new_value); - } - break; - case 5: - { - GtkLayout *layout; - GtkAdjustment *adjustment; - gdouble new_value; - gdouble page_size; - gdouble upper; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - new_value = gtk_adjustment_get_value (adjustment); - new_value += gtk_adjustment_get_step_increment (adjustment); - upper = gtk_adjustment_get_upper (adjustment); - page_size = gtk_adjustment_get_page_size (adjustment); - if (new_value > upper - page_size) - new_value = upper - page_size; - gtk_adjustment_set_value (adjustment, new_value); - } - break; - } - break; - case GDK_BUTTON_RELEASE: - if (reflow->column_drag) { - gdouble old_width = reflow->column_width; - GdkEventButton *button = (GdkEventButton *) event; - GtkAdjustment *adjustment; - GtkLayout *layout; - gdouble value; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - value = gtk_adjustment_get_value (adjustment); - - reflow->temp_column_width = reflow->column_width + - (button->x - reflow->start_x) / (reflow->which_column_dragged - e_reflow_pick_line (reflow, value)); - if (reflow->temp_column_width < 50) - reflow->temp_column_width = 50; - reflow->column_drag = FALSE; - if (old_width != reflow->temp_column_width) { - gdouble page_increment; - gdouble step_increment; - gdouble page_size; - - page_size = gtk_adjustment_get_page_size (adjustment); - gtk_adjustment_set_value (adjustment, value + e_reflow_pick_line (reflow, value) * (reflow->temp_column_width - reflow->column_width)); - reflow->column_width = reflow->temp_column_width; - step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2; - page_increment = page_size - step_increment; - gtk_adjustment_set_step_increment (adjustment, step_increment); - gtk_adjustment_set_page_increment (adjustment, page_increment); - e_reflow_resize_children (item); - e_canvas_item_request_reflow (item); - gnome_canvas_request_redraw (item->canvas, 0, 0, reflow->width, reflow->height); - column_width_changed (reflow); - } - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update (item); - gnome_canvas_item_ungrab (item, button->time); - return TRUE; - } - break; - case GDK_MOTION_NOTIFY: - if (reflow->column_drag) { - gdouble old_width = reflow->temp_column_width; - GdkEventMotion *motion = (GdkEventMotion *) event; - GtkAdjustment *adjustment; - GtkLayout *layout; - gdouble value; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - value = gtk_adjustment_get_value (adjustment); - - reflow->temp_column_width = reflow->column_width + - (motion->x - reflow->start_x) / (reflow->which_column_dragged - e_reflow_pick_line (reflow, value)); - if (reflow->temp_column_width < 50) - reflow->temp_column_width = 50; - if (old_width != reflow->temp_column_width) { - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update (item); - } - return TRUE; - } else { - GdkEventMotion *motion = (GdkEventMotion *) event; - GdkWindow *window; - gdouble n_x; - - n_x = motion->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod (n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - window = gtk_widget_get_window (GTK_WIDGET (item->canvas)); - - if (motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER) { - if (reflow->default_cursor_shown) { - gdk_window_set_cursor (window, reflow->arrow_cursor); - reflow->default_cursor_shown = FALSE; - } - } else - if (!reflow->default_cursor_shown) { - gdk_window_set_cursor (window, reflow->default_cursor); - reflow->default_cursor_shown = TRUE; - } - - } - break; - case GDK_ENTER_NOTIFY: - if (!reflow->column_drag) { - GdkEventCrossing *crossing = (GdkEventCrossing *) event; - GdkWindow *window; - gdouble n_x; - - n_x = crossing->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod (n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - window = gtk_widget_get_window (GTK_WIDGET (item->canvas)); - - if (crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER) { - if (reflow->default_cursor_shown) { - gdk_window_set_cursor (window, reflow->arrow_cursor); - reflow->default_cursor_shown = FALSE; - } - } - } - break; - case GDK_LEAVE_NOTIFY: - if (!reflow->column_drag) { - GdkEventCrossing *crossing = (GdkEventCrossing *) event; - GdkWindow *window; - gdouble n_x; - - n_x = crossing->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod (n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - window = gtk_widget_get_window (GTK_WIDGET (item->canvas)); - - if (!(crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER)) { - if (!reflow->default_cursor_shown) { - gdk_window_set_cursor (window, reflow->default_cursor); - reflow->default_cursor_shown = TRUE; - } - } - } - break; - default: - break; - } - if (return_val) - return return_val; - else if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->event) - return (* GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->event) (item, event); - else - return FALSE; -} - -static void -e_reflow_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - GtkStyleContext *style_context; - GtkWidget *widget; - gint x_rect, y_rect, width_rect, height_rect; - gdouble running_width; - EReflow *reflow = E_REFLOW (item); - GdkRGBA color; - gint i; - gdouble column_width; - - if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->draw) - GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->draw (item, cr, x, y, width, height); - column_width = reflow->column_width; - running_width = E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - /* Compute first column to draw. */ - i = x; - i /= column_width + E_REFLOW_FULL_GUTTER; - running_width += i * (column_width + E_REFLOW_FULL_GUTTER); - - widget = GTK_WIDGET (item->canvas); - style_context = gtk_widget_get_style_context (widget); - - cairo_save (cr); - - gtk_style_context_get_background_color ( - style_context, GTK_STATE_FLAG_ACTIVE, &color); - gdk_cairo_set_source_rgba (cr, &color); - - for (; i < reflow->column_count; i++) { - if (running_width > x + width) - break; - x_rect = running_width; - - gtk_render_background ( - style_context, cr, - (gdouble) x_rect - x, - (gdouble) y_rect - y, - (gdouble) width_rect, - (gdouble) height_rect); - - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - - cairo_restore (cr); - - if (reflow->column_drag) { - GtkAdjustment *adjustment; - GtkLayout *layout; - gdouble value; - gint start_line; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - value = gtk_adjustment_get_value (adjustment); - - start_line = e_reflow_pick_line (reflow, value); - i = x - start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width = start_line * (column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - i += start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - /* Compute first column to draw. */ - i /= column_width + E_REFLOW_FULL_GUTTER; - running_width += i * (column_width + E_REFLOW_FULL_GUTTER); - - cairo_save (cr); - - gtk_style_context_get_color ( - style_context, GTK_STATE_FLAG_NORMAL, &color); - gdk_cairo_set_source_rgba (cr, &color); - - for (; i < reflow->column_count; i++) { - if (running_width > x + width) - break; - x_rect = running_width; - cairo_rectangle ( - cr, - x_rect - x, - y_rect - y, - width_rect - 1, - height_rect - 1); - cairo_fill (cr); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - - cairo_restore (cr); - } -} - -static void -e_reflow_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - EReflow *reflow; - gdouble x0, x1, y0, y1; - - reflow = E_REFLOW (item); - - if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->update) - GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->update (item, i2c, flags); - - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if (x1 < x0 + reflow->width) - x1 = x0 + reflow->width; - if (y1 < y0 + reflow->height) - y1 = y0 + reflow->height; - item->x2 = x1; - item->y2 = y1; - - if (reflow->need_height_update) { - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if (x0 > 0) - x0 = 0; - if (y0 > 0) - y0 = 0; - if (x1 < E_REFLOW (item)->width) - x1 = E_REFLOW (item)->width; - if (x1 < E_REFLOW (item)->height) - x1 = E_REFLOW (item)->height; - - gnome_canvas_request_redraw (item->canvas, x0, y0, x1, y1); - reflow->need_height_update = FALSE; - } else if (reflow->need_column_resize) { - GtkLayout *layout; - GtkAdjustment *adjustment; - gint x_rect, y_rect, width_rect, height_rect; - gint start_line; - gdouble running_width; - gint i; - gdouble column_width; - gdouble value; - - layout = GTK_LAYOUT (item->canvas); - adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout)); - value = gtk_adjustment_get_value (adjustment); - start_line = e_reflow_pick_line (reflow, value); - - if (reflow->previous_temp_column_width != -1) { - running_width = start_line * (reflow->column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->previous_temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - for (i = 0; i < reflow->column_count; i++) { - x_rect = running_width; - gnome_canvas_request_redraw (item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - } - - if (reflow->temp_column_width != -1) { - running_width = start_line * (reflow->column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - for (i = 0; i < reflow->column_count; i++) { - x_rect = running_width; - gnome_canvas_request_redraw (item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - } - - reflow->previous_temp_column_width = reflow->temp_column_width; - reflow->need_column_resize = FALSE; - } -} - -static GnomeCanvasItem * -e_reflow_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - GnomeCanvasItem *child = NULL; - - if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->point) - child = GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->point (item, x, y, cx, cy); - - return child ? child : item; -#if 0 - if (y >= E_REFLOW_BORDER_WIDTH && y <= reflow->height - E_REFLOW_BORDER_WIDTH) { - gfloat n_x; - n_x = x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod (n_x, (reflow->column_width + E_REFLOW_FULL_GUTTER)); - if (n_x < E_REFLOW_FULL_GUTTER) { - *actual_item = item; - return 0; - } - } - return distance; -#endif -} - -static void -e_reflow_reflow (GnomeCanvasItem *item, - gint flags) -{ - EReflow *reflow = E_REFLOW (item); - gdouble old_width; - gdouble running_width; - gdouble running_height; - gint next_column; - gint i; - - if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED)) - return; - - if (reflow->need_reflow_columns) { - reflow_columns (reflow); - } - - old_width = reflow->width; - - running_width = E_REFLOW_BORDER_WIDTH; - running_height = E_REFLOW_BORDER_WIDTH; - - next_column = 1; - - for (i = 0; i < reflow->count; i++) { - gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (next_column < reflow->column_count && i == reflow->columns[next_column]) { - running_height = E_REFLOW_BORDER_WIDTH; - running_width += reflow->column_width + E_REFLOW_FULL_GUTTER; - next_column++; - } - - if (unsorted >= 0 && reflow->items[unsorted]) { - e_canvas_item_move_absolute ( - GNOME_CANVAS_ITEM (reflow->items[unsorted]), - (gdouble) running_width, - (gdouble) running_height); - running_height += reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH; - } - } - reflow->width = running_width + reflow->column_width + E_REFLOW_BORDER_WIDTH; - if (reflow->width < reflow->minimum_width) - reflow->width = reflow->minimum_width; - if (old_width != reflow->width) - e_canvas_item_request_parent_reflow (item); -} - -static gint -e_reflow_selection_event_real (EReflow *reflow, - GnomeCanvasItem *item, - GdkEvent *event) -{ - gint row; - gint return_val = TRUE; - switch (event->type) { - case GDK_BUTTON_PRESS: - switch (event->button.button) { - case 1: /* Fall through. */ - case 2: - row = er_find_item (reflow, item); - if (event->button.button == 1) { - reflow->maybe_did_something = - e_selection_model_maybe_do_something (reflow->selection, row, 0, event->button.state); - reflow->maybe_in_drag = TRUE; - } else { - e_selection_model_do_something (reflow->selection, row, 0, event->button.state); - } - break; - case 3: - row = er_find_item (reflow, item); - e_selection_model_right_click_down (reflow->selection, row, 0, 0); - break; - default: - return_val = FALSE; - break; - } - break; - case GDK_BUTTON_RELEASE: - if (event->button.button == 1) { - if (reflow->maybe_in_drag) { - reflow->maybe_in_drag = FALSE; - if (!reflow->maybe_did_something) { - row = er_find_item (reflow, item); - e_selection_model_do_something (reflow->selection, row, 0, event->button.state); - } - } - } - break; - case GDK_KEY_PRESS: - return_val = e_selection_model_key_press (reflow->selection, (GdkEventKey *) event); - break; - default: - return_val = FALSE; - break; - } - - return return_val; -} - -static void -e_reflow_class_init (EReflowClass *class) -{ - GObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - object_class->set_property = e_reflow_set_property; - object_class->get_property = e_reflow_get_property; - object_class->dispose = e_reflow_dispose; - - /* GnomeCanvasItem method overrides */ - item_class->event = e_reflow_event; - item_class->realize = e_reflow_realize; - item_class->unrealize = e_reflow_unrealize; - item_class->draw = e_reflow_draw; - item_class->update = e_reflow_update; - item_class->point = e_reflow_point; - - class->selection_event = e_reflow_selection_event_real; - class->column_width_changed = NULL; - - g_object_class_install_property ( - object_class, - PROP_MINIMUM_WIDTH, - g_param_spec_double ( - "minimum_width", - "Minimum width", - "Minimum Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_EMPTY_MESSAGE, - g_param_spec_string ( - "empty_message", - "Empty message", - "Empty message", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Reflow model", - "Reflow model", - E_TYPE_REFLOW_MODEL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_COLUMN_WIDTH, - g_param_spec_double ( - "column_width", - "Column width", - "Column width", - 0.0, G_MAXDOUBLE, 150.0, - G_PARAM_READWRITE)); - - signals[SELECTION_EVENT] = g_signal_new ( - "selection_event", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowClass, selection_event), - NULL, NULL, - e_marshal_INT__OBJECT_BOXED, - G_TYPE_INT, 2, - G_TYPE_OBJECT, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - signals[COLUMN_WIDTH_CHANGED] = g_signal_new ( - "column_width_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowClass, column_width_changed), - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, - G_TYPE_DOUBLE); -} - -static void -e_reflow_init (EReflow *reflow) -{ - reflow->model = NULL; - reflow->items = NULL; - reflow->heights = NULL; - reflow->count = 0; - - reflow->columns = NULL; - reflow->column_count = 0; - - reflow->empty_text = NULL; - reflow->empty_message = NULL; - - reflow->minimum_width = 10; - reflow->width = 10; - reflow->height = 10; - - reflow->column_width = 150; - - reflow->column_drag = FALSE; - - reflow->need_height_update = FALSE; - reflow->need_column_resize = FALSE; - reflow->need_reflow_columns = FALSE; - - reflow->maybe_did_something = FALSE; - reflow->maybe_in_drag = FALSE; - - reflow->default_cursor_shown = TRUE; - reflow->arrow_cursor = NULL; - reflow->default_cursor = NULL; - - reflow->cursor_row = -1; - - reflow->incarnate_idle_id = 0; - reflow->do_adjustment_idle_id = 0; - reflow->set_scroll_adjustments_id = 0; - - reflow->selection = E_SELECTION_MODEL (e_selection_model_simple_new ()); - reflow->sorter = e_sorter_array_new (er_create_cmp_cache, er_compare, reflow); - - g_object_set ( - reflow->selection, - "sorter", reflow->sorter, - NULL); - - reflow->selection_changed_id = g_signal_connect ( - reflow->selection, "selection_changed", - G_CALLBACK (selection_changed), reflow); - - reflow->selection_row_changed_id = g_signal_connect ( - reflow->selection, "selection_row_changed", - G_CALLBACK (selection_row_changed), reflow); - - reflow->cursor_changed_id = g_signal_connect ( - reflow->selection, "cursor_changed", - G_CALLBACK (cursor_changed), reflow); - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (reflow), e_reflow_reflow); -} diff --git a/widgets/text/e-reflow.h b/widgets/text/e-reflow.h deleted file mode 100644 index 979857ea5c..0000000000 --- a/widgets/text/e-reflow.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_REFLOW_H -#define E_REFLOW_H - -#include <libgnomecanvas/libgnomecanvas.h> -#include <text/e-reflow-model.h> -#include <misc/e-selection-model.h> -#include <e-util/e-sorter-array.h> - -/* Standard GObject macros */ -#define E_TYPE_REFLOW \ - (e_reflow_get_type ()) -#define E_REFLOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_REFLOW, EReflow)) -#define E_REFLOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_REFLOW, EReflowClass)) -#define E_IS_REFLOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_REFLOW)) -#define E_IS_REFLOW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_REFLOW)) -#define E_REFLOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_REFLOW, EReflowClass)) - -G_BEGIN_DECLS - -typedef struct _EReflow EReflow; -typedef struct _EReflowClass EReflowClass; -typedef struct _EReflowPrivate EReflowPrivate; - -struct _EReflow { - GnomeCanvasGroup parent; - - /* item specific fields */ - EReflowModel *model; - guint model_changed_id; - guint comparison_changed_id; - guint model_items_inserted_id; - guint model_item_removed_id; - guint model_item_changed_id; - - ESelectionModel *selection; - guint selection_changed_id; - guint selection_row_changed_id; - guint cursor_changed_id; - ESorterArray *sorter; - - GtkAdjustment *adjustment; - guint adjustment_changed_id; - guint adjustment_value_changed_id; - guint set_scroll_adjustments_id; - - gint *heights; - GnomeCanvasItem **items; - gint count; - gint allocated_count; - - gint *columns; - gint column_count; /* Number of columnns */ - - GnomeCanvasItem *empty_text; - gchar *empty_message; - - gdouble minimum_width; - gdouble width; - gdouble height; - - gdouble column_width; - - gint incarnate_idle_id; - gint do_adjustment_idle_id; - - /* These are all for when the column is being dragged. */ - gdouble start_x; - gint which_column_dragged; - gdouble temp_column_width; - gdouble previous_temp_column_width; - - gint cursor_row; - - gint reflow_from_column; - - guint column_drag : 1; - - guint need_height_update : 1; - guint need_column_resize : 1; - guint need_reflow_columns : 1; - - guint default_cursor_shown : 1; - - guint maybe_did_something : 1; - guint maybe_in_drag : 1; - GdkCursor *arrow_cursor; - GdkCursor *default_cursor; -}; - -struct _EReflowClass -{ - GnomeCanvasGroupClass parent_class; - - gint (*selection_event) (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event); - void (*column_width_changed) (EReflow *reflow, gdouble width); -}; - -/* - * To be added to a reflow, an item must have the argument "width" as - * a Read/Write argument and "height" as a Read Only argument. It - * should also do an ECanvas parent reflow request if its size - * changes. - */ -GType e_reflow_get_type (void); - -G_END_DECLS - -#endif /* E_REFLOW_H */ diff --git a/widgets/text/e-text-model-repos.c b/widgets/text/e-text-model-repos.c deleted file mode 100644 index b56a213215..0000000000 --- a/widgets/text/e-text-model-repos.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jon Trowbridge <trow@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-text-model-repos.h" - -#define MODEL_CLAMP(model, pos) (CLAMP((pos), 0, strlen((model)->text))) - -gint -e_repos_absolute (gint pos, - gpointer data) -{ - EReposAbsolute *info = (EReposAbsolute *) data; - g_return_val_if_fail (data, -1); - - pos = info->pos; - if (pos < 0) { - gint len = e_text_model_get_text_length (info->model); - pos += len + 1; - } - - return e_text_model_validate_position (info->model, pos); -} - -gint -e_repos_insert_shift (gint pos, - gpointer data) -{ - EReposInsertShift *info = (EReposInsertShift *) data; - g_return_val_if_fail (data, -1); - - if (pos >= info->pos) - pos += info->len; - - return e_text_model_validate_position (info->model, pos); -} - -gint -e_repos_delete_shift (gint pos, - gpointer data) -{ - EReposDeleteShift *info = (EReposDeleteShift *) data; - g_return_val_if_fail (data, -1); - - if (pos > info->pos + info->len) - pos -= info->len; - else if (pos > info->pos) - pos = info->pos; - - return e_text_model_validate_position (info->model, pos); -} diff --git a/widgets/text/e-text-model-repos.h b/widgets/text/e-text-model-repos.h deleted file mode 100644 index f6d50a1111..0000000000 --- a/widgets/text/e-text-model-repos.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * e-text-model-repos.h - Standard ETextModelReposFn definitions - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jon Trowbridge <trow@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TEXT_MODEL_REPOS_H -#define E_TEXT_MODEL_REPOS_H - -#include "e-text-model.h" - -typedef struct { - ETextModel *model; - gint pos; /* Position to move to. Negative values count from the end buffer. - (i.e. -1 puts cursor at the end, -2 one character from end, etc.) */ -} EReposAbsolute; - -gint e_repos_absolute (gint pos, gpointer data); - -typedef struct { - ETextModel *model; - gint pos; /* Location of first inserted character. */ - gint len; /* Number of characters inserted. */ -} EReposInsertShift; - -gint e_repos_insert_shift (gint pos, gpointer data); - -typedef struct { - ETextModel *model; - gint pos; /* Location of first deleted character. */ - gint len; /* Number of characters deleted. */ -} EReposDeleteShift; - -gint e_repos_delete_shift (gint pos, gpointer data); - -#endif diff --git a/widgets/text/e-text-model.c b/widgets/text/e-text-model.c deleted file mode 100644 index 5027b3a3f7..0000000000 --- a/widgets/text/e-text-model.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#undef PARANOID_DEBUGGING - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "e-text-model.h" -#include "e-text-model-repos.h" - -#define E_TEXT_MODEL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_TEXT_MODEL, ETextModelPrivate)) - -enum { - E_TEXT_MODEL_CHANGED, - E_TEXT_MODEL_REPOSITION, - E_TEXT_MODEL_OBJECT_ACTIVATED, - E_TEXT_MODEL_CANCEL_COMPLETION, - E_TEXT_MODEL_LAST_SIGNAL -}; - -static guint signals[E_TEXT_MODEL_LAST_SIGNAL] = { 0 }; - -struct _ETextModelPrivate { - GString *text; -}; - -static gint e_text_model_real_validate_position - (ETextModel *, gint pos); -static const gchar * - e_text_model_real_get_text (ETextModel *model); -static gint e_text_model_real_get_text_length - (ETextModel *model); -static void e_text_model_real_set_text (ETextModel *model, - const gchar *text); -static void e_text_model_real_insert (ETextModel *model, - gint postion, - const gchar *text); -static void e_text_model_real_insert_length (ETextModel *model, - gint postion, - const gchar *text, - gint length); -static void e_text_model_real_delete (ETextModel *model, - gint postion, - gint length); - -G_DEFINE_TYPE (ETextModel, e_text_model, G_TYPE_OBJECT) - -static void -e_text_model_finalize (GObject *object) -{ - ETextModelPrivate *priv; - - priv = E_TEXT_MODEL_GET_PRIVATE (object); - - g_string_free (priv->text, TRUE); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_text_model_parent_class)->finalize (object); -} - -static void -e_text_model_class_init (ETextModelClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ETextModelPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = e_text_model_finalize; - - signals[E_TEXT_MODEL_CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextModelClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[E_TEXT_MODEL_REPOSITION] = g_signal_new ( - "reposition", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextModelClass, reposition), - NULL, NULL, - e_marshal_NONE__POINTER_POINTER, - G_TYPE_NONE, 2, - G_TYPE_POINTER, - G_TYPE_POINTER); - - signals[E_TEXT_MODEL_OBJECT_ACTIVATED] = g_signal_new ( - "object_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextModelClass, object_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - signals[E_TEXT_MODEL_CANCEL_COMPLETION] = g_signal_new ( - "cancel_completion", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextModelClass, cancel_completion), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* No default signal handlers. */ - class->changed = NULL; - class->reposition = NULL; - class->object_activated = NULL; - - class->validate_pos = e_text_model_real_validate_position; - - class->get_text = e_text_model_real_get_text; - class->get_text_len = e_text_model_real_get_text_length; - class->set_text = e_text_model_real_set_text; - class->insert = e_text_model_real_insert; - class->insert_length = e_text_model_real_insert_length; - class->delete = e_text_model_real_delete; - - /* We explicitly don't define default handlers for these. */ - class->objectify = NULL; - class->obj_count = NULL; - class->get_nth_obj = NULL; -} - -static void -e_text_model_init (ETextModel *model) -{ - model->priv = E_TEXT_MODEL_GET_PRIVATE (model); - model->priv->text = g_string_new (""); -} - -static gint -e_text_model_real_validate_position (ETextModel *model, - gint pos) -{ - gint len = e_text_model_get_text_length (model); - - if (pos < 0) - pos = 0; - else if (pos > len) - pos = len; - - return pos; -} - -static const gchar * -e_text_model_real_get_text (ETextModel *model) -{ - if (model->priv->text) - return model->priv->text->str; - else - return ""; -} - -static gint -e_text_model_real_get_text_length (ETextModel *model) -{ - return g_utf8_strlen (model->priv->text->str, -1); -} - -static void -e_text_model_real_set_text (ETextModel *model, - const gchar *text) -{ - EReposAbsolute repos; - gboolean changed = FALSE; - - if (text == NULL) { - changed = (*model->priv->text->str != '\0'); - - g_string_set_size (model->priv->text, 0); - - } else if (*model->priv->text->str == '\0' || - strcmp (model->priv->text->str, text)) { - - g_string_assign (model->priv->text, text); - - changed = TRUE; - } - - if (changed) { - e_text_model_changed (model); - repos.model = model; - repos.pos = -1; - e_text_model_reposition (model, e_repos_absolute, &repos); - } -} - -static void -e_text_model_real_insert (ETextModel *model, - gint position, - const gchar *text) -{ - e_text_model_insert_length (model, position, text, strlen (text)); -} - -static void -e_text_model_real_insert_length (ETextModel *model, - gint position, - const gchar *text, - gint length) -{ - EReposInsertShift repos; - gint model_len = e_text_model_real_get_text_length (model); - gchar *offs; - const gchar *p; - gint byte_length, l; - - if (position > model_len) - return; - - offs = g_utf8_offset_to_pointer (model->priv->text->str, position); - - for (p = text, l = 0; - l < length; - p = g_utf8_next_char (p), l++); - - byte_length = p - text; - - g_string_insert_len ( - model->priv->text, - offs - model->priv->text->str, - text, byte_length); - - e_text_model_changed (model); - - repos.model = model; - repos.pos = position; - repos.len = length; - - e_text_model_reposition (model, e_repos_insert_shift, &repos); -} - -static void -e_text_model_real_delete (ETextModel *model, - gint position, - gint length) -{ - EReposDeleteShift repos; - gint byte_position, byte_length; - gchar *offs, *p; - gint l; - - offs = g_utf8_offset_to_pointer (model->priv->text->str, position); - byte_position = offs - model->priv->text->str; - - for (p = offs, l = 0; - l < length; - p = g_utf8_next_char (p), l++); - - byte_length = p - offs; - - g_string_erase ( - model->priv->text, - byte_position, byte_length); - - e_text_model_changed (model); - - repos.model = model; - repos.pos = position; - repos.len = length; - - e_text_model_reposition (model, e_repos_delete_shift, &repos); -} - -void -e_text_model_changed (ETextModel *model) -{ - ETextModelClass *class; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - class = E_TEXT_MODEL_GET_CLASS (model); - - /* - Objectify before emitting any signal. - While this method could, in theory, do pretty much anything, it is meant - for scanning objects and converting substrings into embedded objects. - */ - if (class->objectify != NULL) - class->objectify (model); - - g_signal_emit (model, signals[E_TEXT_MODEL_CHANGED], 0); -} - -void -e_text_model_cancel_completion (ETextModel *model) -{ - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - g_signal_emit (model, signals[E_TEXT_MODEL_CANCEL_COMPLETION], 0); -} - -void -e_text_model_reposition (ETextModel *model, - ETextModelReposFn fn, - gpointer repos_data) -{ - g_return_if_fail (E_IS_TEXT_MODEL (model)); - g_return_if_fail (fn != NULL); - - g_signal_emit ( - model, signals[E_TEXT_MODEL_REPOSITION], 0, fn, repos_data); -} - -gint -e_text_model_validate_position (ETextModel *model, - gint pos) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), 0); - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->validate_pos != NULL) - pos = class->validate_pos (model, pos); - - return pos; -} - -const gchar * -e_text_model_get_text (ETextModel *model) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), NULL); - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->get_text == NULL) - return ""; - - return class->get_text (model); -} - -gint -e_text_model_get_text_length (ETextModel *model) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), 0); - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->get_text_len (model)) { - - gint len = class->get_text_len (model); - -#ifdef PARANOID_DEBUGGING - const gchar *str = e_text_model_get_text (model); - gint len2 = str ? g_utf8_strlen (str, -1) : 0; - if (len != len) - g_error ("\"%s\" length reported as %d, not %d.", str, len, len2); -#endif - - return len; - - } else { - /* Calculate length the old-fashioned way... */ - const gchar *str = e_text_model_get_text (model); - return str ? g_utf8_strlen (str, -1) : 0; - } -} - -void -e_text_model_set_text (ETextModel *model, - const gchar *text) -{ - ETextModelClass *class; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->set_text != NULL) - class->set_text (model, text); -} - -void -e_text_model_insert (ETextModel *model, - gint position, - const gchar *text) -{ - ETextModelClass *class; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - if (text == NULL) - return; - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->insert != NULL) - class->insert (model, position, text); -} - -void -e_text_model_insert_length (ETextModel *model, - gint position, - const gchar *text, - gint length) -{ - ETextModelClass *class; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - g_return_if_fail (length >= 0); - - if (text == NULL || length == 0) - return; - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->insert_length != NULL) - class->insert_length (model, position, text, length); -} - -void -e_text_model_prepend (ETextModel *model, - const gchar *text) -{ - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - if (text == NULL) - return; - - e_text_model_insert (model, 0, text); -} - -void -e_text_model_append (ETextModel *model, - const gchar *text) -{ - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - if (text == NULL) - return; - - e_text_model_insert (model, e_text_model_get_text_length (model), text); -} - -void -e_text_model_delete (ETextModel *model, - gint position, - gint length) -{ - ETextModelClass *class; - gint txt_len; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - g_return_if_fail (length >= 0); - - txt_len = e_text_model_get_text_length (model); - if (position + length > txt_len) - length = txt_len - position; - - if (length <= 0) - return; - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->delete != NULL) - class->delete (model, position, length); -} - -gint -e_text_model_object_count (ETextModel *model) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), 0); - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->obj_count == NULL) - return 0; - - return class->obj_count (model); -} - -const gchar * -e_text_model_get_nth_object (ETextModel *model, - gint n, - gint *len) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), NULL); - - if (n < 0 || n >= e_text_model_object_count (model)) - return NULL; - - class = E_TEXT_MODEL_GET_CLASS (model); - - if (class->get_nth_obj == NULL) - return NULL; - - return class->get_nth_obj (model, n, len); -} - -gchar * -e_text_model_strdup_nth_object (ETextModel *model, - gint n) -{ - const gchar *obj; - gint len = 0; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), NULL); - - obj = e_text_model_get_nth_object (model, n, &len); - - if (obj) { - gint byte_len; - byte_len = g_utf8_offset_to_pointer (obj, len) - obj; - return g_strndup (obj, byte_len); - } - else { - return NULL; - } -} - -void -e_text_model_get_nth_object_bounds (ETextModel *model, - gint n, - gint *start, - gint *end) -{ - const gchar *txt = NULL, *obj = NULL; - gint len = 0; - - g_return_if_fail (E_IS_TEXT_MODEL (model)); - - txt = e_text_model_get_text (model); - obj = e_text_model_get_nth_object (model, n, &len); - - g_return_if_fail (obj != NULL); - - if (start) - *start = g_utf8_pointer_to_offset (txt, obj); - if (end) - *end = (start ? *start : 0) + len; -} - -gint -e_text_model_get_object_at_offset (ETextModel *model, - gint offset) -{ - ETextModelClass *class; - - g_return_val_if_fail (E_IS_TEXT_MODEL (model), -1); - - if (offset < 0 || offset >= e_text_model_get_text_length (model)) - return -1; - - class = E_TEXT_MODEL_GET_CLASS (model); - - /* If an optimized version has been provided, we use it. */ - if (class->obj_at_offset != NULL) { - return class->obj_at_offset (model, offset); - - } else { - /* If not, we fake it.*/ - - gint i, N, pos0, pos1; - - N = e_text_model_object_count (model); - - for (i = 0; i < N; ++i) { - e_text_model_get_nth_object_bounds (model, i, &pos0, &pos1); - if (pos0 <= offset && offset < pos1) - return i; - } - - } - - return -1; -} - -gint -e_text_model_get_object_at_pointer (ETextModel *model, - const gchar *s) -{ - g_return_val_if_fail (E_IS_TEXT_MODEL (model), -1); - g_return_val_if_fail (s != NULL, -1); - - return e_text_model_get_object_at_offset ( - model, s - e_text_model_get_text (model)); -} - -void -e_text_model_activate_nth_object (ETextModel *model, - gint n) -{ - g_return_if_fail (model != NULL); - g_return_if_fail (E_IS_TEXT_MODEL (model)); - g_return_if_fail (n >= 0); - g_return_if_fail (n < e_text_model_object_count (model)); - - g_signal_emit (model, signals[E_TEXT_MODEL_OBJECT_ACTIVATED], 0, n); -} - -ETextModel * -e_text_model_new (void) -{ - ETextModel *model = g_object_new (E_TYPE_TEXT_MODEL, NULL); - return model; -} diff --git a/widgets/text/e-text-model.h b/widgets/text/e-text-model.h deleted file mode 100644 index 4b0a4475cb..0000000000 --- a/widgets/text/e-text-model.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TEXT_MODEL_H -#define E_TEXT_MODEL_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define E_TYPE_TEXT_MODEL (e_text_model_get_type ()) -#define E_TEXT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TEXT_MODEL, ETextModel)) -#define E_TEXT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TEXT_MODEL, ETextModelClass)) -#define E_IS_TEXT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TEXT_MODEL)) -#define E_IS_TEXT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_TEXT_MODEL)) -#define E_TEXT_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_TEXT_MODEL_TYPE, ETextModelClass)) - -typedef struct _ETextModel ETextModel; -typedef struct _ETextModelClass ETextModelClass; -typedef struct _ETextModelPrivate ETextModelPrivate; - -typedef gint (*ETextModelReposFn) (gint, gpointer); - -struct _ETextModel { - GObject item; - - ETextModelPrivate *priv; -}; - -struct _ETextModelClass { - GObjectClass parent_class; - - /* Signal */ - void (* changed) (ETextModel *model); - void (* reposition) (ETextModel *model, ETextModelReposFn fn, gpointer repos_fn_data); - void (* object_activated) (ETextModel *model, gint obj_num); - void (* cancel_completion) (ETextModel *model); - - /* Virtual methods */ - - gint (* validate_pos) (ETextModel *model, gint pos); - - const gchar *(* get_text) (ETextModel *model); - gint (* get_text_len) (ETextModel *model); - void (* set_text) (ETextModel *model, const gchar *text); - void (* insert) (ETextModel *model, gint position, const gchar *text); - void (* insert_length) (ETextModel *model, gint position, const gchar *text, gint length); - void (* delete) (ETextModel *model, gint position, gint length); - - void (* objectify) (ETextModel *model); - gint (* obj_count) (ETextModel *model); - const gchar *(* get_nth_obj) (ETextModel *model, gint n, gint *len); - gint (* obj_at_offset) (ETextModel *model, gint offset); -}; - -GType e_text_model_get_type (void); - -ETextModel *e_text_model_new (void); - -void e_text_model_changed (ETextModel *model); -void e_text_model_cancel_completion (ETextModel *model); - -void e_text_model_reposition (ETextModel *model, ETextModelReposFn fn, gpointer repos_data); -gint e_text_model_validate_position (ETextModel *model, gint pos); - -/* Functions for manipulating the underlying text. */ - -const gchar *e_text_model_get_text (ETextModel *model); -gint e_text_model_get_text_length (ETextModel *model); -void e_text_model_set_text (ETextModel *model, const gchar *text); -void e_text_model_insert (ETextModel *model, gint position, const gchar *text); -void e_text_model_insert_length (ETextModel *model, gint position, const gchar *text, gint length); -void e_text_model_prepend (ETextModel *model, const gchar *text); -void e_text_model_append (ETextModel *model, const gchar *text); -void e_text_model_delete (ETextModel *model, gint position, gint length); - -/* Functions for accessing embedded objects. */ - -gint e_text_model_object_count (ETextModel *model); -const gchar *e_text_model_get_nth_object (ETextModel *model, gint n, gint *len); -gchar *e_text_model_strdup_nth_object (ETextModel *model, gint n); -void e_text_model_get_nth_object_bounds (ETextModel *model, gint n, gint *start_pos, gint *end_pos); -gint e_text_model_get_object_at_offset (ETextModel *model, gint offset); -gint e_text_model_get_object_at_pointer (ETextModel *model, const gchar *c); -void e_text_model_activate_nth_object (ETextModel *model, gint n); - -G_END_DECLS - -#endif diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c deleted file mode 100644 index f75c4ca8b9..0000000000 --- a/widgets/text/e-text.c +++ /dev/null @@ -1,3405 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-text.c - Text item for evolution. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Jon Trowbridge <trow@ximian.com> - * - * A majority of code taken from: - * - * Text item type for GnomeCanvas widget - * - * GnomeCanvas is basically a port of the Tk toolkit's most excellent - * canvas widget. Tk is copyrighted by the Regents of the University - * of California, Sun Microsystems, and other parties. - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <ctype.h> -#include <string.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "gal-a11y-e-text.h" -#include "misc/e-canvas.h" -#include "misc/e-canvas-utils.h" -#include "e-util/e-unicode.h" -#include <glib/gi18n.h> -#include "e-util/e-text-event-processor-emacs-like.h" -#include "e-util/e-util.h" - -#include "e-text.h" - -G_DEFINE_TYPE (EText, e_text, GNOME_TYPE_CANVAS_ITEM) - -enum { - E_TEXT_CHANGED, - E_TEXT_ACTIVATE, - E_TEXT_KEYPRESS, - E_TEXT_POPULATE_POPUP, - E_TEXT_LAST_SIGNAL -}; - -static GQuark e_text_signals[E_TEXT_LAST_SIGNAL] = { 0 }; - -/* Object argument IDs */ -enum { - PROP_0, - PROP_MODEL, - PROP_EVENT_PROCESSOR, - PROP_TEXT, - PROP_BOLD, - PROP_STRIKEOUT, - PROP_ANCHOR, - PROP_JUSTIFICATION, - PROP_CLIP_WIDTH, - PROP_CLIP_HEIGHT, - PROP_CLIP, - PROP_FILL_CLIP_RECTANGLE, - PROP_X_OFFSET, - PROP_Y_OFFSET, - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, - PROP_TEXT_WIDTH, - PROP_TEXT_HEIGHT, - PROP_EDITABLE, - PROP_USE_ELLIPSIS, - PROP_ELLIPSIS, - PROP_LINE_WRAP, - PROP_BREAK_CHARACTERS, - PROP_MAX_LINES, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ALLOW_NEWLINES, - PROP_CURSOR_POS, - PROP_IM_CONTEXT, - PROP_HANDLE_POPUP -}; - -static void e_text_command (ETextEventProcessor *tep, - ETextEventProcessorCommand *command, - gpointer data); - -static void e_text_text_model_changed (ETextModel *model, - EText *text); -static void e_text_text_model_reposition (ETextModel *model, - ETextModelReposFn fn, - gpointer repos_data, - gpointer data); - -static void _get_tep (EText *text); - -static void calc_height (EText *text); - -static gboolean show_pango_rectangle (EText *text, PangoRectangle rect); - -static void e_text_do_popup (EText *text, - GdkEvent *event_button, - gint position); - -static void e_text_update_primary_selection (EText *text); -static void e_text_paste (EText *text, GdkAtom selection); -static void e_text_insert (EText *text, const gchar *string); -static void e_text_reset_im_context (EText *text); - -static void reset_layout_attrs (EText *text); - -/* IM Context Callbacks */ -static void e_text_commit_cb (GtkIMContext *context, - const gchar *str, - EText *text); -static void e_text_preedit_changed_cb (GtkIMContext *context, - EText *text); -static gboolean e_text_retrieve_surrounding_cb (GtkIMContext *context, - EText *text); -static gboolean e_text_delete_surrounding_cb (GtkIMContext *context, - gint offset, - gint n_chars, - EText *text); - -static GdkAtom clipboard_atom = GDK_NONE; - -static void -disconnect_im_context (EText *text) -{ - if (!text || !text->im_context) - return; - - g_signal_handlers_disconnect_matched ( - text->im_context, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, text); - text->im_context_signals_registered = FALSE; -} - -/* Dispose handler for the text item */ -static void -e_text_dispose (GObject *object) -{ - EText *text; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_TEXT (object)); - - text = E_TEXT (object); - - if (text->model_changed_signal_id) - g_signal_handler_disconnect ( - text->model, - text->model_changed_signal_id); - text->model_changed_signal_id = 0; - - if (text->model_repos_signal_id) - g_signal_handler_disconnect ( - text->model, - text->model_repos_signal_id); - text->model_repos_signal_id = 0; - - if (text->model) - g_object_unref (text->model); - text->model = NULL; - - if (text->tep_command_id) - g_signal_handler_disconnect ( - text->tep, - text->tep_command_id); - text->tep_command_id = 0; - - if (text->tep) - g_object_unref (text->tep); - text->tep = NULL; - - g_free (text->revert); - text->revert = NULL; - - if (text->timeout_id) { - g_source_remove (text->timeout_id); - text->timeout_id = 0; - } - - if (text->timer) { - g_timer_stop (text->timer); - g_timer_destroy (text->timer); - text->timer = NULL; - } - - if (text->dbl_timeout) { - g_source_remove (text->dbl_timeout); - text->dbl_timeout = 0; - } - - if (text->tpl_timeout) { - g_source_remove (text->tpl_timeout); - text->tpl_timeout = 0; - } - - if (text->layout) { - g_object_unref (text->layout); - text->layout = NULL; - } - - if (text->im_context) { - disconnect_im_context (text); - g_object_unref (text->im_context); - text->im_context = NULL; - } - - if (text->font_desc) { - pango_font_description_free (text->font_desc); - text->font_desc = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_text_parent_class)->dispose (object); -} - -static void -insert_preedit_text (EText *text) -{ - PangoAttrList *attrs = NULL; - PangoAttrList *preedit_attrs = NULL; - gchar *preedit_string = NULL; - GString *tmp_string = g_string_new (NULL); - gint length = 0, cpos = 0; - gboolean new_attrs = FALSE; - - if (text->layout == NULL || !GTK_IS_IM_CONTEXT (text->im_context)) - return; - - text->text = e_text_model_get_text (text->model); - length = strlen (text->text); - - g_string_prepend_len (tmp_string, text->text,length); - - /* we came into this function only when text->preedit_len was not 0 - * so we can safely fetch the preedit string */ - gtk_im_context_get_preedit_string ( - text->im_context, &preedit_string, &preedit_attrs, NULL); - - if (preedit_string && g_utf8_validate (preedit_string, -1, NULL)) { - - text->preedit_len = strlen (preedit_string); - - cpos = g_utf8_offset_to_pointer ( - text->text, text->selection_start) - text->text; - - g_string_insert (tmp_string, cpos, preedit_string); - - reset_layout_attrs (text); - - attrs = pango_layout_get_attributes (text->layout); - if (!attrs) { - attrs = pango_attr_list_new (); - new_attrs = TRUE; - } - - pango_layout_set_text (text->layout, tmp_string->str, tmp_string->len); - - pango_attr_list_splice (attrs, preedit_attrs, cpos, text->preedit_len); - - if (new_attrs) { - pango_layout_set_attributes (text->layout, attrs); - pango_attr_list_unref (attrs); - } - } else - text->preedit_len = 0; - - if (preedit_string) - g_free (preedit_string); - if (preedit_attrs) - pango_attr_list_unref (preedit_attrs); - if (tmp_string) - g_string_free (tmp_string, TRUE); -} - -static void -reset_layout_attrs (EText *text) -{ - PangoAttrList *attrs = NULL; - gint object_count; - - if (text->layout == NULL) - return; - - object_count = e_text_model_object_count (text->model); - - if (text->bold || text->strikeout || object_count > 0) { - gint length = 0; - gint i; - - attrs = pango_attr_list_new (); - - for (i = 0; i < object_count; i++) { - gint start_pos, end_pos; - PangoAttribute *attr; - - attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); - - e_text_model_get_nth_object_bounds ( - text->model, i, &start_pos, &end_pos); - - attr->start_index = g_utf8_offset_to_pointer ( - text->text, start_pos) - text->text; - attr->end_index = g_utf8_offset_to_pointer ( - text->text, end_pos) - text->text; - - pango_attr_list_insert (attrs, attr); - } - - if (text->bold || text->strikeout) - length = strlen (text->text); - - if (text->bold) { - PangoAttribute *attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); - attr->start_index = 0; - attr->end_index = length; - - pango_attr_list_insert_before (attrs, attr); - } - if (text->strikeout) { - PangoAttribute *attr = pango_attr_strikethrough_new (TRUE); - attr->start_index = 0; - attr->end_index = length; - - pango_attr_list_insert_before (attrs, attr); - } - } - - pango_layout_set_attributes (text->layout, attrs); - - if (attrs) - pango_attr_list_unref (attrs); - - calc_height (text); -} - -static void -create_layout (EText *text) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (text); - - if (text->layout) - return; - - text->layout = gtk_widget_create_pango_layout ( - GTK_WIDGET (item->canvas), text->text); - if (text->line_wrap) - pango_layout_set_width ( - text->layout, text->clip_width < 0 - ? -1 : text->clip_width * PANGO_SCALE); - reset_layout_attrs (text); -} - -static void -reset_layout (EText *text) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (text); - - if (text->layout == NULL) { - create_layout (text); - } - else { - GtkStyle *style; - - style = gtk_widget_get_style (GTK_WIDGET (item->canvas)); - - if (text->font_desc) { - pango_font_description_free (text->font_desc); - } - text->font_desc = pango_font_description_new (); - if (!pango_font_description_get_size_is_absolute (style->font_desc)) - pango_font_description_set_size ( - text->font_desc, - pango_font_description_get_size (style->font_desc)); - else - pango_font_description_set_absolute_size ( - text->font_desc, - pango_font_description_get_size (style->font_desc)); - pango_font_description_set_family ( - text->font_desc, - pango_font_description_get_family (style->font_desc)); - pango_layout_set_font_description (text->layout, text->font_desc); - - pango_layout_set_text (text->layout, text->text, -1); - reset_layout_attrs (text); - } - - if (!text->button_down) { - PangoRectangle strong_pos, weak_pos; - gchar *offs = g_utf8_offset_to_pointer (text->text, text->selection_start); - - pango_layout_get_cursor_pos ( - text->layout, offs - text->text, - &strong_pos, &weak_pos); - - if (strong_pos.x != weak_pos.x || - strong_pos.y != weak_pos.y || - strong_pos.width != weak_pos.width || - strong_pos.height != weak_pos.height) - show_pango_rectangle (text, weak_pos); - - show_pango_rectangle (text, strong_pos); - } -} - -static void -e_text_text_model_changed (ETextModel *model, - EText *text) -{ - gint model_len = e_text_model_get_text_length (model); - text->text = e_text_model_get_text (model); - - /* Make sure our selection doesn't extend past the bounds of our text. */ - text->selection_start = CLAMP (text->selection_start, 0, model_len); - text->selection_end = CLAMP (text->selection_end, 0, model_len); - - text->needs_reset_layout = 1; - text->needs_split_into_lines = 1; - text->needs_redraw = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (text)); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (text)); - - g_signal_emit (text, e_text_signals[E_TEXT_CHANGED], 0); -} - -static void -e_text_text_model_reposition (ETextModel *model, - ETextModelReposFn fn, - gpointer repos_data, - gpointer user_data) -{ - EText *text = E_TEXT (user_data); - gint model_len = e_text_model_get_text_length (model); - - text->selection_start = fn (text->selection_start, repos_data); - text->selection_end = fn (text->selection_end, repos_data); - - /* Our repos function should make sure we don't overrun the buffer, but it never - * hurts to be paranoid. */ - text->selection_start = CLAMP (text->selection_start, 0, model_len); - text->selection_end = CLAMP (text->selection_end, 0, model_len); - - if (text->selection_start > text->selection_end) { - gint tmp = text->selection_start; - text->selection_start = text->selection_end; - text->selection_end = tmp; - } -} - -static void -get_bounds (EText *text, - gdouble *px1, - gdouble *py1, - gdouble *px2, - gdouble *py2) -{ - GnomeCanvasItem *item; - gdouble wx, wy, clip_width, clip_height; - - item = GNOME_CANVAS_ITEM (text); - - /* Get canvas pixel coordinates for text position */ - - wx = 0; - wy = 0; - gnome_canvas_item_i2w (item, &wx, &wy); - gnome_canvas_w2c (item->canvas, wx, wy, &text->cx, &text->cy); - gnome_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy); - - if (text->clip_width < 0) - clip_width = text->width; - else - clip_width = text->clip_width; - - if (text->clip_height < 0) - clip_height = text->height; - else - clip_height = text->clip_height; - - /* Get canvas pixel coordinates for clip rectangle position */ - text->clip_cwidth = clip_width; - text->clip_cheight = clip_height; - - text->text_cx = text->cx; - text->text_cy = text->cy; - - /* Bounds */ - - if (text->clip) { - *px1 = text->clip_cx; - *py1 = text->clip_cy; - *px2 = text->clip_cx + text->clip_cwidth; - *py2 = text->clip_cy + text->clip_cheight; - } else { - *px1 = text->cx; - *py1 = text->cy; - *px2 = text->cx + text->width; - *py2 = text->cy + text->height; - } -} - -static void -calc_height (EText *text) -{ - GnomeCanvasItem *item; - gint old_height; - gint old_width; - gint width = 0; - gint height = 0; - - item = GNOME_CANVAS_ITEM (text); - - /* Calculate text dimensions */ - - old_height = text->height; - old_width = text->width; - - if (text->layout) - pango_layout_get_pixel_size (text->layout, &width, &height); - - text->height = height; - text->width = width; - - if (old_height != text->height || old_width != text->width) - e_canvas_item_request_parent_reflow (item); -} - -static void -calc_ellipsis (EText *text) -{ -/* FIXME: a pango layout per calc_ellipsis sucks */ - gint width; - PangoLayout *layout = gtk_widget_create_pango_layout ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - text->ellipsis ? text->ellipsis : "..."); - pango_layout_get_size (layout, &width, NULL); - - text->ellipsis_width = width; - - g_object_unref (layout); -} - -static void -split_into_lines (EText *text) -{ - text->num_lines = pango_layout_get_line_count (text->layout); -} - -/* Set_arg handler for the text item */ -static void -e_text_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeCanvasItem *item; - EText *text; - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - - gboolean needs_update = 0; - gboolean needs_reflow = 0; - - item = GNOME_CANVAS_ITEM (object); - text = E_TEXT (object); - - switch (property_id) { - case PROP_MODEL: - - if (text->model_changed_signal_id) - g_signal_handler_disconnect ( - text->model, - text->model_changed_signal_id); - - if (text->model_repos_signal_id) - g_signal_handler_disconnect ( - text->model, - text->model_repos_signal_id); - - g_object_unref (text->model); - text->model = E_TEXT_MODEL (g_value_get_object (value)); - g_object_ref (text->model); - - text->model_changed_signal_id = g_signal_connect ( - text->model, "changed", - G_CALLBACK (e_text_text_model_changed), text); - - text->model_repos_signal_id = g_signal_connect ( - text->model, "reposition", - G_CALLBACK (e_text_text_model_reposition), text); - - text->text = e_text_model_get_text (text->model); - g_signal_emit (text, e_text_signals[E_TEXT_CHANGED], 0); - - text->needs_split_into_lines = 1; - needs_reflow = 1; - break; - - case PROP_EVENT_PROCESSOR: - if (text->tep && text->tep_command_id) - g_signal_handler_disconnect ( - text->tep, - text->tep_command_id); - if (text->tep) { - g_object_unref (text->tep); - } - text->tep = E_TEXT_EVENT_PROCESSOR (g_value_get_object (value)); - g_object_ref (text->tep); - - text->tep_command_id = g_signal_connect ( - text->tep, "command", - G_CALLBACK (e_text_command), text); - - if (!text->allow_newlines) - g_object_set ( - text->tep, - "allow_newlines", FALSE, - NULL); - break; - - case PROP_TEXT: - e_text_model_set_text (text->model, g_value_get_string (value)); - break; - - case PROP_BOLD: - text->bold = g_value_get_boolean (value); - - text->needs_redraw = 1; - text->needs_recalc_bounds = 1; - if (text->line_wrap) - text->needs_split_into_lines = 1; - else { - text->needs_calc_height = 1; - } - needs_update = 1; - needs_reflow = 1; - break; - - case PROP_STRIKEOUT: - text->strikeout = g_value_get_boolean (value); - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_JUSTIFICATION: - text->justification = g_value_get_enum (value); - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_CLIP_WIDTH: - text->clip_width = fabs (g_value_get_double (value)); - calc_ellipsis (text); - if (text->line_wrap) { - if (text->layout) - pango_layout_set_width ( - text->layout, text->clip_width < 0 - ? -1 : text->clip_width * PANGO_SCALE); - text->needs_split_into_lines = 1; - } else { - text->needs_calc_height = 1; - } - needs_reflow = 1; - break; - - case PROP_CLIP_HEIGHT: - text->clip_height = fabs (g_value_get_double (value)); - text->needs_recalc_bounds = 1; - /* toshok: kind of a hack - set needs_reset_layout - * here so when something about the style/them - * changes, we redraw the text at the proper size/with - * the proper font. */ - text->needs_reset_layout = 1; - needs_reflow = 1; - break; - - case PROP_CLIP: - text->clip = g_value_get_boolean (value); - calc_ellipsis (text); - if (text->line_wrap) - text->needs_split_into_lines = 1; - else { - text->needs_calc_height = 1; - } - needs_reflow = 1; - break; - - case PROP_FILL_CLIP_RECTANGLE: - text->fill_clip_rectangle = g_value_get_boolean (value); - needs_update = 1; - break; - - case PROP_X_OFFSET: - text->xofs = g_value_get_double (value); - text->needs_recalc_bounds = 1; - needs_update = 1; - break; - - case PROP_Y_OFFSET: - text->yofs = g_value_get_double (value); - text->needs_recalc_bounds = 1; - needs_update = 1; - break; - - case PROP_FILL_COLOR: - if (g_value_get_string (value)) - gdk_color_parse (g_value_get_string (value), &color); - - text->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - text->rgba_set = TRUE; - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - if (pcolor) { - color = *pcolor; - } - - text->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - text->rgba_set = TRUE; - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_FILL_COLOR_RGBA: - text->rgba = g_value_get_uint (value); - color.red = ((text->rgba >> 24) & 0xff) * 0x101; - color.green = ((text->rgba >> 16) & 0xff) * 0x101; - color.blue = ((text->rgba >> 8) & 0xff) * 0x101; - text->rgba_set = TRUE; - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_EDITABLE: - text->editable = g_value_get_boolean (value); - text->needs_redraw = 1; - needs_update = 1; - break; - - case PROP_USE_ELLIPSIS: - text->use_ellipsis = g_value_get_boolean (value); - needs_reflow = 1; - break; - - case PROP_ELLIPSIS: - if (text->ellipsis) - g_free (text->ellipsis); - - text->ellipsis = g_strdup (g_value_get_string (value)); - calc_ellipsis (text); - needs_reflow = 1; - break; - - case PROP_LINE_WRAP: - text->line_wrap = g_value_get_boolean (value); - if (text->line_wrap) { - if (text->layout) { - pango_layout_set_width ( - text->layout, text->width < 0 - ? -1 : text->width * PANGO_SCALE); - } - } - text->needs_split_into_lines = 1; - needs_reflow = 1; - break; - - case PROP_BREAK_CHARACTERS: - if (text->break_characters) { - g_free (text->break_characters); - text->break_characters = NULL; - } - if (g_value_get_string (value)) - text->break_characters = g_strdup (g_value_get_string (value)); - text->needs_split_into_lines = 1; - needs_reflow = 1; - break; - - case PROP_MAX_LINES: - text->max_lines = g_value_get_int (value); - text->needs_split_into_lines = 1; - needs_reflow = 1; - break; - - case PROP_WIDTH: - text->clip_width = fabs (g_value_get_double (value)); - calc_ellipsis (text); - if (text->line_wrap) { - if (text->layout) { - pango_layout_set_width ( - text->layout, text->width < 0 ? - -1 : text->width * PANGO_SCALE); - } - text->needs_split_into_lines = 1; - } - else { - text->needs_calc_height = 1; - } - needs_reflow = 1; - break; - - case PROP_ALLOW_NEWLINES: - text->allow_newlines = g_value_get_boolean (value); - _get_tep (text); - g_object_set ( - text->tep, - "allow_newlines", g_value_get_boolean (value), - NULL); - break; - - case PROP_CURSOR_POS: { - ETextEventProcessorCommand command; - - command.action = E_TEP_MOVE; - command.position = E_TEP_VALUE; - command.value = g_value_get_int (value); - command.time = GDK_CURRENT_TIME; - e_text_command (text->tep, &command, text); - break; - } - - case PROP_IM_CONTEXT: - if (text->im_context) { - disconnect_im_context (text); - g_object_unref (text->im_context); - } - - text->im_context = g_value_get_object (value); - if (text->im_context) - g_object_ref (text->im_context); - - text->need_im_reset = TRUE; - break; - - case PROP_HANDLE_POPUP: - text->handle_popup = g_value_get_boolean (value); - break; - - default: - return; - } - - if (needs_reflow) - e_canvas_item_request_reflow (item); - if (needs_update) - gnome_canvas_item_request_update (item); -} - -/* Get_arg handler for the text item */ -static void -e_text_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EText *text; - - text = E_TEXT (object); - - switch (property_id) { - case PROP_MODEL: - g_value_set_object (value, text->model); - break; - - case PROP_EVENT_PROCESSOR: - _get_tep (text); - g_value_set_object (value, text->tep); - break; - - case PROP_TEXT: - g_value_set_string (value, text->text); - break; - - case PROP_BOLD: - g_value_set_boolean (value, text->bold); - break; - - case PROP_STRIKEOUT: - g_value_set_boolean (value, text->strikeout); - break; - - case PROP_JUSTIFICATION: - g_value_set_enum (value, text->justification); - break; - - case PROP_CLIP_WIDTH: - g_value_set_double (value, text->clip_width); - break; - - case PROP_CLIP_HEIGHT: - g_value_set_double (value, text->clip_height); - break; - - case PROP_CLIP: - g_value_set_boolean (value, text->clip); - break; - - case PROP_FILL_CLIP_RECTANGLE: - g_value_set_boolean (value, text->fill_clip_rectangle); - break; - - case PROP_X_OFFSET: - g_value_set_double (value, text->xofs); - break; - - case PROP_Y_OFFSET: - g_value_set_double (value, text->yofs); - break; - - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, text->rgba); - break; - - case PROP_TEXT_WIDTH: - g_value_set_double (value, text->width); - break; - - case PROP_TEXT_HEIGHT: - g_value_set_double (value, text->height); - break; - - case PROP_EDITABLE: - g_value_set_boolean (value, text->editable); - break; - - case PROP_USE_ELLIPSIS: - g_value_set_boolean (value, text->use_ellipsis); - break; - - case PROP_ELLIPSIS: - g_value_set_string (value, text->ellipsis); - break; - - case PROP_LINE_WRAP: - g_value_set_boolean (value, text->line_wrap); - break; - - case PROP_BREAK_CHARACTERS: - g_value_set_string (value, text->break_characters); - break; - - case PROP_MAX_LINES: - g_value_set_int (value, text->max_lines); - break; - - case PROP_WIDTH: - g_value_set_double (value, text->clip_width); - break; - - case PROP_HEIGHT: - g_value_set_double ( - value, text->clip && - text->clip_height != -1 ? - text->clip_height : text->height); - break; - - case PROP_ALLOW_NEWLINES: - g_value_set_boolean (value, text->allow_newlines); - break; - - case PROP_CURSOR_POS: - g_value_set_int (value, text->selection_start); - break; - - case PROP_IM_CONTEXT: - g_value_set_object (value, text->im_context); - break; - - case PROP_HANDLE_POPUP: - g_value_set_boolean (value, text->handle_popup); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -/* Update handler for the text item */ -static void -e_text_reflow (GnomeCanvasItem *item, - gint flags) -{ - EText *text; - - text = E_TEXT (item); - - if (text->needs_reset_layout) { - reset_layout (text); - text->needs_reset_layout = 0; - text->needs_calc_height = 1; - } - - if (text->needs_split_into_lines) { - split_into_lines (text); - - text->needs_split_into_lines = 0; - text->needs_calc_height = 1; - } - - if (text->needs_calc_height) { - calc_height (text); - gnome_canvas_item_request_update (item); - text->needs_calc_height = 0; - text->needs_recalc_bounds = 1; - } -} - -/* Update handler for the text item */ -static void -e_text_update (GnomeCanvasItem *item, - const cairo_matrix_t *i2c, - gint flags) -{ - EText *text; - gdouble x1, y1, x2, y2; - - text = E_TEXT (item); - - if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update) - GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update ( - item, i2c, flags); - - if (text->needs_recalc_bounds - || (flags & GNOME_CANVAS_UPDATE_AFFINE)) { - get_bounds (text, &x1, &y1, &x2, &y2); - if (item->x1 != x1 || - item->x2 != x2 || - item->y1 != y1 || - item->y2 != y2) { - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, - item->x2, item->y2); - item->x1 = x1; - item->y1 = y1; - item->x2 = x2; - item->y2 = y2; - text->needs_redraw = 1; - item->canvas->need_repick = TRUE; - } - if (!text->fill_clip_rectangle) - item->canvas->need_repick = TRUE; - text->needs_recalc_bounds = 0; - } - if (text->needs_redraw) { - gnome_canvas_request_redraw ( - item->canvas, item->x1, item->y1, item->x2, item->y2); - text->needs_redraw = 0; - } -} - -/* Realize handler for the text item */ -static void -e_text_realize (GnomeCanvasItem *item) -{ - EText *text; - - text = E_TEXT (item); - - if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->realize) (item); - - create_layout (text); - - text->i_cursor = gdk_cursor_new (GDK_XTERM); - text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); -} - -/* Unrealize handler for the text item */ -static void -e_text_unrealize (GnomeCanvasItem *item) -{ - EText *text; - - text = E_TEXT (item); - - g_object_unref (text->i_cursor); - text->i_cursor = NULL; - g_object_unref (text->default_cursor); - text->default_cursor = NULL; - - if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize) - (* GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize) (item); -} - -static void -_get_tep (EText *text) -{ - if (!text->tep) { - text->tep = e_text_event_processor_emacs_like_new (); - - text->tep_command_id = g_signal_connect ( - text->tep, "command", - G_CALLBACK (e_text_command), text); - } -} - -static void -draw_pango_rectangle (cairo_t *cr, - gint x1, - gint y1, - PangoRectangle rect) -{ - gint width = rect.width / PANGO_SCALE; - gint height = rect.height / PANGO_SCALE; - - if (width <= 0) - width = 1; - if (height <= 0) - height = 1; - - cairo_rectangle ( - cr, x1 + rect.x / PANGO_SCALE, - y1 + rect.y / PANGO_SCALE, width, height); - cairo_fill (cr); -} - -static gboolean -show_pango_rectangle (EText *text, - PangoRectangle rect) -{ - gint x1 = rect.x / PANGO_SCALE; - gint x2 = (rect.x + rect.width) / PANGO_SCALE; - - gint y1 = rect.y / PANGO_SCALE; - gint y2 = (rect.y + rect.height) / PANGO_SCALE; - - gint new_xofs_edit = text->xofs_edit; - gint new_yofs_edit = text->yofs_edit; - - gint clip_width, clip_height; - - clip_width = text->clip_width; - clip_height = text->clip_height; - - if (x1 < new_xofs_edit) - new_xofs_edit = x1; - - if (y1 < new_yofs_edit) - new_yofs_edit = y1; - - if (clip_width >= 0) { - if (2 + x2 - clip_width > new_xofs_edit) - new_xofs_edit = 2 + x2 - clip_width; - } else { - new_xofs_edit = 0; - } - - if (clip_height >= 0) { - if (y2 - clip_height > new_yofs_edit) - new_yofs_edit = y2 - clip_height; - } else { - new_yofs_edit = 0; - } - - if (new_xofs_edit < 0) - new_xofs_edit = 0; - if (new_yofs_edit < 0) - new_yofs_edit = 0; - - if (new_xofs_edit != text->xofs_edit || - new_yofs_edit != text->yofs_edit) { - text->xofs_edit = new_xofs_edit; - text->yofs_edit = new_yofs_edit; - return TRUE; - } - - return FALSE; -} - -/* Draw handler for the text item */ -static void -e_text_draw (GnomeCanvasItem *item, - cairo_t *cr, - gint x, - gint y, - gint width, - gint height) -{ - EText *text; - gint xpos, ypos; - GnomeCanvas *canvas; - GtkWidget *widget; - GtkStyle *style; - GtkStateType state; - - text = E_TEXT (item); - canvas = GNOME_CANVAS_ITEM (text)->canvas; - widget = GTK_WIDGET (canvas); - state = gtk_widget_get_state (widget); - style = gtk_widget_get_style (widget); - - cairo_save (cr); - - if (!text->rgba_set) { - gdk_cairo_set_source_color (cr, &style->fg[state]); - } else { - cairo_set_source_rgba ( - cr, - ((text->rgba >> 24) & 0xff) / 255.0, - ((text->rgba >> 16) & 0xff) / 255.0, - ((text->rgba >> 8) & 0xff) / 255.0, - ( text->rgba & 0xff) / 255.0); - } - - /* Insert preedit text only when im_context signals are connected & - * text->preedit_len is not zero */ - if (text->im_context_signals_registered && text->preedit_len) - insert_preedit_text (text); - - /* Need to reset the layout to cleanly clear the preedit buffer when - * typing in CJK & using backspace on the preedit */ - if (!text->preedit_len) - reset_layout (text); - - if (!pango_layout_get_text (text->layout)) { - cairo_restore (cr); - return; - } - - xpos = text->text_cx; - ypos = text->text_cy; - - xpos = xpos - x + text->xofs; - ypos = ypos - y + text->yofs; - - cairo_save (cr); - - if (text->clip) { - cairo_rectangle ( - cr, xpos, ypos, - text->clip_cwidth - text->xofs, - text->clip_cheight - text->yofs); - cairo_clip (cr); - } - - if (text->editing) { - xpos -= text->xofs_edit; - ypos -= text->yofs_edit; - } - - cairo_move_to (cr, xpos, ypos); - pango_cairo_show_layout (cr, text->layout); - - if (text->editing) { - if (text->selection_start != text->selection_end) { - cairo_region_t *clip_region = cairo_region_create (); - gint indices[2]; - GtkStateType state; - - state = GTK_STATE_ACTIVE; - - indices[0] = MIN ( - text->selection_start, - text->selection_end); - indices[1] = MAX ( - text->selection_start, - text->selection_end); - - /* convert these into byte indices */ - indices[0] = g_utf8_offset_to_pointer ( - text->text, indices[0]) - text->text; - indices[1] = g_utf8_offset_to_pointer ( - text->text, indices[1]) - text->text; - - clip_region = gdk_pango_layout_get_clip_region ( - text->layout, xpos, ypos, indices, 1); - gdk_cairo_region (cr, clip_region); - cairo_clip (cr); - cairo_region_destroy (clip_region); - - gdk_cairo_set_source_color (cr, &style->base[state]); - cairo_paint (cr); - - gdk_cairo_set_source_color (cr, &style->text[state]); - cairo_move_to (cr, xpos, ypos); - pango_cairo_show_layout (cr, text->layout); - } else { - if (text->show_cursor) { - PangoRectangle strong_pos, weak_pos; - gchar *offs; - - offs = g_utf8_offset_to_pointer ( - text->text, text->selection_start); - - pango_layout_get_cursor_pos ( - text->layout, offs - text->text + - text->preedit_len, &strong_pos, - &weak_pos); - draw_pango_rectangle (cr, xpos, ypos, strong_pos); - if (strong_pos.x != weak_pos.x || - strong_pos.y != weak_pos.y || - strong_pos.width != weak_pos.width || - strong_pos.height != weak_pos.height) - draw_pango_rectangle (cr, xpos, ypos, weak_pos); - } - } - } - - cairo_restore (cr); - cairo_restore (cr); -} - -/* Point handler for the text item */ -static GnomeCanvasItem * -e_text_point (GnomeCanvasItem *item, - gdouble x, - gdouble y, - gint cx, - gint cy) -{ - EText *text; - gdouble clip_width; - gdouble clip_height; - - text = E_TEXT (item); - - /* The idea is to build bounding rectangles for each of the lines of - * text (clipped by the clipping rectangle, if it is activated) and see - * whether the point is inside any of these. If it is, we are done. - * Otherwise, calculate the distance to the nearest rectangle. - */ - - if (text->clip_width < 0) - clip_width = text->width; - else - clip_width = text->clip_width; - - if (text->clip_height < 0) - clip_height = text->height; - else - clip_height = text->clip_height; - - if (cx < text->clip_cx || - cx > text->clip_cx + clip_width || - cy < text->clip_cy || - cy > text->clip_cy + clip_height) - return NULL; - - if (text->fill_clip_rectangle || !text->text || !*text->text) - return item; - - cx -= text->cx; - - if (pango_layout_xy_to_index (text->layout, cx, cy, NULL, NULL)) - return item; - - return NULL; -} - -/* Bounds handler for the text item */ -static void -e_text_bounds (GnomeCanvasItem *item, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2) -{ - EText *text; - gdouble width, height; - - text = E_TEXT (item); - - *x1 = 0; - *y1 = 0; - - width = text->width; - height = text->height; - - if (text->clip) { - if (text->clip_width >= 0) - width = text->clip_width; - if (text->clip_height >= 0) - height = text->clip_height; - } - - *x2 = *x1 + width; - *y2 = *y1 + height; -} - -static gint -get_position_from_xy (EText *text, - gint x, - gint y) -{ - gint index; - gint trailing; - - x -= text->xofs; - y -= text->yofs; - - if (text->editing) { - x += text->xofs_edit; - y += text->yofs_edit; - } - - x -= text->cx; - y -= text->cy; - - pango_layout_xy_to_index ( - text->layout, x * PANGO_SCALE, - y * PANGO_SCALE, &index, &trailing); - - return g_utf8_pointer_to_offset (text->text, text->text + index + trailing); -} - -#define SCROLL_WAIT_TIME 30000 - -static gboolean -_blink_scroll_timeout (gpointer data) -{ - EText *text = E_TEXT (data); - gulong current_time; - gboolean scroll = FALSE; - gboolean redraw = FALSE; - - g_timer_elapsed (text->timer, ¤t_time); - - if (text->scroll_start + SCROLL_WAIT_TIME > 1000000) { - if (current_time > text->scroll_start - (1000000 - SCROLL_WAIT_TIME) && - current_time < text->scroll_start) - scroll = TRUE; - } else { - if (current_time > text->scroll_start + SCROLL_WAIT_TIME || - current_time < text->scroll_start) - scroll = TRUE; - } - if (scroll && text->button_down && text->clip) { - gint old_xofs_edit = text->xofs_edit; - gint old_yofs_edit = text->yofs_edit; - - if (text->clip_cwidth >= 0 && - text->lastx - text->clip_cx > text->clip_cwidth && - text->xofs_edit < text->width - text->clip_cwidth) { - text->xofs_edit += 4; - if (text->xofs_edit > text->width - text->clip_cwidth + 1) - text->xofs_edit = text->width - text->clip_cwidth + 1; - } - if (text->lastx - text->clip_cx < 0 && - text->xofs_edit > 0) { - text->xofs_edit -= 4; - if (text->xofs_edit < 0) - text->xofs_edit = 0; - } - - if (text->clip_cheight >= 0 && - text->lasty - text->clip_cy > text->clip_cheight && - text->yofs_edit < text->height - text->clip_cheight) { - text->yofs_edit += 4; - if (text->yofs_edit > text->height - text->clip_cheight + 1) - text->yofs_edit = text->height - text->clip_cheight + 1; - } - if (text->lasty - text->clip_cy < 0 && - text->yofs_edit > 0) { - text->yofs_edit -= 4; - if (text->yofs_edit < 0) - text->yofs_edit = 0; - } - - if (old_xofs_edit != text->xofs_edit || - old_yofs_edit != text->yofs_edit) { - ETextEventProcessorEvent e_tep_event; - e_tep_event.type = GDK_MOTION_NOTIFY; - e_tep_event.motion.state = text->last_state; - e_tep_event.motion.time = 0; - e_tep_event.motion.position = - get_position_from_xy ( - text, text->lastx, text->lasty); - _get_tep (text); - e_text_event_processor_handle_event ( - text->tep, - &e_tep_event); - text->scroll_start = current_time; - redraw = TRUE; - } - } - - if (!((current_time / 500000) % 2)) { - if (!text->show_cursor) - redraw = TRUE; - text->show_cursor = TRUE; - } else { - if (text->show_cursor) - redraw = TRUE; - text->show_cursor = FALSE; - } - if (redraw) { - text->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (text)); - } - return TRUE; -} - -static void -start_editing (EText *text) -{ - if (text->editing) - return; - - e_text_reset_im_context (text); - - g_free (text->revert); - text->revert = g_strdup (text->text); - - text->editing = TRUE; - if (text->pointer_in) { - GdkWindow *window; - - window = gtk_widget_get_window ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas)); - - if (text->default_cursor_shown) { - gdk_window_set_cursor (window, text->i_cursor); - text->default_cursor_shown = FALSE; - } - } - text->select_by_word = FALSE; - text->xofs_edit = 0; - text->yofs_edit = 0; - if (text->timeout_id == 0) - text->timeout_id = g_timeout_add (10, _blink_scroll_timeout, text); - text->timer = g_timer_new (); - g_timer_elapsed (text->timer, &(text->scroll_start)); - g_timer_start (text->timer); -} - -void -e_text_stop_editing (EText *text) -{ - if (!text->editing) - return; - - g_free (text->revert); - text->revert = NULL; - - text->editing = FALSE; - if (!text->default_cursor_shown) { - GdkWindow *window; - - window = gtk_widget_get_window ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas)); - gdk_window_set_cursor (window, text->default_cursor); - text->default_cursor_shown = TRUE; - } - if (text->timer) { - g_timer_stop (text->timer); - g_timer_destroy (text->timer); - text->timer = NULL; - } - - text->need_im_reset = TRUE; - text->preedit_len = 0; - text->preedit_pos = 0; -} - -void -e_text_cancel_editing (EText *text) -{ - if (text->revert) - e_text_model_set_text (text->model, text->revert); - e_text_stop_editing (text); -} - -static gboolean -_click (gpointer data) -{ - *(gint *)data = 0; - return FALSE; -} - -static gint -e_text_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - EText *text = E_TEXT (item); - ETextEventProcessorEvent e_tep_event; - GdkWindow *window; - gint return_val = 0; - - if (!text->model) - return 0; - - window = gtk_widget_get_window (GTK_WIDGET (item->canvas)); - - e_tep_event.type = event->type; - switch (event->type) { - case GDK_FOCUS_CHANGE: - if (text->editable) { - GdkEventFocus *focus_event; - focus_event = (GdkEventFocus *) event; - if (focus_event->in) { - if (text->im_context) { - if (!text->im_context_signals_registered) { - g_signal_connect ( - text->im_context, "commit", - G_CALLBACK (e_text_commit_cb), text); - g_signal_connect ( - text->im_context, "preedit_changed", - G_CALLBACK (e_text_preedit_changed_cb), text); - g_signal_connect ( - text->im_context, "retrieve_surrounding", - G_CALLBACK (e_text_retrieve_surrounding_cb), text); - g_signal_connect ( - text->im_context, "delete_surrounding", - G_CALLBACK (e_text_delete_surrounding_cb), text); - text->im_context_signals_registered = TRUE; - } - gtk_im_context_focus_in (text->im_context); - } - - start_editing (text); - - /* So we'll redraw and the - * cursor will be shown. */ - text->show_cursor = FALSE; - } else { - if (text->im_context) { - gtk_im_context_focus_out (text->im_context); - disconnect_im_context (text); - text->need_im_reset = TRUE; - } - - e_text_stop_editing (text); - if (text->timeout_id) { - g_source_remove (text->timeout_id); - text->timeout_id = 0; - } - if (text->show_cursor) { - text->show_cursor = FALSE; - text->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (text)); - } - } - if (text->line_wrap) - text->needs_split_into_lines = 1; - e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (text)); - } - return_val = 0; - break; - case GDK_KEY_PRESS: - - /* Handle S-F10 key binding here. */ - - if (event->key.keyval == GDK_KEY_F10 - && (event->key.state & GDK_SHIFT_MASK) - && text->handle_popup) { - - /* Simulate a GdkEventButton here, so that we can - * call e_text_do_popup directly */ - - GdkEvent *button_event; - - button_event = gdk_event_new (GDK_BUTTON_PRESS); - button_event->button.time = event->key.time; - button_event->button.button = 0; - e_text_do_popup (text, button_event, 0); - return 1; - } - - /* Fall Through */ - - case GDK_KEY_RELEASE: - - if (text->editing) { - GdkEventKey key; - gint ret; - - if (text->im_context && - gtk_im_context_filter_keypress ( - text->im_context, - (GdkEventKey *) event)) { - text->need_im_reset = TRUE; - return 1; - } - - key = event->key; - e_tep_event.key.time = key.time; - e_tep_event.key.state = key.state; - e_tep_event.key.keyval = key.keyval; - - /* This is probably ugly hack, but we - * have to handle UTF-8 input somehow. */ - e_tep_event.key.string = e_utf8_from_gtk_event_key ( - GTK_WIDGET (item->canvas), - key.keyval, key.string); - if (e_tep_event.key.string != NULL) { - e_tep_event.key.length = strlen (e_tep_event.key.string); - } else { - e_tep_event.key.length = 0; - } - - _get_tep (text); - ret = e_text_event_processor_handle_event (text->tep, &e_tep_event); - - if (event->type == GDK_KEY_PRESS) - g_signal_emit ( - text, e_text_signals[E_TEXT_KEYPRESS], 0, - e_tep_event.key.keyval, e_tep_event.key.state); - - if (e_tep_event.key.string) - g_free ((gpointer) e_tep_event.key.string); - - return ret; - } - break; - case GDK_BUTTON_PRESS: /* Fall Through */ - case GDK_BUTTON_RELEASE: - if ((!text->editing) - && text->editable - && (event->button.button == 1 || - event->button.button == 2)) { - e_canvas_item_grab_focus (item, TRUE); - start_editing (text); - } - - /* We follow convention and emit popup events on right-clicks. */ - if (event->type == GDK_BUTTON_PRESS && event->button.button == 3) { - if (text->handle_popup) { - e_text_do_popup ( - text, event, - get_position_from_xy ( - text, event->button.x, - event->button.y)); - return 1; - } - else { - break; - } - } - - /* Create our own double and triple click events, - * as gnome-canvas doesn't forward them to us */ - if (event->type == GDK_BUTTON_PRESS) { - if (text->dbl_timeout == 0 && - text->tpl_timeout == 0) { - text->dbl_timeout = g_timeout_add ( - 200, _click, &(text->dbl_timeout)); - } else { - if (text->tpl_timeout == 0) { - e_tep_event.type = GDK_2BUTTON_PRESS; - text->tpl_timeout = g_timeout_add ( - 200, _click, &(text->tpl_timeout)); - } else { - e_tep_event.type = GDK_3BUTTON_PRESS; - } - } - } - - if (text->editing) { - GdkEventButton button = event->button; - e_tep_event.button.time = button.time; - e_tep_event.button.state = button.state; - e_tep_event.button.button = button.button; - e_tep_event.button.position = - get_position_from_xy ( - text, button.x, button.y); - e_tep_event.button.device = - gdk_event_get_device (event); - _get_tep (text); - return_val = e_text_event_processor_handle_event ( - text->tep, &e_tep_event); - if (event->button.button == 1) { - if (event->type == GDK_BUTTON_PRESS) - text->button_down = TRUE; - else - text->button_down = FALSE; - } - text->lastx = button.x; - text->lasty = button.y; - text->last_state = button.state; - } - break; - case GDK_MOTION_NOTIFY: - if (text->editing) { - GdkEventMotion motion = event->motion; - e_tep_event.motion.time = motion.time; - e_tep_event.motion.state = motion.state; - e_tep_event.motion.position = - get_position_from_xy ( - text, motion.x, motion.y); - _get_tep (text); - return_val = e_text_event_processor_handle_event ( - text->tep, &e_tep_event); - text->lastx = motion.x; - text->lasty = motion.y; - text->last_state = motion.state; - } - break; - case GDK_ENTER_NOTIFY: - text->pointer_in = TRUE; - if (text->editing) { - if (text->default_cursor_shown) { - gdk_window_set_cursor (window, text->i_cursor); - text->default_cursor_shown = FALSE; - } - } - break; - case GDK_LEAVE_NOTIFY: - text->pointer_in = FALSE; - if (text->editing) { - if (!text->default_cursor_shown) { - gdk_window_set_cursor ( - window, text->default_cursor); - text->default_cursor_shown = TRUE; - } - } - break; - default: - break; - } - if (return_val) - return return_val; - if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->event) - return GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->event (item, event); - else - return 0; -} - -void -e_text_copy_clipboard (EText *text) -{ - gint selection_start_pos; - gint selection_end_pos; - - selection_start_pos = MIN (text->selection_start, text->selection_end); - selection_end_pos = MAX (text->selection_start, text->selection_end); - - /* convert sel_start/sel_end to byte indices */ - selection_start_pos = g_utf8_offset_to_pointer ( - text->text, selection_start_pos) - text->text; - selection_end_pos = g_utf8_offset_to_pointer ( - text->text, selection_end_pos) - text->text; - - gtk_clipboard_set_text ( - gtk_widget_get_clipboard ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - GDK_SELECTION_CLIPBOARD), - text->text + selection_start_pos, - selection_end_pos - selection_start_pos); -} - -void -e_text_delete_selection (EText *text) -{ - gint sel_start, sel_end; - - sel_start = MIN (text->selection_start, text->selection_end); - sel_end = MAX (text->selection_start, text->selection_end); - - if (sel_start != sel_end) - e_text_model_delete (text->model, sel_start, sel_end - sel_start); - text->need_im_reset = TRUE; -} - -void -e_text_cut_clipboard (EText *text) -{ - e_text_copy_clipboard (text); - e_text_delete_selection (text); -} - -void -e_text_paste_clipboard (EText *text) -{ - ETextEventProcessorCommand command; - - command.action = E_TEP_PASTE; - command.position = E_TEP_SELECTION; - command.string = ""; - command.value = 0; - e_text_command (text->tep, &command, text); -} - -void -e_text_select_all (EText *text) -{ - ETextEventProcessorCommand command; - - command.action = E_TEP_SELECT; - command.position = E_TEP_SELECT_ALL; - command.string = ""; - command.value = 0; - e_text_command (text->tep, &command, text); -} - -static void -primary_get_cb (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - guint info, - gpointer data) -{ - EText *text = E_TEXT (data); - gint sel_start, sel_end; - - sel_start = MIN (text->selection_start, text->selection_end); - sel_end = MAX (text->selection_start, text->selection_end); - - /* convert sel_start/sel_end to byte indices */ - sel_start = g_utf8_offset_to_pointer (text->text, sel_start) - text->text; - sel_end = g_utf8_offset_to_pointer (text->text, sel_end) - text->text; - - if (sel_start != sel_end) { - gtk_selection_data_set_text ( - selection_data, - text->text + sel_start, - sel_end - sel_start); - } -} - -static void -primary_clear_cb (GtkClipboard *clipboard, - gpointer data) -{ -#ifdef notyet - /* XXX */ - gtk_editable_select_region ( - GTK_EDITABLE (entry), entry->current_pos, entry->current_pos); -#endif -} - -static void -e_text_update_primary_selection (EText *text) -{ - static const GtkTargetEntry targets[] = { - { (gchar *) "UTF8_STRING", 0, 0 }, - { (gchar *) "UTF-8", 0, 0 }, - { (gchar *) "STRING", 0, 0 }, - { (gchar *) "TEXT", 0, 0 }, - { (gchar *) "COMPOUND_TEXT", 0, 0 } - }; - GtkClipboard *clipboard; - - clipboard = gtk_widget_get_clipboard ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - GDK_SELECTION_PRIMARY); - - if (text->selection_start != text->selection_end) { - if (!gtk_clipboard_set_with_owner ( - clipboard, targets, G_N_ELEMENTS (targets), - primary_get_cb, primary_clear_cb, G_OBJECT (text))) - primary_clear_cb (clipboard, text); - } else { - if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (text)) - gtk_clipboard_clear (clipboard); - } -} - -static void -paste_received (GtkClipboard *clipboard, - const gchar *text, - gpointer data) -{ - EText *etext = E_TEXT (data); - - if (text && g_utf8_validate (text, strlen (text), NULL)) { - if (etext->selection_end != etext->selection_start) - e_text_delete_selection (etext); - - e_text_insert (etext, text); - } - - g_object_unref (etext); -} - -static void -e_text_paste (EText *text, - GdkAtom selection) -{ - g_object_ref (text); - gtk_clipboard_request_text ( - gtk_widget_get_clipboard ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - selection), paste_received, text); -} - -typedef struct { - EText *text; - GdkEvent *event; - gint position; -} PopupClosure; - -static void -popup_menu_detach (GtkWidget *attach_widget, - GtkMenu *menu) -{ -} - -static void -popup_menu_placement_cb (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) -{ - EText *text = E_TEXT (user_data); - GnomeCanvasItem *item = &text->item; - GnomeCanvas *parent = item->canvas; - - if (parent) { - GdkWindow *window; - - window = gtk_widget_get_window (GTK_WIDGET (parent)); - gdk_window_get_origin (window, x, y); - *x += item->x1 + text->width / 2; - *y += item->y1 + text->height / 2; - } - - return; -} - -static void -popup_targets_received (GtkClipboard *clipboard, - GtkSelectionData *data, - gpointer user_data) -{ - PopupClosure *closure = user_data; - EText *text = closure->text; - GdkEvent *event = closure->event; - gint position = closure->position; - GtkWidget *popup_menu = gtk_menu_new (); - GtkWidget *menuitem, *submenu; - guint event_button = 0; - guint32 event_time; - - gdk_event_get_button (event, &event_button); - event_time = gdk_event_get_time (event); - - g_free (closure); - - gtk_menu_attach_to_widget ( - GTK_MENU (popup_menu), - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - popup_menu_detach); - - /* cut menu item */ - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL); - gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - g_signal_connect_swapped ( - menuitem, "activate", - G_CALLBACK (e_text_cut_clipboard), text); - gtk_widget_set_sensitive ( - menuitem, text->editable && - (text->selection_start != text->selection_end)); - - /* copy menu item */ - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL); - gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - g_signal_connect_swapped ( - menuitem, "activate", - G_CALLBACK (e_text_copy_clipboard), text); - gtk_widget_set_sensitive (menuitem, text->selection_start != text->selection_end); - - /* paste menu item */ - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL); - gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - g_signal_connect_swapped ( - menuitem, "activate", - G_CALLBACK (e_text_paste_clipboard), text); - gtk_widget_set_sensitive ( - menuitem, text->editable && - gtk_selection_data_targets_include_text (data)); - - menuitem = gtk_menu_item_new_with_label (_("Select All")); - gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - g_signal_connect_swapped ( - menuitem, "activate", - G_CALLBACK (e_text_select_all), text); - gtk_widget_set_sensitive (menuitem, strlen (text->text) > 0); - - menuitem = gtk_separator_menu_item_new (); - gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - - if (text->im_context && GTK_IS_IM_MULTICONTEXT (text->im_context)) { - menuitem = gtk_menu_item_new_with_label (_("Input Methods")); - gtk_widget_show (menuitem); - submenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); - - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menuitem); - - gtk_im_multicontext_append_menuitems ( - GTK_IM_MULTICONTEXT (text->im_context), - GTK_MENU_SHELL (submenu)); - } - - g_signal_emit ( - text, - e_text_signals[E_TEXT_POPULATE_POPUP], - 0, - event, - position, - popup_menu); - - /* If invoked by S-F10 key binding, button will be 0. */ - if (event_button == 0) { - gtk_menu_popup ( - GTK_MENU (popup_menu), NULL, NULL, - popup_menu_placement_cb, (gpointer) text, - event_button, GDK_CURRENT_TIME); - } else { - gtk_menu_popup ( - GTK_MENU (popup_menu), NULL, NULL, - NULL, NULL, - event_button, event_time); - } - - g_object_unref (text); - gdk_event_free (event); -} - -static void -e_text_do_popup (EText *text, - GdkEvent *button_event, - gint position) -{ - PopupClosure *closure = g_new (PopupClosure, 1); - - closure->text = g_object_ref (text); - closure->event = gdk_event_copy (button_event); - closure->position = position; - - gtk_clipboard_request_contents ( - gtk_widget_get_clipboard ( - GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), - GDK_SELECTION_CLIPBOARD), - gdk_atom_intern ("TARGETS", FALSE), - popup_targets_received, - closure); -} - -static void -e_text_reset_im_context (EText *text) -{ - if (text->need_im_reset && text->im_context) { - text->need_im_reset = FALSE; - gtk_im_context_reset (text->im_context); - } -} - -/* fixme: */ - -static gint -next_word (EText *text, - gint start) -{ - gchar *p = g_utf8_offset_to_pointer (text->text, start); - gint length; - - length = g_utf8_strlen (text->text, -1); - - if (start >= length) { - return length; - } else { - p = g_utf8_next_char (p); - start++; - - while (p && *p) { - gunichar unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - return start + 1; - } - else { - p = g_utf8_next_char (p); - start++; - } - } - } - - return g_utf8_pointer_to_offset (text->text, p); -} - -static gint -find_offset_into_line (EText *text, - gint offset_into_text, - gchar **start_of_line) -{ - gchar *p; - - p = g_utf8_offset_to_pointer (text->text, offset_into_text); - - if (p == text->text) { - if (start_of_line) - *start_of_line = (gchar *)text->text; - return 0; - } - else { - p = g_utf8_find_prev_char (text->text, p); - - while (p && p > text->text) { - if (*p == '\n') { - if (start_of_line) - *start_of_line = p+1; - return offset_into_text - - g_utf8_pointer_to_offset ( - text->text, p + 1); - } - p = g_utf8_find_prev_char (text->text, p); - } - - if (start_of_line) - *start_of_line = (gchar *)text->text; - return offset_into_text; - } -} - -/* direction = TRUE (move forward), FALSE (move backward) - * Any error shall return length (text->text) or 0 or - * text->selection_end (as deemed fit) */ -static gint -_get_updated_position (EText *text, - gboolean direction) -{ - PangoLogAttr *log_attrs = NULL; - gint n_attrs; - gchar *p = NULL; - gint new_pos = 0; - gint length = 0; - - /* Basic sanity test, return whatever position we are currently at. */ - g_return_val_if_fail (text->layout != NULL, text->selection_end); - - length = g_utf8_strlen (text->text, -1); - - /* length checks to make sure we are not wandering - * off into nonexistant memory... */ - if ((text->selection_end >= length) && (TRUE == direction)) /* forward */ - return length; - /* checking for -ve value wont hurt! */ - if ((text->selection_end <= 0) && (FALSE == direction)) /* backward */ - return 0; - - /* check for validness of full text->text */ - if (!g_utf8_validate (text->text, -1, NULL)) - return text->selection_end; - - /* get layout's PangoLogAttr to facilitate moving when - * moving across grapheme cluster as in indic langs */ - pango_layout_get_log_attrs (text->layout, &log_attrs, &n_attrs); - - /* Fetch the current gchar index in the line & keep moving - * forward until we can display cursor */ - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - - new_pos = text->selection_end; - while (1) - { - /* check before moving forward/backwards - * if we have more chars to move or not */ - if (TRUE == direction) - p = g_utf8_next_char (p); - else - p = g_utf8_prev_char (p); - - /* validate the new string & return with original position if check fails */ - if (!g_utf8_validate (p, -1, NULL)) - break; /* will return old value of new_pos */ - - new_pos = g_utf8_pointer_to_offset (text->text, p); - - /* if is_cursor_position is set, cursor can appear in front of character. - * i.e. this is a grapheme boundary AND make some sanity checks */ - if ((new_pos >=0) && (new_pos < n_attrs) && - (log_attrs[new_pos].is_cursor_position)) - break; - else if ((new_pos < 0) || (new_pos >= n_attrs)) - { - new_pos = text->selection_end; - break; - } - } - - if (log_attrs) - g_free (log_attrs); - - return new_pos; -} - -static gint -_get_position (EText *text, - ETextEventProcessorCommand *command) -{ - gint length, obj_num; - gunichar unival; - gchar *p = NULL; - gint new_pos = 0; - - switch (command->position) { - - case E_TEP_VALUE: - new_pos = command->value; - break; - - case E_TEP_SELECTION: - new_pos = text->selection_end; - break; - - case E_TEP_START_OF_BUFFER: - new_pos = 0; - break; - - case E_TEP_END_OF_BUFFER: - new_pos = strlen (text->text); - break; - - case E_TEP_START_OF_LINE: - - if (text->selection_end >= 1) { - - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - if (p != text->text) { - p = g_utf8_find_prev_char (text->text, p); - while (p && p > text->text) { - if (*p == '\n') { - new_pos = g_utf8_pointer_to_offset (text->text, p) + 1; - break; - } - p = g_utf8_find_prev_char (text->text, p); - } - } - } - - break; - - case E_TEP_END_OF_LINE: - new_pos = -1; - length = g_utf8_strlen (text->text, -1); - - if (text->selection_end >= length) { - new_pos = length; - } else { - - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - - while (p && *p) { - if (*p == '\n') { - new_pos = g_utf8_pointer_to_offset (text->text, p); - p = NULL; - } else - p = g_utf8_next_char (p); - } - } - - if (new_pos == -1) - new_pos = g_utf8_pointer_to_offset (text->text, p); - - break; - - case E_TEP_FORWARD_CHARACTER: - length = g_utf8_strlen (text->text, -1); - - if (text->selection_end >= length) - new_pos = length; - else - /* get updated position to display cursor */ - new_pos = _get_updated_position (text, TRUE); - - break; - - case E_TEP_BACKWARD_CHARACTER: - new_pos = 0; - if (text->selection_end >= 1) - /* get updated position to display cursor */ - new_pos = _get_updated_position (text, FALSE); - - break; - - case E_TEP_FORWARD_WORD: - new_pos = next_word (text, text->selection_end); - break; - - case E_TEP_BACKWARD_WORD: - new_pos = 0; - if (text->selection_end >= 1) { - gint pos = text->selection_end; - - p = g_utf8_find_prev_char ( - text->text, g_utf8_offset_to_pointer ( - text->text, text->selection_end)); - pos--; - - if (p != text->text) { - p = g_utf8_find_prev_char (text->text, p); - pos--; - - while (p && p > text->text) { - unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - new_pos = pos + 1; - p = NULL; - } - else { - p = g_utf8_find_prev_char (text->text, p); - pos--; - } - } - } - } - - break; - - case E_TEP_FORWARD_LINE: { - gint offset_into_line; - - offset_into_line = find_offset_into_line (text, text->selection_end, NULL); - if (offset_into_line == -1) - return text->selection_end; - - /* now we search forward til we hit a \n, and then - * offset_into_line more characters */ - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - while (p && *p) { - if (*p == '\n') - break; - p = g_utf8_next_char (p); - } - if (p && *p == '\n') { - /* now we loop forward offset_into_line - * characters, or until we hit \n or \0 */ - - p = g_utf8_next_char (p); - while (offset_into_line > 0 && p && *p != '\n' && *p != '\0') { - p = g_utf8_next_char (p); - offset_into_line--; - } - } - - /* at this point, p points to the new location, - * convert it to an offset and we're done */ - new_pos = g_utf8_pointer_to_offset (text->text, p); - break; - } - case E_TEP_BACKWARD_LINE: { - gint offset_into_line; - - offset_into_line = find_offset_into_line ( - text, text->selection_end, &p); - - if (offset_into_line == -1) - return text->selection_end; - - /* p points to the first character on our line. if we - * have a \n before it, skip it and scan til we hit - * the next one */ - if (p != text->text) { - p = g_utf8_find_prev_char (text->text, p); - if (*p == '\n') { - p = g_utf8_find_prev_char (text->text, p); - while (p > text->text) { - if (*p == '\n') { - p++; - break; - } - p = g_utf8_find_prev_char (text->text, p); - } - } - } - - /* at this point 'p' points to the start of the - * previous line, move forward 'offset_into_line' - * times. */ - - while (offset_into_line > 0 && p && *p != '\n' && *p != '\0') { - p = g_utf8_next_char (p); - offset_into_line--; - } - - /* at this point, p points to the new location, - * convert it to an offset and we're done */ - new_pos = g_utf8_pointer_to_offset (text->text, p); - break; - } - case E_TEP_SELECT_WORD: - /* This is a silly hack to cause double-clicking on an object - * to activate that object. - * (Normally, double click == select word, which is why this is here.) */ - - obj_num = e_text_model_get_object_at_offset ( - text->model, text->selection_start); - if (obj_num != -1) { - e_text_model_activate_nth_object (text->model, obj_num); - new_pos = text->selection_start; - break; - } - - if (text->selection_end < 1) { - new_pos = 0; - break; - } - - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - - p = g_utf8_find_prev_char (text->text, p); - - while (p && p > text->text) { - unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - p = g_utf8_next_char (p); - break; - } - p = g_utf8_find_prev_char (text->text, p); - } - - if (!p) - text->selection_start = 0; - else - text->selection_start = g_utf8_pointer_to_offset (text->text, p); - - text->selection_start = - e_text_model_validate_position ( - text->model, text->selection_start); - - length = g_utf8_strlen (text->text, -1); - if (text->selection_end >= length) { - new_pos = length; - break; - } - - p = g_utf8_offset_to_pointer (text->text, text->selection_end); - while (p && *p) { - unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - new_pos = g_utf8_pointer_to_offset (text->text, p); - break; - } else - p = g_utf8_next_char (p); - } - - if (!new_pos) - new_pos = g_utf8_strlen (text->text, -1); - - return new_pos; - - case E_TEP_SELECT_ALL: - text->selection_start = 0; - new_pos = g_utf8_strlen (text->text, -1); - break; - - case E_TEP_FORWARD_PARAGRAPH: - case E_TEP_BACKWARD_PARAGRAPH: - - case E_TEP_FORWARD_PAGE: - case E_TEP_BACKWARD_PAGE: - new_pos = text->selection_end; - break; - - default: - new_pos = text->selection_end; - break; - } - - new_pos = e_text_model_validate_position (text->model, new_pos); - - return new_pos; -} - -static void -e_text_insert (EText *text, - const gchar *string) -{ - gint len = strlen (string); - - if (len > 0) { - gint utf8len = 0; - - if (!text->allow_newlines) { - const gchar *i; - gchar *new_string = g_malloc (len + 1); - gchar *j = new_string; - - for (i = string; *i; i = g_utf8_next_char (i)) { - if (*i != '\n') { - gunichar c; - gint charlen; - - c = g_utf8_get_char (i); - charlen = g_unichar_to_utf8 (c, j); - j += charlen; - utf8len++; - } - } - *j = 0; - e_text_model_insert_length ( - text->model, text->selection_start, - new_string, utf8len); - g_free (new_string); - } - else { - utf8len = g_utf8_strlen (string, -1); - e_text_model_insert_length ( - text->model, text->selection_start, - string, utf8len); - } - } -} - -static void -capitalize (EText *text, - gint start, - gint end, - ETextEventProcessorCaps type) -{ - gboolean first = TRUE; - const gchar *p = g_utf8_offset_to_pointer (text->text, start); - const gchar *text_end = g_utf8_offset_to_pointer (text->text, end); - gint utf8len = text_end - p; - - if (utf8len > 0) { - gchar *new_text = g_new0 (char, utf8len * 6); - gchar *output = new_text; - - while (p && *p && p < text_end) { - gunichar unival = g_utf8_get_char (p); - gunichar newval = unival; - - switch (type) { - case E_TEP_CAPS_UPPER: - newval = g_unichar_toupper (unival); - break; - case E_TEP_CAPS_LOWER: - newval = g_unichar_tolower (unival); - break; - case E_TEP_CAPS_TITLE: - if (g_unichar_isalpha (unival)) { - if (first) - newval = g_unichar_totitle (unival); - else - newval = g_unichar_tolower (unival); - first = FALSE; - } else { - first = TRUE; - } - break; - } - g_unichar_to_utf8 (newval, output); - output = g_utf8_next_char (output); - - p = g_utf8_next_char (p); - } - *output = 0; - - e_text_model_delete (text->model, start, utf8len); - e_text_model_insert_length (text->model, start, new_text, utf8len); - g_free (new_text); - } -} - -static void -e_text_command (ETextEventProcessor *tep, - ETextEventProcessorCommand *command, - gpointer data) -{ - EText *text = E_TEXT (data); - gboolean scroll = TRUE; - gboolean use_start = TRUE; - - switch (command->action) { - case E_TEP_MOVE: - text->selection_start = _get_position (text, command); - text->selection_end = text->selection_start; - if (text->timer) { - g_timer_reset (text->timer); - } - - text->need_im_reset = TRUE; - use_start = TRUE; - break; - case E_TEP_SELECT: - text->selection_start = - e_text_model_validate_position ( - text->model, text->selection_start); /* paranoia */ - text->selection_end = _get_position (text, command); - - e_text_update_primary_selection (text); - - text->need_im_reset = TRUE; - use_start = FALSE; - - break; - case E_TEP_DELETE: - if (text->selection_end == text->selection_start) { - text->selection_end = _get_position (text, command); - } - e_text_delete_selection (text); - if (text->timer) { - g_timer_reset (text->timer); - } - - text->need_im_reset = TRUE; - use_start = FALSE; - - break; - - case E_TEP_INSERT: - if (g_utf8_validate (command->string, command->value, NULL)) { - if (text->selection_end != text->selection_start) { - e_text_delete_selection (text); - } - e_text_insert (text, command->string); - if (text->timer) { - g_timer_reset (text->timer); - } - text->need_im_reset = TRUE; - } - break; - case E_TEP_COPY: - e_text_copy_clipboard (text); - - if (text->timer) { - g_timer_reset (text->timer); - } - scroll = FALSE; - break; - case E_TEP_PASTE: - e_text_paste (text, GDK_NONE); - if (text->timer) { - g_timer_reset (text->timer); - } - text->need_im_reset = TRUE; - break; - case E_TEP_GET_SELECTION: - e_text_paste (text, GDK_SELECTION_PRIMARY); - break; - case E_TEP_ACTIVATE: - g_signal_emit (text, e_text_signals[E_TEXT_ACTIVATE], 0); - if (text->timer) { - g_timer_reset (text->timer); - } - break; - case E_TEP_SET_SELECT_BY_WORD: - text->select_by_word = command->value; - break; - case E_TEP_GRAB: - e_canvas_item_grab ( - E_CANVAS (GNOME_CANVAS_ITEM (text)->canvas), - GNOME_CANVAS_ITEM (text), - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - text->i_cursor, - command->device, - command->time, - NULL, - NULL); - scroll = FALSE; - break; - case E_TEP_UNGRAB: - e_canvas_item_ungrab ( - E_CANVAS (GNOME_CANVAS_ITEM (text)->canvas), - GNOME_CANVAS_ITEM (text), - command->time); - scroll = FALSE; - break; - case E_TEP_CAPS: - if (text->selection_start == text->selection_end) { - capitalize ( - text, text->selection_start, - next_word (text, text->selection_start), - command->value); - } else { - gint selection_start = MIN ( - text->selection_start, text->selection_end); - gint selection_end = MAX ( - text->selection_start, text->selection_end); - capitalize ( - text, selection_start, - selection_end, command->value); - } - break; - case E_TEP_NOP: - scroll = FALSE; - break; - } - - e_text_reset_im_context (text); - - /* it's possible to get here without ever having been realized - * by our canvas (if the e-text started completely obscured.) - * so let's create our layout object if we don't already have - * one. */ - if (!text->layout) - create_layout (text); - - /* We move cursor only if scroll is TRUE */ - if (scroll && !text->button_down) { - /* XXX do we really need the @trailing logic here? if - * we don't we can scrap the loop and just use - * pango_layout_index_to_pos */ - PangoLayoutLine *cur_line = NULL; - gint selection_index; - PangoLayoutIter *iter = pango_layout_get_iter (text->layout); - - /* check if we are using selection_start or selection_end for moving? */ - selection_index = use_start ? text->selection_start : text->selection_end; - - /* convert to a byte index */ - selection_index = g_utf8_offset_to_pointer ( - text->text, selection_index) - text->text; - - do { - PangoLayoutLine *line = pango_layout_iter_get_line (iter); - - if (selection_index >= line->start_index && - selection_index <= line->start_index + line->length) { - /* found the line with the start of the selection */ - cur_line = line; - break; - } - - } while (pango_layout_iter_next_line (iter)); - - if (cur_line) { - gint xpos, ypos; - gdouble clip_width, clip_height; - /* gboolean trailing = FALSE; */ - PangoRectangle pango_pos; - - if (selection_index > 0 && selection_index == - cur_line->start_index + cur_line->length) { - selection_index--; - /* trailing = TRUE; */ - } - - pango_layout_index_to_pos (text->layout, selection_index, &pango_pos); - - pango_pos.x = PANGO_PIXELS (pango_pos.x); - pango_pos.y = PANGO_PIXELS (pango_pos.y); - pango_pos.width = (pango_pos.width + PANGO_SCALE / 2) / PANGO_SCALE; - pango_pos.height = (pango_pos.height + PANGO_SCALE / 2) / PANGO_SCALE; - - /* scroll for X */ - xpos = pango_pos.x; /* + (trailing ? 0 : pango_pos.width);*/ - - if (xpos + 2 < text->xofs_edit) { - text->xofs_edit = xpos; - } - - clip_width = text->clip_width; - - if (xpos + pango_pos.width - clip_width > text->xofs_edit) { - text->xofs_edit = xpos + pango_pos.width - clip_width; - } - - /* scroll for Y */ - if (pango_pos.y + 2 < text->yofs_edit) { - ypos = pango_pos.y; - text->yofs_edit = ypos; - } - else { - ypos = pango_pos.y + pango_pos.height; - } - - if (text->clip_height < 0) - clip_height = text->height; - else - clip_height = text->clip_height; - - if (ypos - clip_height > text->yofs_edit) { - text->yofs_edit = ypos - clip_height; - } - - } - - pango_layout_iter_free (iter); - } - - text->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (text)); -} - -/* Class initialization function for the text item */ -static void -e_text_class_init (ETextClass *class) -{ - GObjectClass *gobject_class; - GnomeCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gobject_class->dispose = e_text_dispose; - gobject_class->set_property = e_text_set_property; - gobject_class->get_property = e_text_get_property; - - item_class->update = e_text_update; - item_class->realize = e_text_realize; - item_class->unrealize = e_text_unrealize; - item_class->draw = e_text_draw; - item_class->point = e_text_point; - item_class->bounds = e_text_bounds; - item_class->event = e_text_event; - - class->changed = NULL; - class->activate = NULL; - - e_text_signals[E_TEXT_CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_text_signals[E_TEXT_ACTIVATE] = g_signal_new ( - "activate", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextClass, activate), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_text_signals[E_TEXT_KEYPRESS] = g_signal_new ( - "keypress", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextClass, keypress), - NULL, NULL, - e_marshal_NONE__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); - - e_text_signals[E_TEXT_POPULATE_POPUP] = g_signal_new ( - "populate_popup", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ETextClass, populate_popup), - NULL, NULL, - e_marshal_NONE__POINTER_INT_OBJECT, - G_TYPE_NONE, 3, - G_TYPE_POINTER, - G_TYPE_INT, - GTK_TYPE_MENU); - - g_object_class_install_property ( - gobject_class, - PROP_MODEL, - g_param_spec_object ( - "model", - "Model", - "Model", - E_TYPE_TEXT_MODEL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_EVENT_PROCESSOR, - g_param_spec_object ( - "event_processor", - "Event Processor", - "Event Processor", - E_TEXT_EVENT_PROCESSOR_TYPE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_TEXT, - g_param_spec_string ( - "text", - "Text", - "Text", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_BOLD, - g_param_spec_boolean ( - "bold", - "Bold", - "Bold", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_STRIKEOUT, - g_param_spec_boolean ( - "strikeout", - "Strikeout", - "Strikeout", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_JUSTIFICATION, - g_param_spec_enum ( - "justification", - "Justification", - "Justification", - GTK_TYPE_JUSTIFICATION, - GTK_JUSTIFY_LEFT, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_CLIP_WIDTH, - g_param_spec_double ( - "clip_width", - "Clip Width", - "Clip Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_CLIP_HEIGHT, - g_param_spec_double ( - "clip_height", - "Clip Height", - "Clip Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_CLIP, - g_param_spec_boolean ( - "clip", - "Clip", - "Clip", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_FILL_CLIP_RECTANGLE, - g_param_spec_boolean ( - "fill_clip_rectangle", - "Fill clip rectangle", - "Fill clip rectangle", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_X_OFFSET, - g_param_spec_double ( - "x_offset", - "X Offset", - "X Offset", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_Y_OFFSET, - g_param_spec_double ( - "y_offset", - "Y Offset", - "Y Offset", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_FILL_COLOR, - g_param_spec_string ( - "fill_color", - "Fill color", - "Fill color", - NULL, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - gobject_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ( - "fill_color_gdk", - "GDK fill color", - "GDK fill color", - GDK_TYPE_COLOR, - G_PARAM_WRITABLE)); - - g_object_class_install_property ( - gobject_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ( - "fill_color_rgba", - "GDK fill color", - "GDK fill color", - 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_TEXT_WIDTH, - g_param_spec_double ( - "text_width", - "Text width", - "Text width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - gobject_class, - PROP_TEXT_HEIGHT, - g_param_spec_double ( - "text_height", - "Text height", - "Text height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - g_object_class_install_property ( - gobject_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - "Editable", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_USE_ELLIPSIS, - g_param_spec_boolean ( - "use_ellipsis", - "Use ellipsis", - "Use ellipsis", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_ELLIPSIS, - g_param_spec_string ( - "ellipsis", - "Ellipsis", - "Ellipsis", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_LINE_WRAP, - g_param_spec_boolean ( - "line_wrap", - "Line wrap", - "Line wrap", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_BREAK_CHARACTERS, - g_param_spec_string ( - "break_characters", - "Break characters", - "Break characters", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, PROP_MAX_LINES, - g_param_spec_int ( - "max_lines", - "Max lines", - "Max lines", - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_WIDTH, - g_param_spec_double ( - "width", - "Width", - "Width", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_HEIGHT, - g_param_spec_double ( - "height", - "Height", - "Height", - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_ALLOW_NEWLINES, - g_param_spec_boolean ( - "allow_newlines", - "Allow newlines", - "Allow newlines", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_CURSOR_POS, - g_param_spec_int ( - "cursor_pos", - "Cursor position", - "Cursor position", - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_IM_CONTEXT, - g_param_spec_object ( - "im_context", - "IM Context", - "IM Context", - GTK_TYPE_IM_CONTEXT, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - gobject_class, - PROP_HANDLE_POPUP, - g_param_spec_boolean ( - "handle_popup", - "Handle Popup", - "Handle Popup", - FALSE, - G_PARAM_READWRITE)); - - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - - gal_a11y_e_text_init (); -} - -/* Object initialization function for the text item */ -static void -e_text_init (EText *text) -{ - text->model = e_text_model_new (); - text->text = e_text_model_get_text (text->model); - text->preedit_len = 0; - text->preedit_pos = 0; - text->layout = NULL; - - text->revert = NULL; - - text->model_changed_signal_id = g_signal_connect ( - text->model, "changed", - G_CALLBACK (e_text_text_model_changed), text); - - text->model_repos_signal_id = g_signal_connect ( - text->model, "reposition", - G_CALLBACK (e_text_text_model_reposition), text); - - text->justification = GTK_JUSTIFY_LEFT; - text->clip_width = -1.0; - text->clip_height = -1.0; - text->xofs = 0.0; - text->yofs = 0.0; - - text->ellipsis = NULL; - text->use_ellipsis = FALSE; - text->ellipsis_width = 0; - - text->editable = FALSE; - text->editing = FALSE; - text->xofs_edit = 0; - text->yofs_edit = 0; - - text->selection_start = 0; - text->selection_end = 0; - text->select_by_word = FALSE; - - text->timeout_id = 0; - text->timer = NULL; - - text->lastx = 0; - text->lasty = 0; - text->last_state = 0; - - text->scroll_start = 0; - text->show_cursor = TRUE; - text->button_down = FALSE; - - text->tep = NULL; - text->tep_command_id = 0; - - text->pointer_in = FALSE; - text->default_cursor_shown = TRUE; - text->line_wrap = FALSE; - text->break_characters = NULL; - text->max_lines = -1; - text->dbl_timeout = 0; - text->tpl_timeout = 0; - - text->bold = FALSE; - text->strikeout = FALSE; - - text->allow_newlines = TRUE; - - text->last_type_request = -1; - text->last_time_request = 0; - text->queued_requests = NULL; - - text->im_context = NULL; - text->need_im_reset = FALSE; - text->im_context_signals_registered = FALSE; - - text->handle_popup = FALSE; - text->rgba_set = FALSE; - - e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (text), e_text_reflow); -} - -/* IM Context Callbacks */ -static void -e_text_commit_cb (GtkIMContext *context, - const gchar *str, - EText *text) -{ - if (g_utf8_validate (str, strlen (str), NULL)) { - if (text->selection_end != text->selection_start) - e_text_delete_selection (text); - e_text_insert (text, str); - g_signal_emit (text, e_text_signals[E_TEXT_KEYPRESS], 0, 0, 0); - } -} - -static void -e_text_preedit_changed_cb (GtkIMContext *context, - EText *etext) -{ - gchar *preedit_string = NULL; - gint cursor_pos; - - gtk_im_context_get_preedit_string ( - context, &preedit_string, - NULL, &cursor_pos); - - cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); - etext->preedit_len = strlen (preedit_string); - etext->preedit_pos = g_utf8_offset_to_pointer ( - preedit_string, cursor_pos) - preedit_string; - g_free (preedit_string); - - g_signal_emit (etext, e_text_signals[E_TEXT_KEYPRESS], 0, 0, 0); -} - -static gboolean -e_text_retrieve_surrounding_cb (GtkIMContext *context, - EText *text) -{ - gtk_im_context_set_surrounding ( - context, text->text, strlen (text->text), - g_utf8_offset_to_pointer (text->text, MIN ( - text->selection_start, text->selection_end)) - text->text); - - return TRUE; -} - -static gboolean -e_text_delete_surrounding_cb (GtkIMContext *context, - gint offset, - gint n_chars, - EText *text) -{ - e_text_model_delete ( - text->model, - MIN (text->selection_start, text->selection_end) + offset, - n_chars); - - return TRUE; -} diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h deleted file mode 100644 index b3099f1a64..0000000000 --- a/widgets/text/e-text.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * e-text.h - Text item for evolution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Jon Trowbridge <trow@ximian.com> - * - * A majority of code taken from: - * - * Text item type for GnomeCanvas widget - * - * GnomeCanvas is basically a port of the Tk toolkit's most excellent - * canvas widget. Tk is copyrighted by the Regents of the University - * of California, Sun Microsystems, and other parties. - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_TEXT_H -#define E_TEXT_H - -#include <gtk/gtk.h> - -#include <e-util/e-text-event-processor.h> -#include <text/e-text-model.h> -#include <misc/e-canvas.h> - -G_BEGIN_DECLS - -/* Text item for the canvas. Text items are positioned by an anchor point and an anchor direction. - * - * A clipping rectangle may be specified for the text. The rectangle is anchored at the text's anchor - * point, and is specified by clipping width and height parameters. If the clipping rectangle is - * enabled, it will clip the text. - * - * In addition, x and y offset values may be specified. These specify an offset from the anchor - * position. If used in conjunction with the clipping rectangle, these could be used to implement - * simple scrolling of the text within the clipping rectangle. - * - * The following object arguments are available: - * - * name type read/write description - * ------------------------------------------------------------------------------------------ - * text string RW The string of the text label - * bold boolean RW Bold? - * justification GtkJustification RW Justification for multiline text - * fill_color string W X color specification for text - * fill_color_gdk GdkColor* RW Pointer to an allocated GdkColor - * clip_width gdouble RW Width of clip rectangle - * clip_height gdouble RW Height of clip rectangle - * clip boolean RW Use clipping rectangle? - * fill_clip_rect boolean RW Whether the text item represents itself as being the size of the clipping rectangle. - * x_offset gdouble RW Horizontal offset distance from anchor position - * y_offset gdouble RW Vertical offset distance from anchor position - * text_width gdouble R Used to query the width of the rendered text - * text_height gdouble R Used to query the rendered height of the text - * width gdouble RW A synonym for clip_width - * height gdouble R A synonym for text_height - * - * These are currently ignored in the AA version: - * editable boolean RW Can this item be edited - * use_ellipsis boolean RW Whether to use ellipsises if text gets cut off. Meaningless if clip == false. - * ellipsis string RW The characters to use as ellipsis. NULL = "...". - * line_wrap boolean RW Line wrap when not editing. - * break_characters string RW List of characters to optionally break on. - * max_lines gint RW Number of lines possible when doing line wrap. - */ - -#define E_TYPE_TEXT (e_text_get_type ()) -#define E_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TEXT, EText)) -#define E_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TEXT, ETextClass)) -#define E_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TEXT)) -#define E_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_TEXT)) - -typedef struct _EText EText; -typedef struct _ETextClass ETextClass; - -struct _EText { - GnomeCanvasItem item; - - ETextModel *model; - gint model_changed_signal_id; - gint model_repos_signal_id; - - const gchar *text; /* Text to display --- from the ETextModel */ - gint preedit_len; /* preedit length to display */ - gint preedit_pos; /* preedit cursor position */ - PangoLayout *layout; - gint num_lines; /* Number of lines of text */ - - gchar *revert; /* Text to revert to */ - - GtkJustification justification; /* Justification for text */ - - gdouble clip_width; /* Width of optional clip rectangle */ - gdouble clip_height; /* Height of optional clip rectangle */ - - gdouble xofs, yofs; /* Text offset distance from anchor position */ - - gint cx, cy; /* Top-left canvas coordinates for text */ - gint text_cx, text_cy; /* Top-left canvas coordinates for text */ - gint clip_cx, clip_cy; /* Top-left canvas coordinates for clip rectangle */ - gint clip_cwidth, clip_cheight; /* Size of clip rectangle in pixels */ - gint max_width; /* Maximum width of text lines */ - gint width; /* Rendered text width in pixels */ - gint height; /* Rendered text height in pixels */ - - guint32 rgba; /* RGBA color for text */ - gboolean rgba_set; /* whether RGBA is set */ - - gchar *ellipsis; /* The ellipsis characters. NULL = "...". */ - gdouble ellipsis_width; /* The width of the ellipsis. */ - - gint xofs_edit; /* Offset because of editing */ - gint yofs_edit; /* Offset because of editing */ - - /* This needs to be reworked a bit once we get line wrapping. */ - gint selection_start; /* Start of selection IN BYTES */ - gint selection_end; /* End of selection IN BYTES */ - gboolean select_by_word; /* Current selection is by word */ - - /* This section is for drag scrolling and blinking cursor. */ - gint timeout_id; /* Current timeout id for scrolling */ - GTimer *timer; /* Timer for blinking cursor and scrolling */ - - gint lastx, lasty; /* Last x and y motion events */ - gint last_state; /* Last state */ - gulong scroll_start; /* Starting time for scroll (microseconds) */ - - gint show_cursor; /* Is cursor currently shown */ - gboolean button_down; /* Is mouse button 1 down */ - - ETextEventProcessor *tep; /* Text Event Processor */ - gint tep_command_id; - - gboolean has_selection; /* TRUE if we have the selection */ - - guint clip : 1; /* Use clip rectangle? */ - guint fill_clip_rectangle : 1; /* Fill the clipping rectangle. */ - - guint pointer_in : 1; /* Is the pointer currently over us? */ - guint default_cursor_shown : 1; /* Is the default cursor currently shown? */ - - guint line_wrap : 1; /* Do line wrap */ - - guint needs_redraw : 1; /* Needs redraw */ - guint needs_recalc_bounds : 1; /* Need recalc_bounds */ - guint needs_calc_height : 1; /* Need calc_height */ - guint needs_split_into_lines : 1; /* Needs split_into_lines */ - guint needs_reset_layout : 1; /* Needs split_into_lines */ - - guint bold : 1; - guint strikeout : 1; - - guint tooltip_owner : 1; - guint allow_newlines : 1; - - guint use_ellipsis : 1; /* Whether to use the ellipsis. */ - - guint editable : 1; /* Item is editable */ - guint editing : 1; /* Item is currently being edited */ - - gchar *break_characters; /* Characters to optionally break after */ - - gint max_lines; /* Max number of lines (-1 = infinite) */ - - GdkCursor *default_cursor; /* Default cursor (arrow) */ - GdkCursor *i_cursor; /* I beam cursor */ - - gint tooltip_timeout; /* Timeout for the tooltip */ - gint tooltip_count; /* GDK_ENTER_NOTIFY count. */ - - gint dbl_timeout; /* Double click timeout */ - gint tpl_timeout; /* Triple click timeout */ - - gint last_type_request; /* Last selection type requested. */ - guint32 last_time_request; /* The time of the last selection request. */ - GdkAtom last_selection_request; /* The time of the last selection request. */ - GList *queued_requests; /* Queued selection requests. */ - - GtkIMContext *im_context; - gboolean need_im_reset; - gboolean im_context_signals_registered; - - gboolean handle_popup; - - PangoFontDescription *font_desc; -}; - -struct _ETextClass { - GnomeCanvasItemClass parent_class; - - void (* changed) (EText *text); - void (* activate) (EText *text); - void (* keypress) (EText *text, guint keyval, guint state); - void (* populate_popup) (EText *text, GdkEvent *button_event, gint pos, GtkMenu *menu); - void (* style_set) (EText *text, GtkStyle *previous_style); -}; - -/* Standard Gtk function */ -GType e_text_get_type (void); -void e_text_cancel_editing (EText *text); -void e_text_stop_editing (EText *text); - -void e_text_delete_selection (EText *text); -void e_text_cut_clipboard (EText *text); -void e_text_copy_clipboard (EText *text); -void e_text_paste_clipboard (EText *text); -void e_text_select_all (EText *text); - -G_END_DECLS - -#endif diff --git a/widgets/text/gal-a11y-e-text-factory.c b/widgets/text/gal-a11y-e-text-factory.c deleted file mode 100644 index 8e33b38562..0000000000 --- a/widgets/text/gal-a11y-e-text-factory.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "text/e-text.h" -#include "gal-a11y-e-text-factory.h" -#include "gal-a11y-e-text.h" - -static AtkObjectFactoryClass *parent_class; -#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY) - -/* Static functions */ - -static GType -gal_a11y_e_text_factory_get_accessible_type (void) -{ - return GAL_A11Y_TYPE_E_TEXT; -} - -static AtkObject * -gal_a11y_e_text_factory_create_accessible (GObject *obj) -{ - AtkObject *atk_object; - - g_return_val_if_fail (E_IS_TEXT (obj), NULL); - - atk_object = g_object_new (GAL_A11Y_TYPE_E_TEXT, NULL); - atk_object_initialize (atk_object, obj); - - return atk_object; -} - -static void -gal_a11y_e_text_factory_class_init (GalA11yETextFactoryClass *class) -{ - AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (class); - - parent_class = g_type_class_ref (PARENT_TYPE); - - factory_class->create_accessible = gal_a11y_e_text_factory_create_accessible; - factory_class->get_accessible_type = gal_a11y_e_text_factory_get_accessible_type; -} - -static void -gal_a11y_e_text_factory_init (GalA11yETextFactory *factory) -{ -} - -/** - * gal_a11y_e_text_factory_get_type: - * @void: - * - * Registers the &GalA11yETextFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yETextFactory class. - **/ -GType -gal_a11y_e_text_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (GalA11yETextFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gal_a11y_e_text_factory_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yETextFactory), - 0, - (GInstanceInitFunc) gal_a11y_e_text_factory_init, - NULL /* value_text */ - }; - - type = g_type_register_static (PARENT_TYPE, "GalA11yETextFactory", &info, 0); - } - - return type; -} diff --git a/widgets/text/gal-a11y-e-text-factory.h b/widgets/text/gal-a11y-e-text-factory.h deleted file mode 100644 index 1e66d34ff8..0000000000 --- a/widgets/text/gal-a11y-e-text-factory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TEXT_FACTORY_H__ -#define __GAL_A11Y_E_TEXT_FACTORY_H__ - -#include <atk/atkobjectfactory.h> - -#define GAL_A11Y_TYPE_E_TEXT_FACTORY (gal_a11y_e_text_factory_get_type ()) -#define GAL_A11Y_E_TEXT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TEXT_FACTORY, GalA11yETextFactory)) -#define GAL_A11Y_E_TEXT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TEXT_FACTORY, GalA11yETextFactoryClass)) -#define GAL_A11Y_IS_E_TEXT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TEXT_FACTORY)) -#define GAL_A11Y_IS_E_TEXT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TEXT_FACTORY)) - -typedef struct _GalA11yETextFactory GalA11yETextFactory; -typedef struct _GalA11yETextFactoryClass GalA11yETextFactoryClass; - -struct _GalA11yETextFactory { - AtkObjectFactory object; -}; - -struct _GalA11yETextFactoryClass { - AtkObjectFactoryClass parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_text_factory_get_type (void); - -#endif /* __GAL_A11Y_E_TEXT_FACTORY_H__ */ diff --git a/widgets/text/gal-a11y-e-text.c b/widgets/text/gal-a11y-e-text.c deleted file mode 100644 index 44b069d3a7..0000000000 --- a/widgets/text/gal-a11y-e-text.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> - -#include "a11y/gal-a11y-util.h" -#include "text/e-text.h" -#include "text/e-text-model-repos.h" - -#include "gal-a11y-e-text.h" -#include "gal-a11y-e-text-factory.h" - -static GObjectClass *parent_class; -static AtkComponentIface *component_parent_iface; -static GType parent_type; -static gint priv_offset; -static GQuark quark_accessible_object = 0; -#define PARENT_TYPE (parent_type) - -struct _GalA11yETextPrivate { - gint dummy; -}; - -static void -et_dispose (GObject *object) -{ - if (parent_class->dispose) - parent_class->dispose (object); -} - -/* Static functions */ - -static void -et_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - EText *item = E_TEXT (atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (component))); - gdouble real_width; - gdouble real_height; - gint fake_width; - gint fake_height; - - if (component_parent_iface && - component_parent_iface->get_extents) - component_parent_iface->get_extents (component, - x, - y, - &fake_width, - &fake_height, - coord_type); - - g_object_get ( - item, - "text_width", &real_width, - "text_height", &real_height, - NULL); - - if (width) - *width = real_width; - if (height) - *height = real_height; -} - -static const gchar * -et_get_full_text (AtkText *text) -{ - GObject *obj; - EText *etext; - ETextModel *model; - const gchar *full_text; - - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return ""; - - etext = E_TEXT (obj); - g_object_get (etext, "model", &model, NULL); - - full_text = e_text_model_get_text (model); - - return full_text; -} - -static void -et_set_full_text (AtkEditableText *text, - const gchar *full_text) -{ - GObject *obj; - EText *etext; - ETextModel *model; - - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return; - - etext = E_TEXT (obj); - g_object_get (etext, "model", &model, NULL); - - e_text_model_set_text (model, full_text); -} - -static gchar * -et_get_text (AtkText *text, - gint start_offset, - gint end_offset) -{ - gint start, end, real_start, real_end, len; - const gchar *full_text = et_get_full_text (text); - if (full_text == NULL) - return NULL; - len = g_utf8_strlen (full_text, -1); - - start = MIN (MAX (0, start_offset), len); - end = MIN (MAX (-1, end_offset), len); - - if (end_offset == -1) - end = strlen (full_text); - else - end = g_utf8_offset_to_pointer (full_text, end) - full_text; - - start = g_utf8_offset_to_pointer (full_text, start) - full_text; - - real_start = MIN (start, end); - real_end = MAX (start, end); - - return g_strndup (full_text + real_start, real_end - real_start); -} - -static gboolean -is_a_seperator (gunichar c) -{ - return g_unichar_ispunct (c) || g_unichar_isspace (c); -} - -static gint -find_word_start (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset; - gchar *at_offset; - gunichar current, previous; - gint len; - - offset = begin_offset; - len = g_utf8_strlen (text, -1); - - while (offset > 0 && offset < len) { - at_offset = g_utf8_offset_to_pointer (text, offset); - current = g_utf8_get_char_validated (at_offset, -1); - at_offset = g_utf8_offset_to_pointer (text, offset - 1); - previous = g_utf8_get_char_validated (at_offset, -1); - if ((!is_a_seperator (current)) && is_a_seperator (previous)) - break; - offset += step; - } - - return offset; -} - -static gint -find_word_end (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset; - gchar *at_offset; - gunichar current, previous; - gint len; - - offset = begin_offset; - len = g_utf8_strlen (text, -1); - - while (offset > 0 && offset < len) { - at_offset = g_utf8_offset_to_pointer (text, offset); - current = g_utf8_get_char_validated (at_offset, -1); - at_offset = g_utf8_offset_to_pointer (text, offset - 1); - previous = g_utf8_get_char_validated (at_offset, -1); - if (is_a_seperator (current) && (!is_a_seperator (previous))) - break; - offset += step; - } - - return offset; -} - -static gint -find_sentence_start (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset, last_word_end, len; - gchar *at_offset; - gunichar ch; - gint i; - - offset = find_word_start (text, begin_offset, step); - len = g_utf8_strlen (text, -1); - - while (offset > 0 && offset <len) { - last_word_end = find_word_end (text, offset - 1, -1); - if (last_word_end == 0) - break; - for (i = last_word_end; i < offset; i++) { - at_offset = g_utf8_offset_to_pointer (text, i); - ch = g_utf8_get_char_validated (at_offset, -1); - if (ch == '.' || ch == '!' || ch == '?') - return offset; - } - - offset = find_word_start (text, offset + step, step); - } - - return offset; -} - -static gint -find_sentence_end (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset; - gchar *at_offset; - gunichar previous; - gint len; - - offset = begin_offset; - len = g_utf8_strlen (text, -1); - - while (offset > 0 && offset < len) { - at_offset = g_utf8_offset_to_pointer (text, offset - 1); - previous = g_utf8_get_char_validated (at_offset, -1); - if (previous == '.' || previous == '!' || previous == '?') - break; - offset += step; - } - - return offset; -} - -static gint -find_line_start (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset; - gchar *at_offset; - gunichar previous; - gint len; - - offset = begin_offset; - len = g_utf8_strlen (text, -1); - - while (offset > 0 && offset < len) { - at_offset = g_utf8_offset_to_pointer (text, offset - 1); - previous = g_utf8_get_char_validated (at_offset, -1); - if (previous == '\n' || previous == '\r') - break; - offset += step; - } - - return offset; -} - -static gint -find_line_end (const gchar *text, - gint begin_offset, - gint step) -{ - gint offset; - gchar *at_offset; - gunichar current; - gint len; - - offset = begin_offset; - len = g_utf8_strlen (text, -1); - - while (offset >= 0 && offset < len) { - at_offset = g_utf8_offset_to_pointer (text, offset); - current = g_utf8_get_char_validated (at_offset, -1); - if (current == '\n' || current == '\r') - break; - offset += step; - } - - return offset; -} - -static gchar * -et_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - gint start, end, len; - const gchar *full_text = et_get_full_text (text); - g_return_val_if_fail (full_text, NULL); - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - start = offset + 1; - end = offset + 2; - break; - case ATK_TEXT_BOUNDARY_WORD_START: - start = find_word_start (full_text, offset + 1, 1); - end = find_word_start (full_text, start + 1, 1); - break; - case ATK_TEXT_BOUNDARY_WORD_END: - start = find_word_end (full_text, offset + 1, 1); - end = find_word_end (full_text, start + 1, 1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - start = find_sentence_start (full_text, offset + 1, 1); - end = find_sentence_start (full_text, start + 1, 1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_END: - start = find_sentence_end (full_text, offset + 1, 1); - end = find_sentence_end (full_text, start + 1, 1); - break; - case ATK_TEXT_BOUNDARY_LINE_START: - start = find_line_start (full_text, offset + 1, 1); - end = find_line_start (full_text, start + 1, 1); - break; - case ATK_TEXT_BOUNDARY_LINE_END: - start = find_line_end (full_text, offset + 1, 1); - end = find_line_end (full_text, start + 1, 1); - break; - default: - return NULL; - } - - len = g_utf8_strlen (full_text, -1); - if (start_offset) - *start_offset = MIN (MAX (0, start), len); - if (end_offset) - *end_offset = MIN (MAX (0, end), len); - return et_get_text (text, start, end); -} - -static gchar * -et_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - gint start, end, len; - const gchar *full_text = et_get_full_text (text); - g_return_val_if_fail (full_text, NULL); - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - start = offset; - end = offset + 1; - break; - case ATK_TEXT_BOUNDARY_WORD_START: - start = find_word_start (full_text, offset - 1, -1); - end = find_word_start (full_text, offset, 1); - break; - case ATK_TEXT_BOUNDARY_WORD_END: - start = find_word_end (full_text, offset, -1); - end = find_word_end (full_text, offset + 1, 1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - start = find_sentence_start (full_text, offset - 1, -1); - end = find_sentence_start (full_text, offset, 1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_END: - start = find_sentence_end (full_text, offset, -1); - end = find_sentence_end (full_text, offset + 1, 1); - break; - case ATK_TEXT_BOUNDARY_LINE_START: - start = find_line_start (full_text, offset - 1, -1); - end = find_line_start (full_text, offset, 1); - break; - case ATK_TEXT_BOUNDARY_LINE_END: - start = find_line_end (full_text, offset, -1); - end = find_line_end (full_text, offset + 1, 1); - break; - default: - return NULL; - } - - len = g_utf8_strlen (full_text, -1); - if (start_offset) - *start_offset = MIN (MAX (0, start), len); - if (end_offset) - *end_offset = MIN (MAX (0, end), len); - return et_get_text (text, start, end); -} - -static gunichar -et_get_character_at_offset (AtkText *text, - gint offset) -{ - const gchar *full_text = et_get_full_text (text); - gchar *at_offset; - - at_offset = g_utf8_offset_to_pointer (full_text, offset); - return g_utf8_get_char_validated (at_offset, -1); -} - -static gchar * -et_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - gint start, end, len; - const gchar *full_text = et_get_full_text (text); - g_return_val_if_fail (full_text, NULL); - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - start = offset - 1; - end = offset; - break; - case ATK_TEXT_BOUNDARY_WORD_START: - end = find_word_start (full_text, offset - 1, -1); - start = find_word_start (full_text, end - 1, -1); - break; - case ATK_TEXT_BOUNDARY_WORD_END: - end = find_word_end (full_text, offset, -1); - start = find_word_end (full_text, end - 1, -1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - end = find_sentence_start (full_text, offset, -1); - start = find_sentence_start (full_text, end - 1, -1); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_END: - end = find_sentence_end (full_text, offset, -1); - start = find_sentence_end (full_text, end - 1, -1); - break; - case ATK_TEXT_BOUNDARY_LINE_START: - end = find_line_start (full_text, offset, -1); - start = find_line_start (full_text, end - 1, -1); - break; - case ATK_TEXT_BOUNDARY_LINE_END: - end = find_line_end (full_text, offset, -1); - start = find_line_end (full_text, end - 1, -1); - break; - default: - return NULL; - } - - len = g_utf8_strlen (full_text, -1); - if (start_offset) - *start_offset = MIN (MAX (0, start), len); - if (end_offset) - *end_offset = MIN (MAX (0, end), len); - return et_get_text (text, start, end); -} - -static gint -et_get_caret_offset (AtkText *text) -{ - GObject *obj; - EText *etext; - gint offset; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), -1); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return -1; - - g_return_val_if_fail (E_IS_TEXT (obj), -1); - etext = E_TEXT (obj); - - g_object_get (etext, "cursor_pos", &offset, NULL); - return offset; -} - -static AtkAttributeSet * -et_get_run_attributes (AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - /* Unimplemented */ - return NULL; -} - -static AtkAttributeSet * -et_get_default_attributes (AtkText *text) -{ - /* Unimplemented */ - return NULL; -} - -static void -et_get_character_extents (AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords) -{ - GObject *obj; - EText *etext; - GnomeCanvas *canvas; - gint x_widget, y_widget, x_window, y_window; - GdkWindow *window; - GtkWidget *widget; - PangoRectangle pango_pos; - - g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text)); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return; - g_return_if_fail (E_IS_TEXT (obj)); - etext = E_TEXT (obj); - canvas = GNOME_CANVAS_ITEM (etext)->canvas; - widget = GTK_WIDGET (canvas); - window = gtk_widget_get_window (widget); - gdk_window_get_origin (window, &x_widget, &y_widget); - - pango_layout_index_to_pos (etext->layout, offset, &pango_pos); - pango_pos.x = PANGO_PIXELS (pango_pos.x); - pango_pos.y = PANGO_PIXELS (pango_pos.y); - pango_pos.width = (pango_pos.width + PANGO_SCALE / 2) / PANGO_SCALE; - pango_pos.height = (pango_pos.height + PANGO_SCALE / 2) / PANGO_SCALE; - - *x = pango_pos.x + x_widget; - *y = pango_pos.y + y_widget; - - *width = pango_pos.width; - *height = pango_pos.height; - - *x += etext->xofs; - *y += etext->yofs; - - if (etext->editing) { - *x -= etext->xofs_edit; - *y -= etext->yofs_edit; - } - - *x += etext->cx; - *y += etext->cy; - - if (coords == ATK_XY_WINDOW) { - window = gdk_window_get_toplevel (window); - gdk_window_get_origin (window, &x_window, &y_window); - *x -= x_window; - *y -= y_window; - } - else if (coords == ATK_XY_SCREEN) { - } - else { - *x = 0; - *y = 0; - *height = 0; - *width = 0; - } -} - -static gint -et_get_character_count (AtkText *text) -{ - const gchar *full_text = et_get_full_text (text); - - return g_utf8_strlen (full_text, -1); -} - -static gint -et_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - GObject *obj; - EText *etext; - GnomeCanvas *canvas; - gint x_widget, y_widget, x_window, y_window; - GdkWindow *window; - GtkWidget *widget; - gint index; - gint trailing; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), -1); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return -1; - g_return_val_if_fail (E_IS_TEXT (obj), -1); - etext = E_TEXT (obj); - canvas = GNOME_CANVAS_ITEM (etext)->canvas; - widget = GTK_WIDGET (canvas); - window = gtk_widget_get_window (widget); - gdk_window_get_origin (window, &x_widget, &y_widget); - - if (coords == ATK_XY_SCREEN) { - x = x - x_widget; - y = y - y_widget; - } - else if (coords == ATK_XY_WINDOW) { - window = gdk_window_get_toplevel (window); - gdk_window_get_origin (window, &x_window, &y_window); - x = x - x_widget + x_window; - y = y - y_widget + y_window; - } - else - return -1; - - x -= etext->xofs; - y -= etext->yofs; - - if (etext->editing) { - x += etext->xofs_edit; - y += etext->yofs_edit; - } - - x -= etext->cx; - y -= etext->cy; - - pango_layout_xy_to_index ( - etext->layout, - x * PANGO_SCALE - PANGO_SCALE / 2, - y * PANGO_SCALE - PANGO_SCALE / 2, - &index, - &trailing); - - return g_utf8_pointer_to_offset (etext->text, etext->text + index + trailing); -} - -static gint -et_get_n_selections (AtkText *text) -{ - EText *etext; - GObject *obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - - if (obj == NULL) - return -1; - etext = E_TEXT (obj); - - if (etext->selection_start != - etext->selection_end) - return 1; - return 0; -} - -static gchar * -et_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset) -{ - gint start, end, real_start, real_end, len; - EText *etext; - if (selection_num == 0) { - const gchar *full_text = et_get_full_text (text); - if (full_text == NULL) - return NULL; - len = g_utf8_strlen (full_text, -1); - etext = E_TEXT (atk_gobject_accessible_get_object ( - ATK_GOBJECT_ACCESSIBLE (text))); - start = MIN (etext->selection_start, etext->selection_end); - end = MAX (etext->selection_start, etext->selection_end); - start = MIN (MAX (0, start), len); - end = MIN (MAX (0, end), len); - if (start != end) { - if (start_offset) - *start_offset = start; - if (end_offset) - *end_offset = end; - real_start = g_utf8_offset_to_pointer (full_text, start) - full_text; - real_end = g_utf8_offset_to_pointer (full_text, end) - full_text; - return g_strndup (full_text + real_start, real_end - real_start); - } - } - - return NULL; -} - -static gboolean -et_add_selection (AtkText *text, - gint start_offset, - gint end_offset) -{ - GObject *obj; - EText *etext; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return FALSE; - g_return_val_if_fail (E_IS_TEXT (obj), FALSE); - etext = E_TEXT (obj); - - g_return_val_if_fail (start_offset >= 0, FALSE); - g_return_val_if_fail (start_offset >= -1, FALSE); - if (end_offset == -1) - end_offset = et_get_character_count (text); - - if (start_offset != end_offset) { - gint real_start, real_end; - real_start = MIN (start_offset, end_offset); - real_end = MAX (start_offset, end_offset); - etext->selection_start = real_start; - etext->selection_end = real_end; - - gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etext)); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (etext)); - - g_signal_emit_by_name (ATK_OBJECT (text), "text_selection_changed"); - - return TRUE; - } - - return FALSE; -} - -static gboolean -et_remove_selection (AtkText *text, - gint selection_num) -{ - GObject *obj; - EText *etext; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return FALSE; - g_return_val_if_fail (E_IS_TEXT (obj), FALSE); - etext = E_TEXT (obj); - - if (selection_num == 0 - && etext->selection_start != etext->selection_end) { - etext->selection_end = etext->selection_start; - g_signal_emit_by_name (ATK_OBJECT (text), "text_selection_changed"); - return TRUE; - } - - return FALSE; -} - -static gboolean -et_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset) -{ - GObject *obj; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return FALSE; - g_return_val_if_fail (E_IS_TEXT (obj), FALSE); - if (selection_num == 0) - return et_add_selection (text, start_offset, end_offset); - return FALSE; -} - -static gboolean -et_set_caret_offset (AtkText *text, - gint offset) -{ - GObject *obj; - EText *etext; - - g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return FALSE; - - g_return_val_if_fail (E_IS_TEXT (obj), FALSE); - etext = E_TEXT (obj); - - if (offset < -1) - return FALSE; - else { - ETextEventProcessorCommand command; - - if (offset == -1) - offset = et_get_character_count (text); - - command.action = E_TEP_MOVE; - command.position = E_TEP_VALUE; - command.value = offset; - command.time = GDK_CURRENT_TIME; - g_signal_emit_by_name (etext->tep, "command", &command); - return TRUE; - } -} - -static gboolean -et_set_run_attributes (AtkEditableText *text, - AtkAttributeSet *attrib_set, - gint start_offset, - gint end_offset) -{ - /* Unimplemented */ - return FALSE; -} - -static void -et_set_text_contents (AtkEditableText *text, - const gchar *string) -{ - et_set_full_text (text, string); -} - -static void -et_insert_text (AtkEditableText *text, - const gchar *string, - gint length, - gint *position) -{ - /* Utf8 unimplemented */ - gchar *result; - - const gchar *full_text = et_get_full_text (ATK_TEXT (text)); - if (full_text == NULL) - return; - - result = g_strdup_printf ( - "%.*s%.*s%s", *position, full_text, - length, string, full_text + *position); - - et_set_full_text (text, result); - - *position += length; - - g_free (result); -} - -static void -et_copy_text (AtkEditableText *text, - gint start_pos, - gint end_pos) -{ - GObject *obj; - EText *etext; - - g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text)); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return; - - g_return_if_fail (E_IS_TEXT (obj)); - etext = E_TEXT (obj); - - if (start_pos != end_pos) { - etext->selection_start = start_pos; - etext->selection_end = end_pos; - e_text_copy_clipboard (etext); - } -} - -static void -et_delete_text (AtkEditableText *text, - gint start_pos, - gint end_pos) -{ - GObject *obj; - EText *etext; - - g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text)); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return; - - g_return_if_fail (E_IS_TEXT (obj)); - etext = E_TEXT (obj); - - etext->selection_start = start_pos; - etext->selection_end = end_pos; - - e_text_delete_selection (etext); -} - -static void -et_cut_text (AtkEditableText *text, - gint start_pos, - gint end_pos) -{ - et_copy_text (text, start_pos, end_pos); - et_delete_text (text, start_pos, end_pos); -} - -static void -et_paste_text (AtkEditableText *text, - gint position) -{ - GObject *obj; - EText *etext; - - g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text)); - obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); - if (obj == NULL) - return; - - g_return_if_fail (E_IS_TEXT (obj)); - etext = E_TEXT (obj); - - g_object_set (etext, "cursor_pos", position, NULL); - e_text_paste_clipboard (etext); -} - -static void -et_atk_component_iface_init (AtkComponentIface *iface) -{ - iface->get_extents = et_get_extents; -} - -static void -et_atk_text_iface_init (AtkTextIface *iface) -{ - iface->get_text = et_get_text; - iface->get_text_after_offset = et_get_text_after_offset; - iface->get_text_at_offset = et_get_text_at_offset; - iface->get_character_at_offset = et_get_character_at_offset; - iface->get_text_before_offset = et_get_text_before_offset; - iface->get_caret_offset = et_get_caret_offset; - iface->get_run_attributes = et_get_run_attributes; - iface->get_default_attributes = et_get_default_attributes; - iface->get_character_extents = et_get_character_extents; - iface->get_character_count = et_get_character_count; - iface->get_offset_at_point = et_get_offset_at_point; - iface->get_n_selections = et_get_n_selections; - iface->get_selection = et_get_selection; - iface->add_selection = et_add_selection; - iface->remove_selection = et_remove_selection; - iface->set_selection = et_set_selection; - iface->set_caret_offset = et_set_caret_offset; -} - -static void -et_atk_editable_text_iface_init (AtkEditableTextIface *iface) -{ - iface->set_run_attributes = et_set_run_attributes; - iface->set_text_contents = et_set_text_contents; - iface->insert_text = et_insert_text; - iface->copy_text = et_copy_text; - iface->cut_text = et_cut_text; - iface->delete_text = et_delete_text; - iface->paste_text = et_paste_text; -} - -static void -_et_reposition_cb (ETextModel *model, - ETextModelReposFn fn, - gpointer repos_data, - gpointer user_data) -{ - AtkObject *accessible; - AtkText *text; - - accessible = ATK_OBJECT (user_data); - text = ATK_TEXT (accessible); - - if (fn == e_repos_delete_shift) { - EReposDeleteShift *info = (EReposDeleteShift *) repos_data; - g_signal_emit_by_name (text, "text-changed::delete", info->pos, info->len); - } - else if (fn == e_repos_insert_shift) { - EReposInsertShift *info = (EReposInsertShift *) repos_data; - g_signal_emit_by_name (text, "text-changed::insert", info->pos, info->len); - } -} - -static void -_et_command_cb (ETextEventProcessor *tep, - ETextEventProcessorCommand *command, - gpointer user_data) -{ - AtkObject *accessible; - AtkText *text; - - accessible = ATK_OBJECT (user_data); - text = ATK_TEXT (accessible); - - switch (command->action) { - case E_TEP_MOVE: - g_signal_emit_by_name (text, "text-caret-moved", et_get_caret_offset (text)); - break; - case E_TEP_SELECT: - g_signal_emit_by_name (text, "text-selection-changed"); - break; - default: - break; - } -} - -static void -et_real_initialize (AtkObject *obj, - gpointer data) -{ - EText *etext; - - ATK_OBJECT_CLASS (parent_class)->initialize (obj, data); - - g_return_if_fail (GAL_A11Y_IS_E_TEXT (obj)); - g_return_if_fail (E_IS_TEXT (data)); - - etext = E_TEXT (data); - - /* Set up signal callbacks */ - g_signal_connect ( - etext->model, "reposition", - G_CALLBACK (_et_reposition_cb), obj); - - if (etext->tep) - g_signal_connect_after ( - etext->tep, "command", - (GCallback) _et_command_cb, obj); - - obj->role = ATK_ROLE_TEXT; -} - -static void -et_class_init (GalA11yETextClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - AtkObjectClass *atk_class = ATK_OBJECT_CLASS (class); - - quark_accessible_object = - g_quark_from_static_string ("gtk-accessible-object"); - parent_class = g_type_class_ref (PARENT_TYPE); - component_parent_iface = - g_type_interface_peek (parent_class, ATK_TYPE_COMPONENT); - object_class->dispose = et_dispose; - atk_class->initialize = et_real_initialize; -} - -static void -et_init (GalA11yEText *a11y) -{ -} - -/** - * gal_a11y_e_text_get_type: - * @void: - * - * Registers the &GalA11yEText class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &GalA11yEText class. - **/ -GType -gal_a11y_e_text_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - - GTypeInfo info = { - sizeof (GalA11yETextClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) et_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (GalA11yEText), - 0, - (GInstanceInitFunc) et_init, - NULL /* value_text */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) et_atk_component_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - static const GInterfaceInfo atk_text_info = { - (GInterfaceInitFunc) et_atk_text_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - static const GInterfaceInfo atk_editable_text_info = { - (GInterfaceInitFunc) et_atk_editable_text_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - factory = atk_registry_get_factory ( - atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM); - parent_type = atk_object_factory_get_accessible_type (factory); - - type = gal_a11y_type_register_static_with_private ( - PARENT_TYPE, "GalA11yEText", &info, 0, - sizeof (GalA11yETextPrivate), &priv_offset); - - g_type_add_interface_static ( - type, ATK_TYPE_COMPONENT, &atk_component_info); - g_type_add_interface_static ( - type, ATK_TYPE_TEXT, &atk_text_info); - g_type_add_interface_static ( - type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info); - } - - return type; -} - -void -gal_a11y_e_text_init (void) -{ - if (atk_get_root ()) - atk_registry_set_factory_type ( - atk_get_default_registry (), - E_TYPE_TEXT, - gal_a11y_e_text_factory_get_type ()); - -} - diff --git a/widgets/text/gal-a11y-e-text.h b/widgets/text/gal-a11y-e-text.h deleted file mode 100644 index adf2833a19..0000000000 --- a/widgets/text/gal-a11y-e-text.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * 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) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Christopher James Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __GAL_A11Y_E_TEXT_H__ -#define __GAL_A11Y_E_TEXT_H__ - -#include <table/e-table-item.h> - -#define GAL_A11Y_TYPE_E_TEXT (gal_a11y_e_text_get_type ()) -#define GAL_A11Y_E_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TEXT, GalA11yEText)) -#define GAL_A11Y_E_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TEXT, GalA11yETextClass)) -#define GAL_A11Y_IS_E_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TEXT)) -#define GAL_A11Y_IS_E_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TEXT)) - -typedef struct _GalA11yEText GalA11yEText; -typedef struct _GalA11yETextClass GalA11yETextClass; -typedef struct _GalA11yETextPrivate GalA11yETextPrivate; - -/* This struct should actually be larger as this isn't what we derive from. - * The GalA11yETextPrivate comes right after the parent class structure. - **/ -struct _GalA11yEText { - AtkObject object; -}; - -struct _GalA11yETextClass { - AtkObject parent_class; -}; - -/* Standard Glib function */ -GType gal_a11y_e_text_get_type (void); - -void gal_a11y_e_text_init (void); - -#endif /* __GAL_A11Y_E_TEXT_H__ */ |