From 104a3d0bffd91508ef184487aa9fbc0826cc6177 Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Thu, 8 Jun 2000 00:40:23 +0000 Subject: Added e-table-field-chooser*. 2000-06-07 Christopher James Lahey * 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. svn path=/trunk/; revision=3473 --- widgets/table/e-table-defines.h | 6 + widgets/table/e-table-field-chooser-dialog.c | 108 +++++ widgets/table/e-table-field-chooser-dialog.h | 73 ++++ widgets/table/e-table-field-chooser-item.c | 567 +++++++++++++++++++++++++++ widgets/table/e-table-field-chooser-item.h | 47 +++ widgets/table/e-table-field-chooser.c | 137 +++++++ widgets/table/e-table-field-chooser.glade | 114 ++++++ widgets/table/e-table-field-chooser.glade.h | 7 + widgets/table/e-table-field-chooser.h | 74 ++++ widgets/table/e-table-header-item.c | 293 +++++++------- widgets/table/e-table-header-item.h | 11 +- 11 files changed, 1279 insertions(+), 158 deletions(-) create mode 100644 widgets/table/e-table-field-chooser-dialog.c create mode 100644 widgets/table/e-table-field-chooser-dialog.h create mode 100644 widgets/table/e-table-field-chooser-item.c create mode 100644 widgets/table/e-table-field-chooser-item.h create mode 100644 widgets/table/e-table-field-chooser.c create mode 100644 widgets/table/e-table-field-chooser.glade create mode 100644 widgets/table/e-table-field-chooser.glade.h create mode 100644 widgets/table/e-table-field-chooser.h (limited to 'widgets/table') 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 + * + * 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 +#include +#include + +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 + * + * 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 +#include +#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 +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#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 + * + * 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 +#include +#include +#include + +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 @@ + + + + + e-table-field-chooser + e-table-field-chooser + + src + pixmaps + C + True + True + True + False + False + False + True + True + e-table-field-chooser.glade.h + + + + GnomeDialog + dialog-field-chooser + False + Field Chooser + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button3 + True + True + GNOME_STOCK_BUTTON_CLOSE + + + + + GtkVBox + vbox-top + False + 0 + + 0 + True + True + + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GnomeCanvas + canvas-buttons + True + False + 0 + 0 + 100 + 100 + 1 + + + + + + + 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 + * + * 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 +#include + +#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); @@ -822,18 +813,6 @@ set_cursor (ETableHeaderItem *ethi, int pos) e_cursor_set (canvas->window, E_CURSOR_ARROW); } -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) { @@ -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 { -- cgit v1.2.3