aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/e-table/ChangeLog15
-rw-r--r--widgets/e-table/Makefile.am12
-rw-r--r--widgets/e-table/e-table-defines.h6
-rw-r--r--widgets/e-table/e-table-field-chooser-dialog.c108
-rw-r--r--widgets/e-table/e-table-field-chooser-dialog.h73
-rw-r--r--widgets/e-table/e-table-field-chooser-item.c567
-rw-r--r--widgets/e-table/e-table-field-chooser-item.h47
-rw-r--r--widgets/e-table/e-table-field-chooser.c137
-rw-r--r--widgets/e-table/e-table-field-chooser.glade114
-rw-r--r--widgets/e-table/e-table-field-chooser.glade.h7
-rw-r--r--widgets/e-table/e-table-field-chooser.h74
-rw-r--r--widgets/e-table/e-table-header-item.c293
-rw-r--r--widgets/e-table/e-table-header-item.h11
-rw-r--r--widgets/table/e-table-defines.h6
-rw-r--r--widgets/table/e-table-field-chooser-dialog.c108
-rw-r--r--widgets/table/e-table-field-chooser-dialog.h73
-rw-r--r--widgets/table/e-table-field-chooser-item.c567
-rw-r--r--widgets/table/e-table-field-chooser-item.h47
-rw-r--r--widgets/table/e-table-field-chooser.c137
-rw-r--r--widgets/table/e-table-field-chooser.glade114
-rw-r--r--widgets/table/e-table-field-chooser.glade.h7
-rw-r--r--widgets/table/e-table-field-chooser.h74
-rw-r--r--widgets/table/e-table-header-item.c293
-rw-r--r--widgets/table/e-table-header-item.h11
24 files changed, 2583 insertions, 318 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 2d81cf5ac3..55abf70a12 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,18 @@
+2000-06-07 Christopher James Lahey <clahey@helixcode.com>
+
+ * Makefile.am: Added e-table-field-chooser*.
+
+ * e-table-defines.h: Moved some things to here.
+
+ * e-table-field-chooser-dialog.c, e-table-field-chooser-dialog.h,
+ e-table-field-chooser-item.c, e-table-field-chooser-item.h,
+ e-table-field-chooser.c, e-table-field-chooser.glade,
+ e-table-field-chooser.glade.h, e-table-field-chooser.h: New dialog
+ to drag extra fields from. (Not yet finished.)
+
+ * e-table-header-item.c, e-table-header-item.h: Changed to
+ accommodate e-table-field-chooser.
+
2000-06-06 Christopher James Lahey <clahey@helixcode.com>
* e-table-group-container.c, e-table-group-leaf.c,
diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am
index c187332d00..dc3dc0b526 100644
--- a/widgets/e-table/Makefile.am
+++ b/widgets/e-table/Makefile.am
@@ -2,11 +2,13 @@
gladedir = $(datadir)/evolution/glade
glade_DATA = \
e-table-config.glade \
- e-table-group.glade
+ e-table-group.glade \
+ e-table-field-chooser.glade
glade_headers = \
e-table-config.glade.h \
- e-table-group.glade.h
+ e-table-group.glade.h \
+ e-table-field-chooser.glade.h
INCLUDES = \
$(EXTRA_GNOME_CFLAGS) \
@@ -37,6 +39,12 @@ libetable_a_SOURCES = \
e-table-config.c \
e-table-config.h \
e-table-defines.h \
+ e-table-field-chooser-dialog.c \
+ e-table-field-chooser-dialog.h \
+ e-table-field-chooser-item.c \
+ e-table-field-chooser-item.h \
+ e-table-field-chooser.c \
+ e-table-field-chooser.h \
e-table-group.c \
e-table-group.h \
e-table-group-container.c \
diff --git a/widgets/e-table/e-table-defines.h b/widgets/e-table/e-table-defines.h
index 02f1d19b77..9eb797dd66 100644
--- a/widgets/e-table/e-table-defines.h
+++ b/widgets/e-table/e-table-defines.h
@@ -1,3 +1,9 @@
#define BUTTON_HEIGHT 10
#define BUTTON_PADDING 2
#define GROUP_INDENT (BUTTON_HEIGHT + (BUTTON_PADDING * 2))
+
+/* Padding above and below of the string in the header display */
+#define HEADER_PADDING 4
+
+#define MIN_ARROW_SIZE 10
+
diff --git a/widgets/e-table/e-table-field-chooser-dialog.c b/widgets/e-table/e-table-field-chooser-dialog.c
new file mode 100644
index 0000000000..6fbc5ba38c
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser-dialog.c
@@ -0,0 +1,108 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-field-chooser-dialog.c
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <e-table-field-chooser-dialog.h>
+
+static void e_table_field_chooser_dialog_init (ETableFieldChooserDialog *card);
+static void e_table_field_chooser_dialog_class_init (ETableFieldChooserDialogClass *klass);
+static void e_table_field_chooser_dialog_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static GnomeDialogClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+};
+
+GtkType
+e_table_field_chooser_dialog_get_type (void)
+{
+ static GtkType table_field_chooser_dialog_type = 0;
+
+ if (!table_field_chooser_dialog_type)
+ {
+ static const GtkTypeInfo table_field_chooser_dialog_info =
+ {
+ "ETableFieldChooserDialog",
+ sizeof (ETableFieldChooserDialog),
+ sizeof (ETableFieldChooserDialogClass),
+ (GtkClassInitFunc) e_table_field_chooser_dialog_class_init,
+ (GtkObjectInitFunc) e_table_field_chooser_dialog_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ table_field_chooser_dialog_type = gtk_type_unique (gtk_vbox_get_type (), &table_field_chooser_dialog_info);
+ }
+
+ return table_field_chooser_dialog_type;
+}
+
+static void
+e_table_field_chooser_dialog_class_init (ETableFieldChooserDialogClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkVBoxClass *vbox_class;
+
+ object_class = (GtkObjectClass*) klass;
+ vbox_class = (GtkVBoxClass *) klass;
+
+ parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+ object_class->set_arg = e_table_field_chooser_dialog_set_arg;
+ object_class->get_arg = e_table_field_chooser_dialog_get_arg;
+}
+
+static void
+e_table_field_chooser_dialog_init (ETableFieldChooserDialog *e_table_field_chooser_dialog)
+{
+}
+
+GtkWidget*
+e_table_field_chooser_dialog_new (void)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_table_field_chooser_dialog_get_type ()));
+ return widget;
+}
+
+static void
+e_table_field_chooser_dialog_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id){
+ default:
+ break;
+ }
+}
+
+static void
+e_table_field_chooser_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id) {
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/widgets/e-table/e-table-field-chooser-dialog.h b/widgets/e-table/e-table-field-chooser-dialog.h
new file mode 100644
index 0000000000..3a23f13bb5
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser-dialog.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-table-field-chooser-dialog.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_TABLE_FIELD_CHOOSER_DIALOG_H__
+#define __E_TABLE_FIELD_CHOOSER_DIALOG_H__
+
+#include <gnome.h>
+#include <glade/glade.h>
+#include "e-table-field-chooser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+/* ETableFieldChooserDialog - A dialog displaying information about a contact.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ */
+
+#define E_TABLE_FIELD_CHOOSER_DIALOG_TYPE (e_table_field_chooser_dialog_get_type ())
+#define E_TABLE_FIELD_CHOOSER_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE, ETableFieldChooserDialog))
+#define E_TABLE_FIELD_CHOOSER_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE, ETableFieldChooserDialogClass))
+#define E_IS_TABLE_FIELD_CHOOSER_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE))
+
+
+typedef struct _ETableFieldChooserDialog ETableFieldChooserDialog;
+typedef struct _ETableFieldChooserDialogClass ETableFieldChooserDialogClass;
+
+struct _ETableFieldChooserDialog
+{
+ GnomeDialog parent;
+
+ /* item specific fields */
+ ETableFieldChooser *chooser;
+};
+
+struct _ETableFieldChooserDialogClass
+{
+ GnomeDialogClass parent_class;
+};
+
+
+GtkWidget *e_table_field_chooser_dialog_new(void);
+GtkType e_table_field_chooser_dialog_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __E_TABLE_FIELD_CHOOSER_DIALOG_H__ */
diff --git a/widgets/e-table/e-table-field-chooser-item.c b/widgets/e-table/e-table-field-chooser-item.c
new file mode 100644
index 0000000000..fd08af3307
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser-item.c
@@ -0,0 +1,567 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-table-column-view.c: A canvas item based view of the ETableColumn.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * Copyright 1999, 2000 Helix Code, Inc.
+ */
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkdnd.h>
+#include <libgnomeui/gnome-canvas.h>
+#include <libgnomeui/gnome-canvas-util.h>
+#include <libgnomeui/gnome-canvas-polygon.h>
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "e-util/e-xml-utils.h"
+#include "e-util/e-canvas.h"
+
+#include "e-table-header.h"
+#include "e-table-col-dnd.h"
+#include "e-table-defines.h"
+
+#include "e-table-field-chooser-item.h"
+
+#if 0
+enum {
+ BUTTON_PRESSED,
+ LAST_SIGNAL
+};
+
+static guint etfci_signals [LAST_SIGNAL] = { 0, };
+#endif
+
+#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
+
+#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
+
+static GnomeCanvasItemClass *etfci_parent_class;
+
+static void etfci_drop_table_header (ETableFieldChooserItem *etfci);
+
+enum {
+ ARG_0,
+ ARG_TABLE_HEADER,
+ ARG_DND_CODE,
+ ARG_TABLE_FONTSET,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+};
+
+static void
+etfci_destroy (GtkObject *object){
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (object);
+
+ etfci_drop_table_header (etfci);
+
+ gdk_font_unref(etfci->font);
+
+ if (GTK_OBJECT_CLASS (etfci_parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (etfci_parent_class)->destroy) (object);
+}
+
+static void
+etfci_reflow (GnomeCanvasItem *item, gint flags)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ double old_height;
+
+ old_height = etfci->height;
+
+ etfci->height = e_table_header_count (etfci->full_header) * etfci->button_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, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ double i2c [6];
+ ArtPoint c1, c2, i1, i2;
+
+ if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)
+ (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)(item, affine, clip_path, flags);
+
+ i1.x = i1.y = 0;
+ i2.x = etfci->width;
+ i2.y = etfci->height;
+
+ gnome_canvas_item_i2c_affine (item, i2c);
+ art_affine_point (&c1, &i1, i2c);
+ art_affine_point (&c2, &i2, i2c);
+
+ if (item->x1 != c1.x ||
+ item->y1 != c1.y ||
+ item->x2 != c2.x ||
+ item->y2 != c2.y)
+ {
+ gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+ item->x1 = c1.x;
+ item->y1 = c1.y;
+ item->x2 = c2.x;
+ item->y2 = c2.y;
+
+ gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
+ }
+ gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+}
+
+static void
+etfci_font_load (ETableFieldChooserItem *etfci, char *font)
+{
+ if (etfci->font)
+ gdk_font_unref (etfci->font);
+ etfci->font = NULL;
+
+ if (font)
+ etfci->font = gdk_fontset_load (font);
+
+ if (etfci->font == NULL) {
+ etfci->font = GTK_WIDGET(GNOME_CANVAS_ITEM(etfci)->canvas)->style->font;
+ gdk_font_ref(etfci->font);
+ }
+
+ etfci->button_height = etfci->font->ascent + etfci->font->descent + HEADER_PADDING;
+}
+
+static void
+etfci_drop_table_header (ETableFieldChooserItem *etfci)
+{
+ GtkObject *header;
+
+ if (!etfci->full_header)
+ return;
+
+ header = GTK_OBJECT (etfci->full_header);
+ gtk_signal_disconnect (header, etfci->structure_change_id);
+ gtk_signal_disconnect (header, etfci->dimension_change_id);
+
+ gtk_object_unref (header);
+ etfci->full_header = NULL;
+ etfci->height = 0;
+}
+
+static void
+structure_changed (ETableHeader *header, ETableFieldChooserItem *etfci)
+{
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+dimension_changed (ETableHeader *header, int col, ETableFieldChooserItem *etfci)
+{
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+etfci_add_table_header (ETableFieldChooserItem *etfci, ETableHeader *header)
+{
+ etfci->full_header = header;
+ gtk_object_ref (GTK_OBJECT (etfci->full_header));
+
+ etfci->structure_change_id = gtk_signal_connect (
+ GTK_OBJECT (header), "structure_change",
+ GTK_SIGNAL_FUNC(structure_changed), etfci);
+ etfci->dimension_change_id = gtk_signal_connect (
+ GTK_OBJECT (header), "dimension_change",
+ GTK_SIGNAL_FUNC(dimension_changed), etfci);
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+etfci_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableFieldChooserItem *etfci;
+
+ item = GNOME_CANVAS_ITEM (o);
+ etfci = E_TABLE_FIELD_CHOOSER_ITEM (o);
+
+ switch (arg_id){
+ case ARG_TABLE_HEADER:
+ etfci_drop_table_header (etfci);
+ etfci_add_table_header (etfci, E_TABLE_HEADER(GTK_VALUE_OBJECT (*arg)));
+ break;
+
+ case ARG_DND_CODE:
+ g_free(etfci->dnd_code);
+ etfci->dnd_code = g_strdup(GTK_VALUE_STRING (*arg));
+ break;
+
+ case ARG_TABLE_FONTSET:
+ etfci_font_load (etfci, GTK_VALUE_STRING (*arg));
+ e_canvas_item_request_reflow(item);
+ break;
+
+ case ARG_WIDTH:
+ etfci->width = GTK_VALUE_DOUBLE (*arg);
+ gnome_canvas_item_request_update(item);
+ break;
+ }
+}
+
+static void
+etfci_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableFieldChooserItem *etfci;
+
+ item = GNOME_CANVAS_ITEM (o);
+ etfci = E_TABLE_FIELD_CHOOSER_ITEM (o);
+
+ switch (arg_id){
+
+ case ARG_DND_CODE:
+ GTK_VALUE_STRING (*arg) = g_strdup (etfci->dnd_code);
+ break;
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = etfci->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = etfci->height;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ 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]),
+ 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);
+ GdkWindow *window;
+
+ if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize)
+ (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item);
+
+ window = GTK_WIDGET (item->canvas)->window;
+
+ if (!etfci->font)
+ etfci_font_load (etfci, NULL);
+
+ etfci->drag_end_id = gtk_signal_connect (
+ GTK_OBJECT (item->canvas), "drag_end",
+ GTK_SIGNAL_FUNC (etfci_drag_end), etfci);
+ etfci->drag_data_get_id = gtk_signal_connect (
+ GTK_OBJECT (item->canvas), "drag_data_get",
+ GTK_SIGNAL_FUNC (etfci_drag_data_get), etfci);
+}
+
+static void
+etfci_unrealize (GnomeCanvasItem *item)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+
+ if (etfci->font)
+ gdk_font_unref (etfci->font);
+ etfci->font = NULL;
+
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), etfci->drag_end_id);
+ etfci->drag_end_id = 0;
+ gtk_signal_disconnect (GTK_OBJECT (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
+draw_button (ETableFieldChooserItem *etfci, ETableCol *col,
+ GdkDrawable *drawable, GtkStyle *style,
+ int x, int y, int width, int height)
+{
+ GdkRectangle clip;
+ int xtra;
+ GdkRectangle area;
+
+ GtkWidget *widget = GTK_WIDGET(GNOME_CANVAS_ITEM(etfci)->canvas);
+
+ gdk_window_clear_area (drawable, x, y, width, height);
+
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
+
+ gtk_paint_box (style, drawable,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ &area, widget, "button",
+ x, y, width, height);
+
+ clip.x = x + HEADER_PADDING / 2;
+ clip.y = y + HEADER_PADDING / 2;
+ clip.width = width - HEADER_PADDING;
+ clip.height = etfci->button_height;
+
+ if (col->is_pixbuf){
+ xtra = (clip.width - gdk_pixbuf_get_width (col->pixbuf))/2;
+
+ xtra += HEADER_PADDING / 2;
+
+ gdk_pixbuf_render_to_drawable_alpha (col->pixbuf,
+ drawable,
+ 0, 0,
+ x + xtra, y + (clip.height - gdk_pixbuf_get_height (col->pixbuf)) / 2,
+ gdk_pixbuf_get_width (col->pixbuf), gdk_pixbuf_get_height(col->pixbuf),
+ GDK_PIXBUF_ALPHA_FULL, 128,
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+ } else {
+ /* Center the thing */
+ xtra = (clip.width - gdk_string_measure (etfci->font, col->text))/2;
+
+ /* Skip over border */
+ if (xtra < 0)
+ xtra = 0;
+
+ xtra += HEADER_PADDING / 2;
+
+ gdk_draw_text (
+ drawable, etfci->font,
+ style->text_gc[GTK_STATE_NORMAL], x + xtra, y + etfci->button_height - etfci->font->descent - HEADER_PADDING / 2,
+ col->text, strlen (col->text));
+ }
+}
+
+static void
+etfci_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ GnomeCanvas *canvas = item->canvas;
+ const int rows = e_table_header_count (etfci->full_header);
+ int y1, y2;
+ int row;
+
+ y1 = y2 = 0;
+ for (row = 0; row < rows; row++, y1 = y2){
+ ETableCol *ecol = e_table_header_get_column (etfci->full_header, row);
+
+ y2 += etfci->button_height;
+
+ if (y1 > (y + height))
+ break;
+
+ if (y2 < y)
+ continue;
+
+ draw_button (etfci, ecol, drawable,
+ GTK_WIDGET (canvas)->style,
+ - x, y1 - y, etfci->width, y2 - y1);
+ }
+}
+
+static double
+etfci_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
+ GnomeCanvasItem **actual_item)
+{
+ *actual_item = item;
+ return 0.0;
+}
+
+static gboolean
+etfci_maybe_start_drag (ETableFieldChooserItem *etfci, double x, double 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)
+{
+ GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas);
+ GtkTargetList *list;
+ GdkDragContext *context;
+ ETableCol *ecol;
+ GdkPixmap *pixmap;
+ int drag_col;
+
+ GtkTargetEntry etfci_drag_types [] = {
+ { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
+ };
+
+ drag_col = event->motion.x / etfci->button_height;
+
+ if (drag_col < 0 || drag_col > e_table_header_count(etfci->full_header))
+ return;
+
+ ecol = e_table_header_get_column (etfci->full_header, drag_col);
+
+ etfci->drag_col = ecol->col_idx;
+
+ etfci_drag_types[0].target = g_strdup_printf("%s-%s", etfci_drag_types[0].target, etfci->dnd_code);
+ list = gtk_target_list_new (etfci_drag_types, ELEMENTS (etfci_drag_types));
+ context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
+ g_free(etfci_drag_types[0].target);
+
+
+ pixmap = gdk_pixmap_new (widget->window, etfci->width, etfci->button_height, -1);
+ draw_button (etfci, ecol, pixmap,
+ widget->style,
+ 0, 0, etfci->width, etfci->button_height);
+ gtk_drag_set_icon_pixmap (context,
+ gdk_window_get_colormap (widget->window),
+ pixmap,
+ NULL,
+ etfci->width / 2,
+ etfci->button_height / 2);
+ gdk_pixmap_unref (pixmap);
+ etfci->maybe_drag = FALSE;
+}
+
+/*
+ * Handles the events on the ETableFieldChooserItem
+ */
+static int
+etfci_event (GnomeCanvasItem *item, GdkEvent *e)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ GnomeCanvas *canvas = item->canvas;
+ int 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);
+ 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 (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+
+ etfci_parent_class = gtk_type_class (PARENT_OBJECT_TYPE);
+
+ object_class->destroy = etfci_destroy;
+ object_class->set_arg = etfci_set_arg;
+ object_class->get_arg = etfci_get_arg;
+
+ 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;
+
+ gtk_object_add_arg_type ("ETableFieldChooserItem::ETableHeader", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::dnd_code", GTK_TYPE_STRING,
+ GTK_ARG_READWRITE, ARG_DND_CODE);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::fontset", GTK_TYPE_STRING,
+ GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+
+}
+
+static void
+etfci_init (GnomeCanvasItem *item)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+
+ etfci->full_header = NULL;
+
+ etfci->height = etfci->width = 0;
+ etfci->button_height = 0;
+
+ etfci->font = NULL;
+
+ etfci->structure_change_id = 0;
+ etfci->dimension_change_id = 0;
+
+ etfci->dnd_code = NULL;
+
+ etfci->maybe_drag = 0;
+ etfci->drag_end_id = 0;
+
+ e_canvas_item_set_reflow_callback(item, etfci_reflow);
+}
+
+GtkType
+e_table_field_chooser_item_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "ETableFieldChooserItem",
+ sizeof (ETableFieldChooserItem),
+ sizeof (ETableFieldChooserItemClass),
+ (GtkClassInitFunc) etfci_class_init,
+ (GtkObjectInitFunc) etfci_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
+ }
+
+ return type;
+}
+
diff --git a/widgets/e-table/e-table-field-chooser-item.h b/widgets/e-table/e-table-field-chooser-item.h
new file mode 100644
index 0000000000..4b349f40e3
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser-item.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_FIELD_CHOOSER_ITEM_H_
+#define _E_TABLE_FIELD_CHOOSER_ITEM_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include <gnome-xml/tree.h>
+#include "e-table-header.h"
+
+#define E_TABLE_FIELD_CHOOSER_ITEM_TYPE (e_table_field_chooser_item_get_type ())
+#define E_TABLE_FIELD_CHOOSER_ITEM(o) (GTK_CHECK_CAST ((o), E_TABLE_FIELD_CHOOSER_ITEM_TYPE, ETableFieldChooserItem))
+#define E_TABLE_FIELD_CHOOSER_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_FIELD_CHOOSER_ITEM_TYPE, ETableFieldChooserItemClass))
+#define E_IS_TABLE_FIELD_CHOOSER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_FIELD_CHOOSER_ITEM_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_FIELD_CHOOSER_ITEM_TYPE))
+
+typedef struct {
+ GnomeCanvasItem parent;
+ ETableHeader *full_header;
+
+ double height, width;
+ double button_height;
+
+ GdkFont *font;
+
+ /*
+ * Ids
+ */
+ int structure_change_id, dimension_change_id;
+
+ gchar *dnd_code;
+
+ /*
+ * For dragging columns
+ */
+ guint maybe_drag:1;
+ int click_x, click_y;
+ int drag_col;
+ guint drag_data_get_id;
+ guint drag_end_id;
+} ETableFieldChooserItem;
+
+typedef struct {
+ GnomeCanvasItemClass parent_class;
+} ETableFieldChooserItemClass;
+
+GtkType e_table_field_chooser_item_get_type (void);
+
+#endif /* _E_TABLE_FIELD_CHOOSER_ITEM_H_ */
diff --git a/widgets/e-table/e-table-field-chooser.c b/widgets/e-table/e-table-field-chooser.c
new file mode 100644
index 0000000000..71582edf58
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-field-chooser.c
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <e-table-field-chooser.h>
+#include <e-table-field-chooser-item.h>
+
+static void e_table_field_chooser_init (ETableFieldChooser *card);
+static void e_table_field_chooser_class_init (ETableFieldChooserClass *klass);
+static void e_table_field_chooser_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_destroy (GtkObject *object);
+
+static GtkVBoxClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+};
+
+GtkType
+e_table_field_chooser_get_type (void)
+{
+ static GtkType table_field_chooser_type = 0;
+
+ if (!table_field_chooser_type)
+ {
+ static const GtkTypeInfo table_field_chooser_info =
+ {
+ "ETableFieldChooser",
+ sizeof (ETableFieldChooser),
+ sizeof (ETableFieldChooserClass),
+ (GtkClassInitFunc) e_table_field_chooser_class_init,
+ (GtkObjectInitFunc) e_table_field_chooser_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ table_field_chooser_type = gtk_type_unique (gtk_vbox_get_type (), &table_field_chooser_info);
+ }
+
+ return table_field_chooser_type;
+}
+
+static void
+e_table_field_chooser_class_init (ETableFieldChooserClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkVBoxClass *vbox_class;
+
+ object_class = (GtkObjectClass*) klass;
+ vbox_class = (GtkVBoxClass *) klass;
+
+ parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+ object_class->set_arg = e_table_field_chooser_set_arg;
+ object_class->get_arg = e_table_field_chooser_get_arg;
+ object_class->destroy = e_table_field_chooser_destroy;
+}
+
+static void
+e_table_field_chooser_init (ETableFieldChooser *e_table_field_chooser)
+{
+ GladeXML *gui;
+ GtkWidget *widget;
+
+ gui = glade_xml_new (ETABLE_GLADEDIR "/fullname.glade", NULL);
+ e_table_field_chooser->gui = gui;
+
+ widget = glade_xml_get_widget(gui, "vbox-top");
+ if (!widget) {
+ return;
+ }
+ gtk_widget_reparent(widget,
+ GTK_WIDGET(e_table_field_chooser));
+
+ e_table_field_chooser->canvas = GNOME_CANVAS(glade_xml_get_widget(gui, "canvas-buttons"));
+ e_table_field_chooser->item = gnome_canvas_item_new(GNOME_CANVAS_GROUP(e_table_field_chooser->canvas->root),
+ e_table_field_chooser_item_get_type(),
+ NULL);
+}
+
+void
+e_table_field_chooser_destroy (GtkObject *object)
+{
+ ETableFieldChooser *e_table_field_chooser = E_TABLE_FIELD_CHOOSER(object);
+
+ if (e_table_field_chooser->gui)
+ gtk_object_unref(GTK_OBJECT(e_table_field_chooser->gui));
+}
+
+GtkWidget*
+e_table_field_chooser_new (void)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_table_field_chooser_get_type ()));
+ return widget;
+}
+
+static void
+e_table_field_chooser_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id){
+ default:
+ break;
+ }
+}
+
+static void
+e_table_field_chooser_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id) {
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/widgets/e-table/e-table-field-chooser.glade b/widgets/e-table/e-table-field-chooser.glade
new file mode 100644
index 0000000000..d179e0cca8
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser.glade
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<GTK-Interface>
+
+<project>
+ <name>e-table-field-chooser</name>
+ <program_name>e-table-field-chooser</program_name>
+ <directory></directory>
+ <source_directory>src</source_directory>
+ <pixmaps_directory>pixmaps</pixmaps_directory>
+ <language>C</language>
+ <gnome_support>True</gnome_support>
+ <gettext_support>True</gettext_support>
+ <use_widget_names>True</use_widget_names>
+ <output_main_file>False</output_main_file>
+ <output_support_files>False</output_support_files>
+ <output_build_files>False</output_build_files>
+ <gnome_help_support>True</gnome_help_support>
+ <output_translatable_strings>True</output_translatable_strings>
+ <translatable_strings_file>e-table-field-chooser.glade.h</translatable_strings_file>
+</project>
+
+<widget>
+ <class>GnomeDialog</class>
+ <name>dialog-field-chooser</name>
+ <visible>False</visible>
+ <title>Field Chooser</title>
+ <type>GTK_WINDOW_TOPLEVEL</type>
+ <position>GTK_WIN_POS_NONE</position>
+ <modal>False</modal>
+ <allow_shrink>False</allow_shrink>
+ <allow_grow>True</allow_grow>
+ <auto_shrink>False</auto_shrink>
+ <auto_close>False</auto_close>
+ <hide_on_close>False</hide_on_close>
+
+ <widget>
+ <class>GtkVBox</class>
+ <child_name>GnomeDialog:vbox</child_name>
+ <name>dialog-vbox1</name>
+ <homogeneous>False</homogeneous>
+ <spacing>8</spacing>
+ <child>
+ <padding>4</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkHButtonBox</class>
+ <child_name>GnomeDialog:action_area</child_name>
+ <name>dialog-action_area1</name>
+ <layout_style>GTK_BUTTONBOX_END</layout_style>
+ <spacing>8</spacing>
+ <child_min_width>85</child_min_width>
+ <child_min_height>27</child_min_height>
+ <child_ipad_x>7</child_ipad_x>
+ <child_ipad_y>0</child_ipad_y>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>True</fill>
+ <pack>GTK_PACK_END</pack>
+ </child>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button3</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
+ </widget>
+ </widget>
+
+ <widget>
+ <class>GtkVBox</class>
+ <name>vbox-top</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkScrolledWindow</class>
+ <name>scrolledwindow1</name>
+ <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
+ <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
+ <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
+ <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GnomeCanvas</class>
+ <name>canvas-buttons</name>
+ <can_focus>True</can_focus>
+ <anti_aliased>False</anti_aliased>
+ <scroll_x1>0</scroll_x1>
+ <scroll_y1>0</scroll_y1>
+ <scroll_x2>100</scroll_x2>
+ <scroll_y2>100</scroll_y2>
+ <pixels_per_unit>1</pixels_per_unit>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+</widget>
+
+</GTK-Interface>
diff --git a/widgets/e-table/e-table-field-chooser.glade.h b/widgets/e-table/e-table-field-chooser.glade.h
new file mode 100644
index 0000000000..344535f180
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser.glade.h
@@ -0,0 +1,7 @@
+/*
+ * Translatable strings file generated by Glade.
+ * Add this file to your project's POTFILES.in.
+ * DO NOT compile it as part of your application.
+ */
+
+gchar *s = N_("Field Chooser");
diff --git a/widgets/e-table/e-table-field-chooser.h b/widgets/e-table/e-table-field-chooser.h
new file mode 100644
index 0000000000..e1d8289824
--- /dev/null
+++ b/widgets/e-table/e-table-field-chooser.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-contact-editor-fullname.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_TABLE_FIELD_CHOOSER_H__
+#define __E_TABLE_FIELD_CHOOSER_H__
+
+#include <gnome.h>
+#include <glade/glade.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+/* ETableFieldChooser - A dialog displaying information about a contact.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ */
+
+#define E_TABLE_FIELD_CHOOSER_TYPE (e_table_field_chooser_get_type ())
+#define E_TABLE_FIELD_CHOOSER(obj) (GTK_CHECK_CAST ((obj), E_TABLE_FIELD_CHOOSER_TYPE, ETableFieldChooser))
+#define E_TABLE_FIELD_CHOOSER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TABLE_FIELD_CHOOSER_TYPE, ETableFieldChooserClass))
+#define E_IS_TABLE_FIELD_CHOOSER(obj) (GTK_CHECK_TYPE ((obj), E_TABLE_FIELD_CHOOSER_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TABLE_FIELD_CHOOSER_TYPE))
+
+
+typedef struct _ETableFieldChooser ETableFieldChooser;
+typedef struct _ETableFieldChooserClass ETableFieldChooserClass;
+
+struct _ETableFieldChooser
+{
+ GtkVBox parent;
+
+ /* item specific fields */
+ GladeXML *gui;
+ GnomeCanvas *canvas;
+ GnomeCanvasItem *item;
+};
+
+struct _ETableFieldChooserClass
+{
+ GtkVBoxClass parent_class;
+};
+
+
+GtkWidget *e_table_field_chooser_new(void);
+GtkType e_table_field_chooser_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __E_TABLE_FIELD_CHOOSER_H__ */
diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c
index 6d3329ab11..26ed69c73c 100644
--- a/widgets/e-table/e-table-header-item.c
+++ b/widgets/e-table/e-table-header-item.c
@@ -38,11 +38,6 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, };
#define ARROW_DOWN_HEIGHT 16
#define ARROW_PTR 7
-/* Padding above and below of the string in the header display */
-#define PADDING 4
-
-#define MIN_ARROW_SIZE 10
-
/* Defines the tolerance for proximity of the column division to the cursor position */
#define TOLERANCE 4
@@ -54,7 +49,6 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, };
static GnomeCanvasItemClass *ethi_parent_class;
-static void ethi_request_redraw (ETableHeaderItem *ethi);
static void ethi_drop_table_header (ETableHeaderItem *ethi);
/*
@@ -73,20 +67,11 @@ static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
- ARG_TABLE_X,
- ARG_TABLE_Y,
+ ARG_DND_CODE,
ARG_TABLE_FONTSET,
ARG_SORT_INFO
};
-static GtkTargetEntry ethi_drag_types [] = {
- { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
-};
-
-static GtkTargetEntry ethi_drop_types [] = {
- { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
-};
-
static void
ethi_destroy (GtkObject *object){
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (object);
@@ -110,9 +95,13 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
+ double i2c [6];
+ ArtPoint c1, c2, i1, i2;
+
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, affine, clip_path, flags);
+
if (ethi->sort_info)
ethi->group_indent_width = e_table_sort_info_grouping_get_count(ethi->sort_info) * GROUP_INDENT;
else
@@ -120,16 +109,24 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags
ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width;
- if (item->x1 != ethi->x1 ||
- item->y1 != ethi->y1 ||
- item->x2 != ethi->x1 + ethi->width ||
- item->y2 != ethi->y1 + ethi->height)
+ i1.x = i1.y = 0;
+ i2.x = ethi->width;
+ i2.y = ethi->height;
+
+ gnome_canvas_item_i2c_affine (item, i2c);
+ art_affine_point (&c1, &i1, i2c);
+ art_affine_point (&c2, &i2, i2c);
+
+ if (item->x1 != c1.x ||
+ item->y1 != c1.y ||
+ item->x2 != c2.x ||
+ item->y2 != c2.y)
{
gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
- item->x1 = ethi->x1;
- item->y1 = ethi->y1;
- item->x2 = ethi->x1 + ethi->width;
- item->y2 = ethi->y1 + ethi->height;
+ item->x1 = c1.x;
+ item->y1 = c1.y;
+ item->x2 = c2.x;
+ item->y2 = c2.y;
gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
}
@@ -146,9 +143,9 @@ ethi_font_load (ETableHeaderItem *ethi, char *font)
if (ethi->font == NULL)
ethi->font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1");
- ethi->height = ethi->font->ascent + ethi->font->descent + PADDING;
- if (ethi->height < MIN_ARROW_SIZE + 4 + PADDING)
- ethi->height = MIN_ARROW_SIZE + 4 + PADDING;
+ ethi->height = ethi->font->ascent + ethi->font->descent + HEADER_PADDING;
+ if (ethi->height < MIN_ARROW_SIZE + 4 + HEADER_PADDING)
+ ethi->height = MIN_ARROW_SIZE + 4 + HEADER_PADDING;
}
static void
@@ -216,12 +213,9 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
ethi_add_table_header (ethi, E_TABLE_HEADER(GTK_VALUE_OBJECT (*arg)));
break;
- case ARG_TABLE_X:
- ethi->x1 = GTK_VALUE_INT (*arg);
- break;
-
- case ARG_TABLE_Y:
- ethi->y1 = GTK_VALUE_INT (*arg);
+ case ARG_DND_CODE:
+ g_free(ethi->dnd_code);
+ ethi->dnd_code = g_strdup (GTK_VALUE_STRING (*arg));
break;
case ARG_TABLE_FONTSET:
@@ -254,14 +248,31 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
break;
}
- ethi_update (item, NULL, NULL, 0);
+ gnome_canvas_item_request_update(item);
+}
+
+static void
+ethi_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableHeaderItem *ethi;
+
+ ethi = E_TABLE_HEADER_ITEM (o);
+
+ switch (arg_id){
+ case ARG_DND_CODE:
+ GTK_VALUE_STRING (*arg) = g_strdup (ethi->dnd_code);
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
- int x1 = ethi->x1;
+ int x1 = 0;
int col;
if (x < x1)
@@ -292,65 +303,6 @@ ethi_remove_drop_marker (ETableHeaderItem *ethi)
ethi->drag_mark = -1;
}
-#if 0
-static void
-ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
-{
- GnomeCanvasPoints *points;
- int x;
-
- if (ethi->drag_mark == col)
- return;
-
- if (ethi->drag_mark_item)
- gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
-
- ethi->drag_mark = col;
-
- ethi->drag_mark_item = gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
- gnome_canvas_group_get_type (),
- "x", 0,
- "y", 0,
- NULL);
-
- points = gnome_canvas_points_new (3);
-
- x = e_table_header_col_diff (ethi->eth, 0, col);
-
- if (col > 0)
- x += ethi->group_indent_width;
-
- points->coords [0] = ethi->x1 + x - 5;
- points->coords [1] = ethi->y1;
- points->coords [2] = points->coords [0] + 10;
- points->coords [3] = points->coords [1];
- points->coords [4] = ethi->x1 + x;
- points->coords [5] = ethi->y1 + 5;
-
- gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (ethi->drag_mark_item),
- gnome_canvas_polygon_get_type (),
- "points", points,
- "fill_color", "red",
- NULL);
-
- points->coords [0] --;
- points->coords [1] += ethi->height - 1;
- points->coords [3] = points->coords [1];
- points->coords [5] = points->coords [1] - 6;
-
- gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (ethi->drag_mark_item),
- gnome_canvas_polygon_get_type (),
- "points", points,
- "fill_color", "red",
- NULL);
-
- gnome_canvas_points_unref (points);
-}
-#endif
-
static GtkWidget *
make_shapped_window_from_xpm (const char **xpm)
{
@@ -427,7 +379,7 @@ ethi_add_destroy_marker (ETableHeaderItem *ethi)
ethi->stipple = gdk_bitmap_create_from_data (
NULL, gray50_bits, gray50_width, gray50_height);
- x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
+ x1 = (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
if (ethi->drag_col > 0)
x1 += ethi->group_indent_width;
@@ -435,11 +387,11 @@ ethi_add_destroy_marker (ETableHeaderItem *ethi)
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
- "y1", (double) ethi->y1 + 1,
+ "y1", (double) 1,
"x2", (double) x1 + e_table_header_col_diff (
ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
- "y2", (double) ethi->y1 + ethi->height - 2,
+ "y2", (double) ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
@@ -465,8 +417,8 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
return FALSE;
gdk_drag_status (context, 0, time);
- if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
- (y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
+ if ((x >= 0) && (x <= (ethi->width)) &&
+ (y >= 0) && (y <= (ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
@@ -493,15 +445,48 @@ ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *eth
if (ethi->drag_col == -1)
return;
- /* if (canvas == gtk_drag_get_source_widget (context)) { */
if (context->action == 0) {
- ethi_request_redraw (ethi);
e_table_header_remove (ethi->eth, ethi->drag_col);
+ gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
}
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
- /* } */
+}
+
+static void
+ethi_drag_data_received (GtkWidget *canvas,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ ETableHeaderItem *ethi)
+{
+ e_table_header_move (ethi->eth, ethi->drag_col, ethi->drop_col);
+ 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]),
+ string,
+ strlen(string));
+ g_free(string);
+ }
}
static gboolean
@@ -517,24 +502,22 @@ ethi_drag_drop (GtkWidget *canvas,
if (ethi->drag_col == -1)
return FALSE;
- /* if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget (context)) {*/
- if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
- (y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
+ if ((x >= 0) && (x <= (ethi->width)) &&
+ (y >= 0) && (y <= (ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
ethi_add_drop_marker (ethi, col);
+
+ ethi->drop_col = col;
if (col != -1) {
- if (col != ethi->drag_col) {
- ethi_request_redraw (ethi);
- e_table_header_move (ethi->eth, ethi->drag_col, col);
- }
- successful = TRUE;
+ char *target = g_strdup_printf ("%s-%s", TARGET_ETABLE_COL_TYPE, ethi->dnd_code);
+ gtk_drag_get_data (canvas, context, gdk_atom_intern(target, FALSE), time);
+ g_free (target);
}
}
- /* } */
gtk_drag_finish (context, successful, successful, time);
return successful;
}
@@ -545,10 +528,8 @@ ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableH
if (ethi->drag_col == -1)
return;
- /* if (widget == gtk_drag_get_source_widget (context)) { */
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
- /* } */
}
static void
@@ -557,6 +538,10 @@ ethi_realize (GnomeCanvasItem *item)
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
+ GtkTargetEntry ethi_drop_types [] = {
+ { 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);
@@ -573,25 +558,28 @@ ethi_realize (GnomeCanvasItem *item)
/*
* 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, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
+ g_free(ethi_drop_types[0].target);
+
+ /* Drop signals */
+ ethi->drag_motion_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_motion",
+ GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
+ ethi->drag_leave_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_leave",
+ GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
+ ethi->drag_drop_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_drop",
+ GTK_SIGNAL_FUNC (ethi_drag_drop), ethi);
+ ethi->drag_data_received_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_data_received",
+ GTK_SIGNAL_FUNC (ethi_drag_data_received), ethi);
+
+ /* Drag signals */
+ ethi->drag_end_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_end",
+ GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
+ ethi->drag_data_get_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_data_get",
+ GTK_SIGNAL_FUNC (ethi_drag_data_get), ethi);
- ethi->drag_motion_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_motion",
- GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
-
- ethi->drag_leave_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_leave",
- GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
-
- ethi->drag_end_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_end",
- GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
-
- ethi->drag_drop_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_drop",
- GTK_SIGNAL_FUNC (ethi_drag_drop), ethi);
}
static void
@@ -603,9 +591,12 @@ ethi_unrealize (GnomeCanvasItem *item)
ethi->gc = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
- gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_drop_id);
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_data_received_id);
+
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_data_get_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
@@ -633,9 +624,9 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x , y, width, height);
- clip.x = x + PADDING / 2;
- clip.y = y + PADDING / 2;
- clip.width = width - PADDING;
+ clip.x = x + HEADER_PADDING / 2;
+ clip.y = y + HEADER_PADDING / 2;
+ clip.width = width - HEADER_PADDING;
clip.height = ethi->height;
gdk_gc_set_clip_rectangle (ethi->gc, &clip);
@@ -643,7 +634,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
if (col->is_pixbuf){
xtra = (clip.width - gdk_pixbuf_get_width (col->pixbuf))/2;
- xtra += PADDING / 2;
+ xtra += HEADER_PADDING / 2;
gdk_pixbuf_render_to_drawable_alpha (col->pixbuf,
drawable,
@@ -661,11 +652,11 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
if (xtra < 0)
xtra = 0;
- xtra += PADDING / 2;
+ xtra += HEADER_PADDING / 2;
gdk_draw_text (
drawable, ethi->font,
- ethi->gc, x + xtra, y + ethi->height - ethi->font->descent - PADDING / 2,
+ ethi->gc, x + xtra, y + ethi->height - ethi->font->descent - HEADER_PADDING / 2,
col->text, strlen (col->text));
}
@@ -690,7 +681,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
"header",
(arrow == E_TABLE_COL_ARROW_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN,
TRUE,
- x + PADDING / 2 + clip.width - MIN_ARROW_SIZE - 2,
+ x + HEADER_PADDING / 2 + clip.width - MIN_ARROW_SIZE - 2,
y + (ethi->height - MIN_ARROW_SIZE) / 2,
MIN_ARROW_SIZE,
MIN_ARROW_SIZE);
@@ -733,7 +724,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
}
ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width;
- x1 = x2 = ethi->x1;
+ x1 = x2 = 0;
x2 += ethi->group_indent_width;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
@@ -753,7 +744,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
- x1 - x, ethi->y1 - y, x2 - x1, ethi->height,
+ x1 - x, - y, x2 - x1, ethi->height,
(ETableColArrow) g_hash_table_lookup (arrows, (gpointer) ecol->col_idx));
}
g_hash_table_destroy (arrows);
@@ -823,18 +814,6 @@ set_cursor (ETableHeaderItem *ethi, int pos)
}
static void
-ethi_request_redraw (ETableHeaderItem *ethi)
-{
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (ethi)->canvas;
-
- /*
- * request a redraw
- */
- gnome_canvas_request_redraw (
- canvas, ethi->x1, ethi->y1, ethi->x1 + ethi->width, ethi->x1 + ethi->height);
-}
-
-static void
ethi_end_resize (ETableHeaderItem *ethi)
{
ethi->resize_col = -1;
@@ -872,6 +851,10 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
int group_indent = 0;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
+ GtkTargetEntry ethi_drag_types [] = {
+ { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
+ };
+
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
@@ -900,8 +883,10 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
}
}
+ 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, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
+ g_free(ethi_drag_types[0].target);
ecol = e_table_header_get_column (ethi->eth, ethi->drag_col);
col_width = ecol->width;
@@ -1269,6 +1254,7 @@ ethi_class_init (GtkObjectClass *object_class)
object_class->destroy = ethi_destroy;
object_class->set_arg = ethi_set_arg;
+ object_class->get_arg = ethi_get_arg;
item_class->update = ethi_update;
item_class->realize = ethi_realize;
@@ -1279,10 +1265,8 @@ ethi_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_OBJECT,
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
- gtk_object_add_arg_type ("ETableHeaderItem::x", GTK_TYPE_INT,
- GTK_ARG_WRITABLE, ARG_TABLE_X);
- gtk_object_add_arg_type ("ETableHeaderItem::y", GTK_TYPE_INT,
- GTK_ARG_WRITABLE, ARG_TABLE_Y);
+ gtk_object_add_arg_type ("ETableHeaderItem::dnd_code", GTK_TYPE_STRING,
+ GTK_ARG_WRITABLE, ARG_DND_CODE);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
gtk_object_add_arg_type ("ETableHeaderItem::sort_info", GTK_TYPE_OBJECT,
@@ -1355,4 +1339,3 @@ e_table_header_item_get_type (void)
return type;
}
-
diff --git a/widgets/e-table/e-table-header-item.h b/widgets/e-table/e-table-header-item.h
index 300a7c81fb..15b627bfa9 100644
--- a/widgets/e-table/e-table-header-item.h
+++ b/widgets/e-table/e-table-header-item.h
@@ -20,7 +20,7 @@ typedef struct {
GdkGC *gc;
GdkCursor *change_cursor;
- short x1, y1, height, width;
+ short height, width;
GdkFont *font;
/*
@@ -45,16 +45,21 @@ typedef struct {
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
- int drag_col, drag_mark;
- guint drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id;
+ int drag_col, drop_col, drag_mark;
+ guint drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id, drag_data_received_id, drag_data_get_id;
guint sort_info_changed_id, group_info_changed_id;
GnomeCanvasItem *remove_item;
GdkBitmap *stipple;
+ gchar *dnd_code;
+
/*
* For column sorting info
*/
ETableSortInfo *sort_info;
+
+ /* For adding fields. */
+ ETableHeader *full_header;
} ETableHeaderItem;
typedef struct {
diff --git a/widgets/table/e-table-defines.h b/widgets/table/e-table-defines.h
index 02f1d19b77..9eb797dd66 100644
--- a/widgets/table/e-table-defines.h
+++ b/widgets/table/e-table-defines.h
@@ -1,3 +1,9 @@
#define BUTTON_HEIGHT 10
#define BUTTON_PADDING 2
#define GROUP_INDENT (BUTTON_HEIGHT + (BUTTON_PADDING * 2))
+
+/* Padding above and below of the string in the header display */
+#define HEADER_PADDING 4
+
+#define MIN_ARROW_SIZE 10
+
diff --git a/widgets/table/e-table-field-chooser-dialog.c b/widgets/table/e-table-field-chooser-dialog.c
new file mode 100644
index 0000000000..6fbc5ba38c
--- /dev/null
+++ b/widgets/table/e-table-field-chooser-dialog.c
@@ -0,0 +1,108 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-field-chooser-dialog.c
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <e-table-field-chooser-dialog.h>
+
+static void e_table_field_chooser_dialog_init (ETableFieldChooserDialog *card);
+static void e_table_field_chooser_dialog_class_init (ETableFieldChooserDialogClass *klass);
+static void e_table_field_chooser_dialog_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static GnomeDialogClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+};
+
+GtkType
+e_table_field_chooser_dialog_get_type (void)
+{
+ static GtkType table_field_chooser_dialog_type = 0;
+
+ if (!table_field_chooser_dialog_type)
+ {
+ static const GtkTypeInfo table_field_chooser_dialog_info =
+ {
+ "ETableFieldChooserDialog",
+ sizeof (ETableFieldChooserDialog),
+ sizeof (ETableFieldChooserDialogClass),
+ (GtkClassInitFunc) e_table_field_chooser_dialog_class_init,
+ (GtkObjectInitFunc) e_table_field_chooser_dialog_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ table_field_chooser_dialog_type = gtk_type_unique (gtk_vbox_get_type (), &table_field_chooser_dialog_info);
+ }
+
+ return table_field_chooser_dialog_type;
+}
+
+static void
+e_table_field_chooser_dialog_class_init (ETableFieldChooserDialogClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkVBoxClass *vbox_class;
+
+ object_class = (GtkObjectClass*) klass;
+ vbox_class = (GtkVBoxClass *) klass;
+
+ parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+ object_class->set_arg = e_table_field_chooser_dialog_set_arg;
+ object_class->get_arg = e_table_field_chooser_dialog_get_arg;
+}
+
+static void
+e_table_field_chooser_dialog_init (ETableFieldChooserDialog *e_table_field_chooser_dialog)
+{
+}
+
+GtkWidget*
+e_table_field_chooser_dialog_new (void)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_table_field_chooser_dialog_get_type ()));
+ return widget;
+}
+
+static void
+e_table_field_chooser_dialog_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id){
+ default:
+ break;
+ }
+}
+
+static void
+e_table_field_chooser_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id) {
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/widgets/table/e-table-field-chooser-dialog.h b/widgets/table/e-table-field-chooser-dialog.h
new file mode 100644
index 0000000000..3a23f13bb5
--- /dev/null
+++ b/widgets/table/e-table-field-chooser-dialog.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-table-field-chooser-dialog.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_TABLE_FIELD_CHOOSER_DIALOG_H__
+#define __E_TABLE_FIELD_CHOOSER_DIALOG_H__
+
+#include <gnome.h>
+#include <glade/glade.h>
+#include "e-table-field-chooser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+/* ETableFieldChooserDialog - A dialog displaying information about a contact.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ */
+
+#define E_TABLE_FIELD_CHOOSER_DIALOG_TYPE (e_table_field_chooser_dialog_get_type ())
+#define E_TABLE_FIELD_CHOOSER_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE, ETableFieldChooserDialog))
+#define E_TABLE_FIELD_CHOOSER_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE, ETableFieldChooserDialogClass))
+#define E_IS_TABLE_FIELD_CHOOSER_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TABLE_FIELD_CHOOSER_DIALOG_TYPE))
+
+
+typedef struct _ETableFieldChooserDialog ETableFieldChooserDialog;
+typedef struct _ETableFieldChooserDialogClass ETableFieldChooserDialogClass;
+
+struct _ETableFieldChooserDialog
+{
+ GnomeDialog parent;
+
+ /* item specific fields */
+ ETableFieldChooser *chooser;
+};
+
+struct _ETableFieldChooserDialogClass
+{
+ GnomeDialogClass parent_class;
+};
+
+
+GtkWidget *e_table_field_chooser_dialog_new(void);
+GtkType e_table_field_chooser_dialog_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#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
new file mode 100644
index 0000000000..fd08af3307
--- /dev/null
+++ b/widgets/table/e-table-field-chooser-item.c
@@ -0,0 +1,567 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-table-column-view.c: A canvas item based view of the ETableColumn.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * Copyright 1999, 2000 Helix Code, Inc.
+ */
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkdnd.h>
+#include <libgnomeui/gnome-canvas.h>
+#include <libgnomeui/gnome-canvas-util.h>
+#include <libgnomeui/gnome-canvas-polygon.h>
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "e-util/e-xml-utils.h"
+#include "e-util/e-canvas.h"
+
+#include "e-table-header.h"
+#include "e-table-col-dnd.h"
+#include "e-table-defines.h"
+
+#include "e-table-field-chooser-item.h"
+
+#if 0
+enum {
+ BUTTON_PRESSED,
+ LAST_SIGNAL
+};
+
+static guint etfci_signals [LAST_SIGNAL] = { 0, };
+#endif
+
+#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
+
+#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
+
+static GnomeCanvasItemClass *etfci_parent_class;
+
+static void etfci_drop_table_header (ETableFieldChooserItem *etfci);
+
+enum {
+ ARG_0,
+ ARG_TABLE_HEADER,
+ ARG_DND_CODE,
+ ARG_TABLE_FONTSET,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+};
+
+static void
+etfci_destroy (GtkObject *object){
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (object);
+
+ etfci_drop_table_header (etfci);
+
+ gdk_font_unref(etfci->font);
+
+ if (GTK_OBJECT_CLASS (etfci_parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (etfci_parent_class)->destroy) (object);
+}
+
+static void
+etfci_reflow (GnomeCanvasItem *item, gint flags)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ double old_height;
+
+ old_height = etfci->height;
+
+ etfci->height = e_table_header_count (etfci->full_header) * etfci->button_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, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ double i2c [6];
+ ArtPoint c1, c2, i1, i2;
+
+ if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)
+ (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)(item, affine, clip_path, flags);
+
+ i1.x = i1.y = 0;
+ i2.x = etfci->width;
+ i2.y = etfci->height;
+
+ gnome_canvas_item_i2c_affine (item, i2c);
+ art_affine_point (&c1, &i1, i2c);
+ art_affine_point (&c2, &i2, i2c);
+
+ if (item->x1 != c1.x ||
+ item->y1 != c1.y ||
+ item->x2 != c2.x ||
+ item->y2 != c2.y)
+ {
+ gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+ item->x1 = c1.x;
+ item->y1 = c1.y;
+ item->x2 = c2.x;
+ item->y2 = c2.y;
+
+ gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
+ }
+ gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+}
+
+static void
+etfci_font_load (ETableFieldChooserItem *etfci, char *font)
+{
+ if (etfci->font)
+ gdk_font_unref (etfci->font);
+ etfci->font = NULL;
+
+ if (font)
+ etfci->font = gdk_fontset_load (font);
+
+ if (etfci->font == NULL) {
+ etfci->font = GTK_WIDGET(GNOME_CANVAS_ITEM(etfci)->canvas)->style->font;
+ gdk_font_ref(etfci->font);
+ }
+
+ etfci->button_height = etfci->font->ascent + etfci->font->descent + HEADER_PADDING;
+}
+
+static void
+etfci_drop_table_header (ETableFieldChooserItem *etfci)
+{
+ GtkObject *header;
+
+ if (!etfci->full_header)
+ return;
+
+ header = GTK_OBJECT (etfci->full_header);
+ gtk_signal_disconnect (header, etfci->structure_change_id);
+ gtk_signal_disconnect (header, etfci->dimension_change_id);
+
+ gtk_object_unref (header);
+ etfci->full_header = NULL;
+ etfci->height = 0;
+}
+
+static void
+structure_changed (ETableHeader *header, ETableFieldChooserItem *etfci)
+{
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+dimension_changed (ETableHeader *header, int col, ETableFieldChooserItem *etfci)
+{
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+etfci_add_table_header (ETableFieldChooserItem *etfci, ETableHeader *header)
+{
+ etfci->full_header = header;
+ gtk_object_ref (GTK_OBJECT (etfci->full_header));
+
+ etfci->structure_change_id = gtk_signal_connect (
+ GTK_OBJECT (header), "structure_change",
+ GTK_SIGNAL_FUNC(structure_changed), etfci);
+ etfci->dimension_change_id = gtk_signal_connect (
+ GTK_OBJECT (header), "dimension_change",
+ GTK_SIGNAL_FUNC(dimension_changed), etfci);
+ e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+}
+
+static void
+etfci_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableFieldChooserItem *etfci;
+
+ item = GNOME_CANVAS_ITEM (o);
+ etfci = E_TABLE_FIELD_CHOOSER_ITEM (o);
+
+ switch (arg_id){
+ case ARG_TABLE_HEADER:
+ etfci_drop_table_header (etfci);
+ etfci_add_table_header (etfci, E_TABLE_HEADER(GTK_VALUE_OBJECT (*arg)));
+ break;
+
+ case ARG_DND_CODE:
+ g_free(etfci->dnd_code);
+ etfci->dnd_code = g_strdup(GTK_VALUE_STRING (*arg));
+ break;
+
+ case ARG_TABLE_FONTSET:
+ etfci_font_load (etfci, GTK_VALUE_STRING (*arg));
+ e_canvas_item_request_reflow(item);
+ break;
+
+ case ARG_WIDTH:
+ etfci->width = GTK_VALUE_DOUBLE (*arg);
+ gnome_canvas_item_request_update(item);
+ break;
+ }
+}
+
+static void
+etfci_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableFieldChooserItem *etfci;
+
+ item = GNOME_CANVAS_ITEM (o);
+ etfci = E_TABLE_FIELD_CHOOSER_ITEM (o);
+
+ switch (arg_id){
+
+ case ARG_DND_CODE:
+ GTK_VALUE_STRING (*arg) = g_strdup (etfci->dnd_code);
+ break;
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = etfci->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = etfci->height;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ 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]),
+ 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);
+ GdkWindow *window;
+
+ if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize)
+ (*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item);
+
+ window = GTK_WIDGET (item->canvas)->window;
+
+ if (!etfci->font)
+ etfci_font_load (etfci, NULL);
+
+ etfci->drag_end_id = gtk_signal_connect (
+ GTK_OBJECT (item->canvas), "drag_end",
+ GTK_SIGNAL_FUNC (etfci_drag_end), etfci);
+ etfci->drag_data_get_id = gtk_signal_connect (
+ GTK_OBJECT (item->canvas), "drag_data_get",
+ GTK_SIGNAL_FUNC (etfci_drag_data_get), etfci);
+}
+
+static void
+etfci_unrealize (GnomeCanvasItem *item)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+
+ if (etfci->font)
+ gdk_font_unref (etfci->font);
+ etfci->font = NULL;
+
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), etfci->drag_end_id);
+ etfci->drag_end_id = 0;
+ gtk_signal_disconnect (GTK_OBJECT (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
+draw_button (ETableFieldChooserItem *etfci, ETableCol *col,
+ GdkDrawable *drawable, GtkStyle *style,
+ int x, int y, int width, int height)
+{
+ GdkRectangle clip;
+ int xtra;
+ GdkRectangle area;
+
+ GtkWidget *widget = GTK_WIDGET(GNOME_CANVAS_ITEM(etfci)->canvas);
+
+ gdk_window_clear_area (drawable, x, y, width, height);
+
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
+
+ gtk_paint_box (style, drawable,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ &area, widget, "button",
+ x, y, width, height);
+
+ clip.x = x + HEADER_PADDING / 2;
+ clip.y = y + HEADER_PADDING / 2;
+ clip.width = width - HEADER_PADDING;
+ clip.height = etfci->button_height;
+
+ if (col->is_pixbuf){
+ xtra = (clip.width - gdk_pixbuf_get_width (col->pixbuf))/2;
+
+ xtra += HEADER_PADDING / 2;
+
+ gdk_pixbuf_render_to_drawable_alpha (col->pixbuf,
+ drawable,
+ 0, 0,
+ x + xtra, y + (clip.height - gdk_pixbuf_get_height (col->pixbuf)) / 2,
+ gdk_pixbuf_get_width (col->pixbuf), gdk_pixbuf_get_height(col->pixbuf),
+ GDK_PIXBUF_ALPHA_FULL, 128,
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+ } else {
+ /* Center the thing */
+ xtra = (clip.width - gdk_string_measure (etfci->font, col->text))/2;
+
+ /* Skip over border */
+ if (xtra < 0)
+ xtra = 0;
+
+ xtra += HEADER_PADDING / 2;
+
+ gdk_draw_text (
+ drawable, etfci->font,
+ style->text_gc[GTK_STATE_NORMAL], x + xtra, y + etfci->button_height - etfci->font->descent - HEADER_PADDING / 2,
+ col->text, strlen (col->text));
+ }
+}
+
+static void
+etfci_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ GnomeCanvas *canvas = item->canvas;
+ const int rows = e_table_header_count (etfci->full_header);
+ int y1, y2;
+ int row;
+
+ y1 = y2 = 0;
+ for (row = 0; row < rows; row++, y1 = y2){
+ ETableCol *ecol = e_table_header_get_column (etfci->full_header, row);
+
+ y2 += etfci->button_height;
+
+ if (y1 > (y + height))
+ break;
+
+ if (y2 < y)
+ continue;
+
+ draw_button (etfci, ecol, drawable,
+ GTK_WIDGET (canvas)->style,
+ - x, y1 - y, etfci->width, y2 - y1);
+ }
+}
+
+static double
+etfci_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
+ GnomeCanvasItem **actual_item)
+{
+ *actual_item = item;
+ return 0.0;
+}
+
+static gboolean
+etfci_maybe_start_drag (ETableFieldChooserItem *etfci, double x, double 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)
+{
+ GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas);
+ GtkTargetList *list;
+ GdkDragContext *context;
+ ETableCol *ecol;
+ GdkPixmap *pixmap;
+ int drag_col;
+
+ GtkTargetEntry etfci_drag_types [] = {
+ { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
+ };
+
+ drag_col = event->motion.x / etfci->button_height;
+
+ if (drag_col < 0 || drag_col > e_table_header_count(etfci->full_header))
+ return;
+
+ ecol = e_table_header_get_column (etfci->full_header, drag_col);
+
+ etfci->drag_col = ecol->col_idx;
+
+ etfci_drag_types[0].target = g_strdup_printf("%s-%s", etfci_drag_types[0].target, etfci->dnd_code);
+ list = gtk_target_list_new (etfci_drag_types, ELEMENTS (etfci_drag_types));
+ context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
+ g_free(etfci_drag_types[0].target);
+
+
+ pixmap = gdk_pixmap_new (widget->window, etfci->width, etfci->button_height, -1);
+ draw_button (etfci, ecol, pixmap,
+ widget->style,
+ 0, 0, etfci->width, etfci->button_height);
+ gtk_drag_set_icon_pixmap (context,
+ gdk_window_get_colormap (widget->window),
+ pixmap,
+ NULL,
+ etfci->width / 2,
+ etfci->button_height / 2);
+ gdk_pixmap_unref (pixmap);
+ etfci->maybe_drag = FALSE;
+}
+
+/*
+ * Handles the events on the ETableFieldChooserItem
+ */
+static int
+etfci_event (GnomeCanvasItem *item, GdkEvent *e)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+ GnomeCanvas *canvas = item->canvas;
+ int 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);
+ 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 (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+
+ etfci_parent_class = gtk_type_class (PARENT_OBJECT_TYPE);
+
+ object_class->destroy = etfci_destroy;
+ object_class->set_arg = etfci_set_arg;
+ object_class->get_arg = etfci_get_arg;
+
+ 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;
+
+ gtk_object_add_arg_type ("ETableFieldChooserItem::ETableHeader", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::dnd_code", GTK_TYPE_STRING,
+ GTK_ARG_READWRITE, ARG_DND_CODE);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::fontset", GTK_TYPE_STRING,
+ GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableFieldChooserItem::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+
+}
+
+static void
+etfci_init (GnomeCanvasItem *item)
+{
+ ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
+
+ etfci->full_header = NULL;
+
+ etfci->height = etfci->width = 0;
+ etfci->button_height = 0;
+
+ etfci->font = NULL;
+
+ etfci->structure_change_id = 0;
+ etfci->dimension_change_id = 0;
+
+ etfci->dnd_code = NULL;
+
+ etfci->maybe_drag = 0;
+ etfci->drag_end_id = 0;
+
+ e_canvas_item_set_reflow_callback(item, etfci_reflow);
+}
+
+GtkType
+e_table_field_chooser_item_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "ETableFieldChooserItem",
+ sizeof (ETableFieldChooserItem),
+ sizeof (ETableFieldChooserItemClass),
+ (GtkClassInitFunc) etfci_class_init,
+ (GtkObjectInitFunc) etfci_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
+ }
+
+ return type;
+}
+
diff --git a/widgets/table/e-table-field-chooser-item.h b/widgets/table/e-table-field-chooser-item.h
new file mode 100644
index 0000000000..4b349f40e3
--- /dev/null
+++ b/widgets/table/e-table-field-chooser-item.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_FIELD_CHOOSER_ITEM_H_
+#define _E_TABLE_FIELD_CHOOSER_ITEM_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include <gnome-xml/tree.h>
+#include "e-table-header.h"
+
+#define E_TABLE_FIELD_CHOOSER_ITEM_TYPE (e_table_field_chooser_item_get_type ())
+#define E_TABLE_FIELD_CHOOSER_ITEM(o) (GTK_CHECK_CAST ((o), E_TABLE_FIELD_CHOOSER_ITEM_TYPE, ETableFieldChooserItem))
+#define E_TABLE_FIELD_CHOOSER_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_FIELD_CHOOSER_ITEM_TYPE, ETableFieldChooserItemClass))
+#define E_IS_TABLE_FIELD_CHOOSER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_FIELD_CHOOSER_ITEM_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_FIELD_CHOOSER_ITEM_TYPE))
+
+typedef struct {
+ GnomeCanvasItem parent;
+ ETableHeader *full_header;
+
+ double height, width;
+ double button_height;
+
+ GdkFont *font;
+
+ /*
+ * Ids
+ */
+ int structure_change_id, dimension_change_id;
+
+ gchar *dnd_code;
+
+ /*
+ * For dragging columns
+ */
+ guint maybe_drag:1;
+ int click_x, click_y;
+ int drag_col;
+ guint drag_data_get_id;
+ guint drag_end_id;
+} ETableFieldChooserItem;
+
+typedef struct {
+ GnomeCanvasItemClass parent_class;
+} ETableFieldChooserItemClass;
+
+GtkType e_table_field_chooser_item_get_type (void);
+
+#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
new file mode 100644
index 0000000000..71582edf58
--- /dev/null
+++ b/widgets/table/e-table-field-chooser.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-field-chooser.c
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <e-table-field-chooser.h>
+#include <e-table-field-chooser-item.h>
+
+static void e_table_field_chooser_init (ETableFieldChooser *card);
+static void e_table_field_chooser_class_init (ETableFieldChooserClass *klass);
+static void e_table_field_chooser_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void e_table_field_chooser_destroy (GtkObject *object);
+
+static GtkVBoxClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+};
+
+GtkType
+e_table_field_chooser_get_type (void)
+{
+ static GtkType table_field_chooser_type = 0;
+
+ if (!table_field_chooser_type)
+ {
+ static const GtkTypeInfo table_field_chooser_info =
+ {
+ "ETableFieldChooser",
+ sizeof (ETableFieldChooser),
+ sizeof (ETableFieldChooserClass),
+ (GtkClassInitFunc) e_table_field_chooser_class_init,
+ (GtkObjectInitFunc) e_table_field_chooser_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ table_field_chooser_type = gtk_type_unique (gtk_vbox_get_type (), &table_field_chooser_info);
+ }
+
+ return table_field_chooser_type;
+}
+
+static void
+e_table_field_chooser_class_init (ETableFieldChooserClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkVBoxClass *vbox_class;
+
+ object_class = (GtkObjectClass*) klass;
+ vbox_class = (GtkVBoxClass *) klass;
+
+ parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+ object_class->set_arg = e_table_field_chooser_set_arg;
+ object_class->get_arg = e_table_field_chooser_get_arg;
+ object_class->destroy = e_table_field_chooser_destroy;
+}
+
+static void
+e_table_field_chooser_init (ETableFieldChooser *e_table_field_chooser)
+{
+ GladeXML *gui;
+ GtkWidget *widget;
+
+ gui = glade_xml_new (ETABLE_GLADEDIR "/fullname.glade", NULL);
+ e_table_field_chooser->gui = gui;
+
+ widget = glade_xml_get_widget(gui, "vbox-top");
+ if (!widget) {
+ return;
+ }
+ gtk_widget_reparent(widget,
+ GTK_WIDGET(e_table_field_chooser));
+
+ e_table_field_chooser->canvas = GNOME_CANVAS(glade_xml_get_widget(gui, "canvas-buttons"));
+ e_table_field_chooser->item = gnome_canvas_item_new(GNOME_CANVAS_GROUP(e_table_field_chooser->canvas->root),
+ e_table_field_chooser_item_get_type(),
+ NULL);
+}
+
+void
+e_table_field_chooser_destroy (GtkObject *object)
+{
+ ETableFieldChooser *e_table_field_chooser = E_TABLE_FIELD_CHOOSER(object);
+
+ if (e_table_field_chooser->gui)
+ gtk_object_unref(GTK_OBJECT(e_table_field_chooser->gui));
+}
+
+GtkWidget*
+e_table_field_chooser_new (void)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_table_field_chooser_get_type ()));
+ return widget;
+}
+
+static void
+e_table_field_chooser_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id){
+ default:
+ break;
+ }
+}
+
+static void
+e_table_field_chooser_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id) {
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/widgets/table/e-table-field-chooser.glade b/widgets/table/e-table-field-chooser.glade
new file mode 100644
index 0000000000..d179e0cca8
--- /dev/null
+++ b/widgets/table/e-table-field-chooser.glade
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<GTK-Interface>
+
+<project>
+ <name>e-table-field-chooser</name>
+ <program_name>e-table-field-chooser</program_name>
+ <directory></directory>
+ <source_directory>src</source_directory>
+ <pixmaps_directory>pixmaps</pixmaps_directory>
+ <language>C</language>
+ <gnome_support>True</gnome_support>
+ <gettext_support>True</gettext_support>
+ <use_widget_names>True</use_widget_names>
+ <output_main_file>False</output_main_file>
+ <output_support_files>False</output_support_files>
+ <output_build_files>False</output_build_files>
+ <gnome_help_support>True</gnome_help_support>
+ <output_translatable_strings>True</output_translatable_strings>
+ <translatable_strings_file>e-table-field-chooser.glade.h</translatable_strings_file>
+</project>
+
+<widget>
+ <class>GnomeDialog</class>
+ <name>dialog-field-chooser</name>
+ <visible>False</visible>
+ <title>Field Chooser</title>
+ <type>GTK_WINDOW_TOPLEVEL</type>
+ <position>GTK_WIN_POS_NONE</position>
+ <modal>False</modal>
+ <allow_shrink>False</allow_shrink>
+ <allow_grow>True</allow_grow>
+ <auto_shrink>False</auto_shrink>
+ <auto_close>False</auto_close>
+ <hide_on_close>False</hide_on_close>
+
+ <widget>
+ <class>GtkVBox</class>
+ <child_name>GnomeDialog:vbox</child_name>
+ <name>dialog-vbox1</name>
+ <homogeneous>False</homogeneous>
+ <spacing>8</spacing>
+ <child>
+ <padding>4</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkHButtonBox</class>
+ <child_name>GnomeDialog:action_area</child_name>
+ <name>dialog-action_area1</name>
+ <layout_style>GTK_BUTTONBOX_END</layout_style>
+ <spacing>8</spacing>
+ <child_min_width>85</child_min_width>
+ <child_min_height>27</child_min_height>
+ <child_ipad_x>7</child_ipad_x>
+ <child_ipad_y>0</child_ipad_y>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>True</fill>
+ <pack>GTK_PACK_END</pack>
+ </child>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button3</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
+ </widget>
+ </widget>
+
+ <widget>
+ <class>GtkVBox</class>
+ <name>vbox-top</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkScrolledWindow</class>
+ <name>scrolledwindow1</name>
+ <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
+ <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
+ <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
+ <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GnomeCanvas</class>
+ <name>canvas-buttons</name>
+ <can_focus>True</can_focus>
+ <anti_aliased>False</anti_aliased>
+ <scroll_x1>0</scroll_x1>
+ <scroll_y1>0</scroll_y1>
+ <scroll_x2>100</scroll_x2>
+ <scroll_y2>100</scroll_y2>
+ <pixels_per_unit>1</pixels_per_unit>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+</widget>
+
+</GTK-Interface>
diff --git a/widgets/table/e-table-field-chooser.glade.h b/widgets/table/e-table-field-chooser.glade.h
new file mode 100644
index 0000000000..344535f180
--- /dev/null
+++ b/widgets/table/e-table-field-chooser.glade.h
@@ -0,0 +1,7 @@
+/*
+ * Translatable strings file generated by Glade.
+ * Add this file to your project's POTFILES.in.
+ * DO NOT compile it as part of your application.
+ */
+
+gchar *s = N_("Field Chooser");
diff --git a/widgets/table/e-table-field-chooser.h b/widgets/table/e-table-field-chooser.h
new file mode 100644
index 0000000000..e1d8289824
--- /dev/null
+++ b/widgets/table/e-table-field-chooser.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-contact-editor-fullname.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_TABLE_FIELD_CHOOSER_H__
+#define __E_TABLE_FIELD_CHOOSER_H__
+
+#include <gnome.h>
+#include <glade/glade.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+/* ETableFieldChooser - A dialog displaying information about a contact.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ */
+
+#define E_TABLE_FIELD_CHOOSER_TYPE (e_table_field_chooser_get_type ())
+#define E_TABLE_FIELD_CHOOSER(obj) (GTK_CHECK_CAST ((obj), E_TABLE_FIELD_CHOOSER_TYPE, ETableFieldChooser))
+#define E_TABLE_FIELD_CHOOSER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TABLE_FIELD_CHOOSER_TYPE, ETableFieldChooserClass))
+#define E_IS_TABLE_FIELD_CHOOSER(obj) (GTK_CHECK_TYPE ((obj), E_TABLE_FIELD_CHOOSER_TYPE))
+#define E_IS_TABLE_FIELD_CHOOSER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TABLE_FIELD_CHOOSER_TYPE))
+
+
+typedef struct _ETableFieldChooser ETableFieldChooser;
+typedef struct _ETableFieldChooserClass ETableFieldChooserClass;
+
+struct _ETableFieldChooser
+{
+ GtkVBox parent;
+
+ /* item specific fields */
+ GladeXML *gui;
+ GnomeCanvas *canvas;
+ GnomeCanvasItem *item;
+};
+
+struct _ETableFieldChooserClass
+{
+ GtkVBoxClass parent_class;
+};
+
+
+GtkWidget *e_table_field_chooser_new(void);
+GtkType e_table_field_chooser_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __E_TABLE_FIELD_CHOOSER_H__ */
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index 6d3329ab11..26ed69c73c 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -38,11 +38,6 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, };
#define ARROW_DOWN_HEIGHT 16
#define ARROW_PTR 7
-/* Padding above and below of the string in the header display */
-#define PADDING 4
-
-#define MIN_ARROW_SIZE 10
-
/* Defines the tolerance for proximity of the column division to the cursor position */
#define TOLERANCE 4
@@ -54,7 +49,6 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, };
static GnomeCanvasItemClass *ethi_parent_class;
-static void ethi_request_redraw (ETableHeaderItem *ethi);
static void ethi_drop_table_header (ETableHeaderItem *ethi);
/*
@@ -73,20 +67,11 @@ static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
- ARG_TABLE_X,
- ARG_TABLE_Y,
+ ARG_DND_CODE,
ARG_TABLE_FONTSET,
ARG_SORT_INFO
};
-static GtkTargetEntry ethi_drag_types [] = {
- { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
-};
-
-static GtkTargetEntry ethi_drop_types [] = {
- { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
-};
-
static void
ethi_destroy (GtkObject *object){
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (object);
@@ -110,9 +95,13 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
+ double i2c [6];
+ ArtPoint c1, c2, i1, i2;
+
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, affine, clip_path, flags);
+
if (ethi->sort_info)
ethi->group_indent_width = e_table_sort_info_grouping_get_count(ethi->sort_info) * GROUP_INDENT;
else
@@ -120,16 +109,24 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags
ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width;
- if (item->x1 != ethi->x1 ||
- item->y1 != ethi->y1 ||
- item->x2 != ethi->x1 + ethi->width ||
- item->y2 != ethi->y1 + ethi->height)
+ i1.x = i1.y = 0;
+ i2.x = ethi->width;
+ i2.y = ethi->height;
+
+ gnome_canvas_item_i2c_affine (item, i2c);
+ art_affine_point (&c1, &i1, i2c);
+ art_affine_point (&c2, &i2, i2c);
+
+ if (item->x1 != c1.x ||
+ item->y1 != c1.y ||
+ item->x2 != c2.x ||
+ item->y2 != c2.y)
{
gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
- item->x1 = ethi->x1;
- item->y1 = ethi->y1;
- item->x2 = ethi->x1 + ethi->width;
- item->y2 = ethi->y1 + ethi->height;
+ item->x1 = c1.x;
+ item->y1 = c1.y;
+ item->x2 = c2.x;
+ item->y2 = c2.y;
gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
}
@@ -146,9 +143,9 @@ ethi_font_load (ETableHeaderItem *ethi, char *font)
if (ethi->font == NULL)
ethi->font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1");
- ethi->height = ethi->font->ascent + ethi->font->descent + PADDING;
- if (ethi->height < MIN_ARROW_SIZE + 4 + PADDING)
- ethi->height = MIN_ARROW_SIZE + 4 + PADDING;
+ ethi->height = ethi->font->ascent + ethi->font->descent + HEADER_PADDING;
+ if (ethi->height < MIN_ARROW_SIZE + 4 + HEADER_PADDING)
+ ethi->height = MIN_ARROW_SIZE + 4 + HEADER_PADDING;
}
static void
@@ -216,12 +213,9 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
ethi_add_table_header (ethi, E_TABLE_HEADER(GTK_VALUE_OBJECT (*arg)));
break;
- case ARG_TABLE_X:
- ethi->x1 = GTK_VALUE_INT (*arg);
- break;
-
- case ARG_TABLE_Y:
- ethi->y1 = GTK_VALUE_INT (*arg);
+ case ARG_DND_CODE:
+ g_free(ethi->dnd_code);
+ ethi->dnd_code = g_strdup (GTK_VALUE_STRING (*arg));
break;
case ARG_TABLE_FONTSET:
@@ -254,14 +248,31 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
break;
}
- ethi_update (item, NULL, NULL, 0);
+ gnome_canvas_item_request_update(item);
+}
+
+static void
+ethi_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableHeaderItem *ethi;
+
+ ethi = E_TABLE_HEADER_ITEM (o);
+
+ switch (arg_id){
+ case ARG_DND_CODE:
+ GTK_VALUE_STRING (*arg) = g_strdup (ethi->dnd_code);
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
- int x1 = ethi->x1;
+ int x1 = 0;
int col;
if (x < x1)
@@ -292,65 +303,6 @@ ethi_remove_drop_marker (ETableHeaderItem *ethi)
ethi->drag_mark = -1;
}
-#if 0
-static void
-ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
-{
- GnomeCanvasPoints *points;
- int x;
-
- if (ethi->drag_mark == col)
- return;
-
- if (ethi->drag_mark_item)
- gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
-
- ethi->drag_mark = col;
-
- ethi->drag_mark_item = gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
- gnome_canvas_group_get_type (),
- "x", 0,
- "y", 0,
- NULL);
-
- points = gnome_canvas_points_new (3);
-
- x = e_table_header_col_diff (ethi->eth, 0, col);
-
- if (col > 0)
- x += ethi->group_indent_width;
-
- points->coords [0] = ethi->x1 + x - 5;
- points->coords [1] = ethi->y1;
- points->coords [2] = points->coords [0] + 10;
- points->coords [3] = points->coords [1];
- points->coords [4] = ethi->x1 + x;
- points->coords [5] = ethi->y1 + 5;
-
- gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (ethi->drag_mark_item),
- gnome_canvas_polygon_get_type (),
- "points", points,
- "fill_color", "red",
- NULL);
-
- points->coords [0] --;
- points->coords [1] += ethi->height - 1;
- points->coords [3] = points->coords [1];
- points->coords [5] = points->coords [1] - 6;
-
- gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (ethi->drag_mark_item),
- gnome_canvas_polygon_get_type (),
- "points", points,
- "fill_color", "red",
- NULL);
-
- gnome_canvas_points_unref (points);
-}
-#endif
-
static GtkWidget *
make_shapped_window_from_xpm (const char **xpm)
{
@@ -427,7 +379,7 @@ ethi_add_destroy_marker (ETableHeaderItem *ethi)
ethi->stipple = gdk_bitmap_create_from_data (
NULL, gray50_bits, gray50_width, gray50_height);
- x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
+ x1 = (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
if (ethi->drag_col > 0)
x1 += ethi->group_indent_width;
@@ -435,11 +387,11 @@ ethi_add_destroy_marker (ETableHeaderItem *ethi)
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
- "y1", (double) ethi->y1 + 1,
+ "y1", (double) 1,
"x2", (double) x1 + e_table_header_col_diff (
ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
- "y2", (double) ethi->y1 + ethi->height - 2,
+ "y2", (double) ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
@@ -465,8 +417,8 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
return FALSE;
gdk_drag_status (context, 0, time);
- if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
- (y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
+ if ((x >= 0) && (x <= (ethi->width)) &&
+ (y >= 0) && (y <= (ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
@@ -493,15 +445,48 @@ ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *eth
if (ethi->drag_col == -1)
return;
- /* if (canvas == gtk_drag_get_source_widget (context)) { */
if (context->action == 0) {
- ethi_request_redraw (ethi);
e_table_header_remove (ethi->eth, ethi->drag_col);
+ gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
}
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
- /* } */
+}
+
+static void
+ethi_drag_data_received (GtkWidget *canvas,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ ETableHeaderItem *ethi)
+{
+ e_table_header_move (ethi->eth, ethi->drag_col, ethi->drop_col);
+ 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]),
+ string,
+ strlen(string));
+ g_free(string);
+ }
}
static gboolean
@@ -517,24 +502,22 @@ ethi_drag_drop (GtkWidget *canvas,
if (ethi->drag_col == -1)
return FALSE;
- /* if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget (context)) {*/
- if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
- (y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
+ if ((x >= 0) && (x <= (ethi->width)) &&
+ (y >= 0) && (y <= (ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
ethi_add_drop_marker (ethi, col);
+
+ ethi->drop_col = col;
if (col != -1) {
- if (col != ethi->drag_col) {
- ethi_request_redraw (ethi);
- e_table_header_move (ethi->eth, ethi->drag_col, col);
- }
- successful = TRUE;
+ char *target = g_strdup_printf ("%s-%s", TARGET_ETABLE_COL_TYPE, ethi->dnd_code);
+ gtk_drag_get_data (canvas, context, gdk_atom_intern(target, FALSE), time);
+ g_free (target);
}
}
- /* } */
gtk_drag_finish (context, successful, successful, time);
return successful;
}
@@ -545,10 +528,8 @@ ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableH
if (ethi->drag_col == -1)
return;
- /* if (widget == gtk_drag_get_source_widget (context)) { */
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
- /* } */
}
static void
@@ -557,6 +538,10 @@ ethi_realize (GnomeCanvasItem *item)
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
+ GtkTargetEntry ethi_drop_types [] = {
+ { 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);
@@ -573,25 +558,28 @@ ethi_realize (GnomeCanvasItem *item)
/*
* 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, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
+ g_free(ethi_drop_types[0].target);
+
+ /* Drop signals */
+ ethi->drag_motion_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_motion",
+ GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
+ ethi->drag_leave_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_leave",
+ GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
+ ethi->drag_drop_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_drop",
+ GTK_SIGNAL_FUNC (ethi_drag_drop), ethi);
+ ethi->drag_data_received_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_data_received",
+ GTK_SIGNAL_FUNC (ethi_drag_data_received), ethi);
+
+ /* Drag signals */
+ ethi->drag_end_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_end",
+ GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
+ ethi->drag_data_get_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_data_get",
+ GTK_SIGNAL_FUNC (ethi_drag_data_get), ethi);
- ethi->drag_motion_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_motion",
- GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
-
- ethi->drag_leave_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_leave",
- GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
-
- ethi->drag_end_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_end",
- GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
-
- ethi->drag_drop_id = gtk_signal_connect (
- GTK_OBJECT (item->canvas), "drag_drop",
- GTK_SIGNAL_FUNC (ethi_drag_drop), ethi);
}
static void
@@ -603,9 +591,12 @@ ethi_unrealize (GnomeCanvasItem *item)
ethi->gc = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
- gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_drop_id);
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_data_received_id);
+
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
+ gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_data_get_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
@@ -633,9 +624,9 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x , y, width, height);
- clip.x = x + PADDING / 2;
- clip.y = y + PADDING / 2;
- clip.width = width - PADDING;
+ clip.x = x + HEADER_PADDING / 2;
+ clip.y = y + HEADER_PADDING / 2;
+ clip.width = width - HEADER_PADDING;
clip.height = ethi->height;
gdk_gc_set_clip_rectangle (ethi->gc, &clip);
@@ -643,7 +634,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
if (col->is_pixbuf){
xtra = (clip.width - gdk_pixbuf_get_width (col->pixbuf))/2;
- xtra += PADDING / 2;
+ xtra += HEADER_PADDING / 2;
gdk_pixbuf_render_to_drawable_alpha (col->pixbuf,
drawable,
@@ -661,11 +652,11 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
if (xtra < 0)
xtra = 0;
- xtra += PADDING / 2;
+ xtra += HEADER_PADDING / 2;
gdk_draw_text (
drawable, ethi->font,
- ethi->gc, x + xtra, y + ethi->height - ethi->font->descent - PADDING / 2,
+ ethi->gc, x + xtra, y + ethi->height - ethi->font->descent - HEADER_PADDING / 2,
col->text, strlen (col->text));
}
@@ -690,7 +681,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
"header",
(arrow == E_TABLE_COL_ARROW_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN,
TRUE,
- x + PADDING / 2 + clip.width - MIN_ARROW_SIZE - 2,
+ x + HEADER_PADDING / 2 + clip.width - MIN_ARROW_SIZE - 2,
y + (ethi->height - MIN_ARROW_SIZE) / 2,
MIN_ARROW_SIZE,
MIN_ARROW_SIZE);
@@ -733,7 +724,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
}
ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width;
- x1 = x2 = ethi->x1;
+ x1 = x2 = 0;
x2 += ethi->group_indent_width;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
@@ -753,7 +744,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
- x1 - x, ethi->y1 - y, x2 - x1, ethi->height,
+ x1 - x, - y, x2 - x1, ethi->height,
(ETableColArrow) g_hash_table_lookup (arrows, (gpointer) ecol->col_idx));
}
g_hash_table_destroy (arrows);
@@ -823,18 +814,6 @@ set_cursor (ETableHeaderItem *ethi, int pos)
}
static void
-ethi_request_redraw (ETableHeaderItem *ethi)
-{
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (ethi)->canvas;
-
- /*
- * request a redraw
- */
- gnome_canvas_request_redraw (
- canvas, ethi->x1, ethi->y1, ethi->x1 + ethi->width, ethi->x1 + ethi->height);
-}
-
-static void
ethi_end_resize (ETableHeaderItem *ethi)
{
ethi->resize_col = -1;
@@ -872,6 +851,10 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
int group_indent = 0;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
+ GtkTargetEntry ethi_drag_types [] = {
+ { TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
+ };
+
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
@@ -900,8 +883,10 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
}
}
+ 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, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
+ g_free(ethi_drag_types[0].target);
ecol = e_table_header_get_column (ethi->eth, ethi->drag_col);
col_width = ecol->width;
@@ -1269,6 +1254,7 @@ ethi_class_init (GtkObjectClass *object_class)
object_class->destroy = ethi_destroy;
object_class->set_arg = ethi_set_arg;
+ object_class->get_arg = ethi_get_arg;
item_class->update = ethi_update;
item_class->realize = ethi_realize;
@@ -1279,10 +1265,8 @@ ethi_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_OBJECT,
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
- gtk_object_add_arg_type ("ETableHeaderItem::x", GTK_TYPE_INT,
- GTK_ARG_WRITABLE, ARG_TABLE_X);
- gtk_object_add_arg_type ("ETableHeaderItem::y", GTK_TYPE_INT,
- GTK_ARG_WRITABLE, ARG_TABLE_Y);
+ gtk_object_add_arg_type ("ETableHeaderItem::dnd_code", GTK_TYPE_STRING,
+ GTK_ARG_WRITABLE, ARG_DND_CODE);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
gtk_object_add_arg_type ("ETableHeaderItem::sort_info", GTK_TYPE_OBJECT,
@@ -1355,4 +1339,3 @@ e_table_header_item_get_type (void)
return type;
}
-
diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h
index 300a7c81fb..15b627bfa9 100644
--- a/widgets/table/e-table-header-item.h
+++ b/widgets/table/e-table-header-item.h
@@ -20,7 +20,7 @@ typedef struct {
GdkGC *gc;
GdkCursor *change_cursor;
- short x1, y1, height, width;
+ short height, width;
GdkFont *font;
/*
@@ -45,16 +45,21 @@ typedef struct {
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
- int drag_col, drag_mark;
- guint drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id;
+ int drag_col, drop_col, drag_mark;
+ guint drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id, drag_data_received_id, drag_data_get_id;
guint sort_info_changed_id, group_info_changed_id;
GnomeCanvasItem *remove_item;
GdkBitmap *stipple;
+ gchar *dnd_code;
+
/*
* For column sorting info
*/
ETableSortInfo *sort_info;
+
+ /* For adding fields. */
+ ETableHeader *full_header;
} ETableHeaderItem;
typedef struct {