diff options
author | Christopher James Lahey <clahey@helixcode.com> | 2000-07-26 04:05:29 +0800 |
---|---|---|
committer | Chris Lahey <clahey@src.gnome.org> | 2000-07-26 04:05:29 +0800 |
commit | 384b3e38f2b049f808d1b4a72ca1d396ae6e2fb2 (patch) | |
tree | d0fa89ff2f5e70c8cdb33353381c0e6bc6e20428 | |
parent | 1f1872ec3c71546fd66e0d4bb9bc82f0738cde80 (diff) | |
download | gsoc2013-evolution-384b3e38f2b049f808d1b4a72ca1d396ae6e2fb2.tar.gz gsoc2013-evolution-384b3e38f2b049f808d1b4a72ca1d396ae6e2fb2.tar.zst gsoc2013-evolution-384b3e38f2b049f808d1b4a72ca1d396ae6e2fb2.zip |
New files for doing a selection model. Not finished yet and thus not in
2000-07-25 Christopher James Lahey <clahey@helixcode.com>
* e-table-selection-model.c, e-table-selection-model.h: New files
for doing a selection model. Not finished yet and thus not in
Makefile.am.
* e-table.c, e-table.h: Renamed the new dnd signals so that they
won't conflict with the widget signals.
svn path=/trunk/; revision=4326
-rw-r--r-- | widgets/e-table/ChangeLog | 9 | ||||
-rw-r--r-- | widgets/e-table/e-table-selection-model.c | 274 | ||||
-rw-r--r-- | widgets/e-table/e-table-selection-model.h | 57 | ||||
-rw-r--r-- | widgets/e-table/e-table.c | 102 | ||||
-rw-r--r-- | widgets/e-table/e-table.h | 90 | ||||
-rw-r--r-- | widgets/table/e-table-selection-model.c | 274 | ||||
-rw-r--r-- | widgets/table/e-table-selection-model.h | 57 | ||||
-rw-r--r-- | widgets/table/e-table.c | 102 | ||||
-rw-r--r-- | widgets/table/e-table.h | 90 |
9 files changed, 863 insertions, 192 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index e263060158..c6348038fd 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,5 +1,14 @@ 2000-07-25 Christopher James Lahey <clahey@helixcode.com> + * e-table-selection-model.c, e-table-selection-model.h: New files + for doing a selection model. Not finished yet and thus not in + Makefile.am. + + * e-table.c, e-table.h: Renamed the new dnd signals so that they + won't conflict with the widget signals. + +2000-07-25 Christopher James Lahey <clahey@helixcode.com> + * e-table.c, e-table.h: Implemented some of the drag & drop code. Drops all report as being on row 0, col 0. Also, automatic drags don't set the row and column being dragged from. diff --git a/widgets/e-table/e-table-selection-model.c b/widgets/e-table/e-table-selection-model.c new file mode 100644 index 0000000000..9a199f74e8 --- /dev/null +++ b/widgets/e-table/e-table-selection-model.c @@ -0,0 +1,274 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * e-table-selection-model.c: a Table Selection Model + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * (C) 1999 Helix Code, Inc. + */ +#include <config.h> +#include <gtk/gtksignal.h> +#include "e-table-selection-model.h" +#include "e-util/e-util.h" + +#define ETSM_CLASS(e) ((ETableSelectionModelClass *)((GtkObject *)e)->klass) + +#define PARENT_TYPE gtk_object_get_type () + + +static GtkObjectClass *e_table_selection_model_parent_class; + +enum { + SELECTION_MODEL_CHANGED, + GROUP_SELECTION_CHANGED, + LAST_SIGNAL +}; + +static guint e_table_selection_model_signals [LAST_SIGNAL] = { 0, }; + +static void +model_changed(ETableModel *etm, ETableSelectionModel *etsm) +{ + g_free(etsm->selection); + etsm->selection = NULL; + etsm->row_count = -1; +} + +static void +model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm) +{ + int box; + int i; + int offset; + if(etsm->row_count >= 0) { + if ((etsm->row_count & 0x1f /*%32*/) == 0) { + etsm->selection = e_realloc(etsm->selection, (etsm->row_count >> 5/* /32 */) + 1); + etsm->selection[etsm->row_count >> 5] = 0; + } + box = row >> 5; + for (i = etsm->row_count >> 5; i > box; i--) { + etsm->selection[i] = (etsm->selection[i] >> 1) & (etsm->selection[i - 1] << 31) + } + offset = row & 0x1f; + etsm->selection[i] = ((etsm->selection[i] >> (32 - offset)) << (31 - offset)) & ((etsm->selection[i] << offset) >> offset); + } +} + +inline static void +add_model(ETableSelectionModel *etsm, ETableModel *model) +{ + etsm->model = model; + if (model) + gtk_object_ref(GTK_OBJECT(model)); +} + +inline static void +drop_model(ETableSelectionModel *etsm) +{ + if (etsm->model) + gtk_object_unref(GTK_OBJECT(etsm->model)); + etsm->model = NULL; +} + +static void +etsm_destroy (GtkObject *object) +{ + ETableSelectionModel *etsm; + + etsm = E_TABLE_SELECTION_MODEL (object); + + g_free(etsm->selction); +} + +static void +e_table_selection_model_init (ETableSelectionModel *selection) +{ + selection->selection = NULL; + selection->row_count = -1; +} + +static void +e_table_selection_model_class_init (ETableSelectionModelClass *klass) +{ + GtkObjectClass *object_class; + + e_table_selection_model_parent_class = gtk_type_class (gtk_object_get_type ()); + + object_class = GTK_OBJECT_CLASS(klass); + + object_class->destroy = etsm_destroy; + + e_table_selection_model_signals [SELECTION_MODEL_CHANGED] = + gtk_signal_new ("selection_model_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_model_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + e_table_selection_model_signals [GROUP_SELECTION_CHANGED] = + gtk_signal_new ("group_selection_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableSelectionModelClass, group_selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + klass->selection_model_changed = NULL; + klass->group_selection_changed = NULL; + + gtk_object_class_add_signals (object_class, e_table_selection_model_signals, LAST_SIGNAL); +} + +E_MAKE_TYPE(e_table_selection_model, "ETableSelectionModel", ETableSelectionModel, + e_table_selection_model_class_init, e_table_selection_model_init, PARENT_TYPE); + +static void +e_table_selection_model_selection_model_changed (ETableSelectionModel *selection) +{ + g_return_if_fail (selection != NULL); + g_return_if_fail (E_IS_TABLE_SELECTION_MODEL (selection)); + + if (selection->frozen) { + selection->selection_model_changed = 1; + } else { + gtk_signal_emit (GTK_OBJECT (selection), + e_table_selection_model_signals [SELECTION_MODEL_CHANGED]); + } +} + +static void +e_table_selection_model_group_selection_changed (ETableSelectionModel *selection) +{ + g_return_if_fail (selection != NULL); + g_return_if_fail (E_IS_TABLE_SELECTION_MODEL (selection)); + + if (selection->frozen) { + selection->group_selection_changed = 1; + } else { + gtk_signal_emit (GTK_OBJECT (selection), + e_table_selection_model_signals [GROUP_SELECTION_CHANGED]); + } +} + +void +e_table_selection_model_freeze (ETableSelectionModel *selection) +{ + selection->frozen = 1; +} + +void +e_table_selection_model_thaw (ETableSelectionModel *selection) +{ + selection->frozen = 0; + if (selection->selection_model_changed) { + selection->selection_model_changed = 0; + e_table_selection_model_selection_model_changed(selection); + } + if (selection->group_selection_changed) { + selection->group_selection_changed = 0; + e_table_selection_model_group_selection_changed(selection); + } +} + + +guint +e_table_selection_model_grouping_get_count (ETableSelectionModel *selection) +{ + return selection->group_count; +} + +static void +e_table_selection_model_grouping_real_truncate (ETableSelectionModel *selection, int length) +{ + if (length < selection->group_count) { + selection->group_count = length; + } + if (length > selection->group_count) { + selection->groupings = g_realloc(selection->groupings, length * sizeof(ETableSortColumn)); + selection->group_count = length; + } +} + +void +e_table_selection_model_grouping_truncate (ETableSelectionModel *selection, int length) +{ + e_table_selection_model_grouping_real_truncate(selection, length); + e_table_selection_model_group_selection_changed(selection); +} + +ETableSortColumn +e_table_selection_model_grouping_get_nth (ETableSelectionModel *selection, int n) +{ + if (n < selection->group_count) { + return selection->groupings[n]; + } else { + ETableSortColumn fake = {0, 0}; + return fake; + } +} + +void +e_table_selection_model_grouping_set_nth (ETableSelectionModel *selection, int n, ETableSortColumn column) +{ + if (n >= selection->group_count) { + e_table_selection_model_grouping_real_truncate(selection, n + 1); + } + selection->groupings[n] = column; + e_table_selection_model_group_selection_changed(selection); +} + + +guint +e_table_selection_model_sorting_get_count (ETableSelectionModel *selection) +{ + return selection->sort_count; +} + +static void +e_table_selection_model_sorting_real_truncate (ETableSelectionModel *selection, int length) +{ + if (length < selection->sort_count) { + selection->sort_count = length; + } + if (length > selection->sort_count) { + selection->sortings = g_realloc(selection->sortings, length * sizeof(ETableSortColumn)); + selection->sort_count = length; + } +} + +void +e_table_selection_model_sorting_truncate (ETableSelectionModel *selection, int length) +{ + e_table_selection_model_sorting_real_truncate (selection, length); + e_table_selection_model_selection_model_changed(selection); +} + +ETableSortColumn +e_table_selection_model_sorting_get_nth (ETableSelectionModel *selection, int n) +{ + if (n < selection->sort_count) { + return selection->sortings[n]; + } else { + ETableSortColumn fake = {0, 0}; + return fake; + } +} + +void +e_table_selection_model_sorting_set_nth (ETableSelectionModel *selection, int n, ETableSortColumn column) +{ + if (n >= selection->sort_count) { + e_table_selection_model_sorting_real_truncate(selection, n + 1); + } + selection->sortings[n] = column; + e_table_selection_model_selection_model_changed(selection); +} + + +ETableSelectionModel * +e_table_selection_model_new (void) +{ + return gtk_type_new (e_table_selection_model_get_type ()); +} diff --git a/widgets/e-table/e-table-selection-model.h b/widgets/e-table/e-table-selection-model.h new file mode 100644 index 0000000000..8b7d0a0507 --- /dev/null +++ b/widgets/e-table/e-table-selection-model.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_SELECTION_MODEL_H_ +#define _E_TABLE_SELECTION_MODEL_H_ + +#include <gtk/gtkobject.h> + +#define E_TABLE_SELECTION_MODEL_TYPE (e_table_selection_model_get_type ()) +#define E_TABLE_SELECTION_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_SELECTION_MODEL_TYPE, ETableSelectionModel)) +#define E_TABLE_SELECTION_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SELECTION_MODEL_TYPE, ETableSelectionModelClass)) +#define E_IS_TABLE_SELECTION_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_SELECTION_MODEL_TYPE)) +#define E_IS_TABLE_SELECTION_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SELECTION_MODEL_TYPE)) + +typedef struct _ETableSortColumn ETableSortColumn; + +struct _ETableSortColumn { + guint column : 31; + guint ascending : 1; +}; + +typedef struct { + GtkObject base; + + ETableModel *model; + + gint row_count; + guint *selection; + + gint cursor_row; + gint cursor_col; + + guint model_changed_id; + guint model_row_inserted_id, model_row_deleted_id; + + guint frozen : 1; + guint selection_model_changed : 1; + guint group_info_changed : 1; +} ETableSelectionModel; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Signals + */ + void (*selection_model_changed) (ETableSelectionModel *selection); + void (*group_model_changed) (ETableSelectionModel *selection); +} ETableSelectionModelClass; + +GtkType e_table_selection_model_get_type (void); + +gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection, + int n); +GList *e_table_selection_model_get_selection_list (ETableSelectionModel *selection); + +ETableSelectionModel *e_table_selection_model_new (void); + +#endif /* _E_TABLE_SELECTION_MODEL_H_ */ diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c index 2eb7cfe3c9..c20c7cd21e 100644 --- a/widgets/e-table/e-table.c +++ b/widgets/e-table/e-table.c @@ -46,15 +46,15 @@ enum { RIGHT_CLICK, KEY_PRESS, - DRAG_BEGIN, - DRAG_END, - DRAG_DATA_GET, - DRAG_DATA_DELETE, + TABLE_DRAG_BEGIN, + TABLE_DRAG_END, + TABLE_DRAG_DATA_GET, + TABLE_DRAG_DATA_DELETE, - DRAG_LEAVE, - DRAG_MOTION, - DRAG_DROP, - DRAG_DATA_RECEIVED, + TABLE_DRAG_LEAVE, + TABLE_DRAG_MOTION, + TABLE_DRAG_DROP, + TABLE_DRAG_DATA_RECEIVED, LAST_SIGNAL }; @@ -1046,7 +1046,7 @@ et_drag_begin (GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_BEGIN], + et_signals [TABLE_DRAG_BEGIN], et->drag_row, et->drag_col, context); @@ -1058,7 +1058,7 @@ et_drag_end (GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_END], + et_signals [TABLE_DRAG_END], et->drag_row, et->drag_col, context); @@ -1073,7 +1073,7 @@ et_drag_data_get(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DATA_GET], + et_signals [TABLE_DRAG_DATA_GET], et->drag_row, et->drag_col, context, @@ -1088,7 +1088,7 @@ et_drag_data_delete(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DATA_DELETE], + et_signals [TABLE_DRAG_DATA_DELETE], et->drag_row, et->drag_col, context); @@ -1101,7 +1101,7 @@ et_drag_leave(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, @@ -1129,7 +1129,7 @@ et_drag_motion(GtkWidget *widget, if (et->drop_row >= 0 && et->drop_col >= 0 && row != et->drop_row && col != et->drop_row) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, @@ -1138,7 +1138,7 @@ et_drag_motion(GtkWidget *widget, et->drop_row = row; et->drop_col = col; gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], et->drop_row, et->drop_col, context, @@ -1168,13 +1168,13 @@ et_drag_drop(GtkWidget *widget, if (et->drop_row >= 0 && et->drop_col >= 0 && row != et->drop_row && col != et->drop_row) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, time); gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], row, col, context, @@ -1186,7 +1186,7 @@ et_drag_drop(GtkWidget *widget, et->drop_row = row; et->drop_col = col; gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DROP], + et_signals [TABLE_DRAG_DROP], et->drop_row, et->drop_col, context, @@ -1217,7 +1217,7 @@ et_drag_data_received(GtkWidget *widget, &row, &col); gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], row, col, context, @@ -1246,15 +1246,15 @@ e_table_class_init (GtkObjectClass *object_class) klass->right_click = NULL; klass->key_press = NULL; - klass->drag_begin = NULL; - klass->drag_end = NULL; - klass->drag_data_get = NULL; - klass->drag_data_delete = NULL; + klass->table_drag_begin = NULL; + klass->table_drag_end = NULL; + klass->table_drag_data_get = NULL; + klass->table_drag_data_delete = NULL; - klass->drag_leave = NULL; - klass->drag_motion = NULL; - klass->drag_drop = NULL; - klass->drag_data_received = NULL; + klass->table_drag_leave = NULL; + klass->table_drag_motion = NULL; + klass->table_drag_drop = NULL; + klass->table_drag_data_received = NULL; et_signals [ROW_SELECTION] = gtk_signal_new ("row_selection", @@ -1296,31 +1296,31 @@ e_table_class_init (GtkObjectClass *object_class) e_marshal_INT__INT_INT_POINTER, GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_POINTER); - et_signals[DRAG_BEGIN] = - gtk_signal_new ("drag_begin", + et_signals[TABLE_DRAG_BEGIN] = + gtk_signal_new ("table_drag_begin", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_begin), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_begin), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_END] = - gtk_signal_new ("drag_end", + et_signals[TABLE_DRAG_END] = + gtk_signal_new ("table_drag_end", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_end), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_end), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_DATA_GET] = - gtk_signal_new ("drag_data_get", + et_signals[TABLE_DRAG_DATA_GET] = + gtk_signal_new ("table_drag_data_get", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_get), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_get), e_marshal_NONE__INT_INT_POINTER_POINTER_UINT_UINT, GTK_TYPE_NONE, 6, GTK_TYPE_INT, @@ -1329,33 +1329,33 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_SELECTION_DATA, GTK_TYPE_UINT, GTK_TYPE_UINT); - et_signals[DRAG_DATA_DELETE] = - gtk_signal_new ("drag_data_delete", + et_signals[TABLE_DRAG_DATA_DELETE] = + gtk_signal_new ("table_drag_data_delete", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_delete), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_delete), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_LEAVE] = - gtk_signal_new ("drag_leave", + et_signals[TABLE_DRAG_LEAVE] = + gtk_signal_new ("table_drag_leave", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_leave), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_leave), e_marshal_NONE__INT_INT_POINTER_UINT, GTK_TYPE_NONE, 4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT, GTK_TYPE_UINT); - et_signals[DRAG_MOTION] = - gtk_signal_new ("drag_motion", + et_signals[TABLE_DRAG_MOTION] = + gtk_signal_new ("table_drag_motion", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_motion), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_motion), e_marshal_BOOL__INT_INT_POINTER_INT_INT_UINT, GTK_TYPE_BOOL, 6, GTK_TYPE_INT, @@ -1364,11 +1364,11 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_UINT); - et_signals[DRAG_DROP] = - gtk_signal_new ("drag_drop", + et_signals[TABLE_DRAG_DROP] = + gtk_signal_new ("table_drag_drop", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_drop), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_drop), e_marshal_BOOL__INT_INT_POINTER_INT_INT_UINT, GTK_TYPE_BOOL, 6, GTK_TYPE_INT, @@ -1377,11 +1377,11 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_UINT); - et_signals[DRAG_DATA_RECEIVED] = - gtk_signal_new ("drag_data_received", + et_signals[TABLE_DRAG_DATA_RECEIVED] = + gtk_signal_new ("table_drag_data_received", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_received), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_received), e_marshal_NONE__INT_INT_POINTER_INT_INT_POINTER_UINT_UINT, GTK_TYPE_NONE, 8, GTK_TYPE_INT, diff --git a/widgets/e-table/e-table.h b/widgets/e-table/e-table.h index 85d0e387bd..7612cddebe 100644 --- a/widgets/e-table/e-table.h +++ b/widgets/e-table/e-table.h @@ -88,55 +88,55 @@ typedef struct { GtkAdjustment *vadjustment); /* Source side drag signals */ - void (* drag_begin) (ETable *table, + void (* table_drag_begin) (ETable *table, + int row, + int col, + GdkDragContext *context); + void (* table_drag_end) (ETable *table, int row, int col, GdkDragContext *context); - void (* drag_end) (ETable *table, - int row, - int col, - GdkDragContext *context); - void (* drag_data_get) (ETable *table, - int row, - int col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); - void (* drag_data_delete) (ETable *table, - int row, - int col, - GdkDragContext *context); - + void (* table_drag_data_get) (ETable *table, + int row, + int col, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); + void (* table_drag_data_delete) (ETable *table, + int row, + int col, + GdkDragContext *context); + /* Target side drag signals */ - void (* drag_leave) (ETable *table, - int row, - int col, - GdkDragContext *context, - guint time); - gboolean (* drag_motion) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - guint time); - gboolean (* drag_drop) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - guint time); - void (* drag_data_received) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); + void (* table_drag_leave) (ETable *table, + int row, + int col, + GdkDragContext *context, + guint time); + gboolean (* table_drag_motion) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + guint time); + gboolean (* table_drag_drop) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + guint time); + void (* table_drag_data_received) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); } ETableClass; GtkType e_table_get_type (void); diff --git a/widgets/table/e-table-selection-model.c b/widgets/table/e-table-selection-model.c new file mode 100644 index 0000000000..9a199f74e8 --- /dev/null +++ b/widgets/table/e-table-selection-model.c @@ -0,0 +1,274 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * e-table-selection-model.c: a Table Selection Model + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * (C) 1999 Helix Code, Inc. + */ +#include <config.h> +#include <gtk/gtksignal.h> +#include "e-table-selection-model.h" +#include "e-util/e-util.h" + +#define ETSM_CLASS(e) ((ETableSelectionModelClass *)((GtkObject *)e)->klass) + +#define PARENT_TYPE gtk_object_get_type () + + +static GtkObjectClass *e_table_selection_model_parent_class; + +enum { + SELECTION_MODEL_CHANGED, + GROUP_SELECTION_CHANGED, + LAST_SIGNAL +}; + +static guint e_table_selection_model_signals [LAST_SIGNAL] = { 0, }; + +static void +model_changed(ETableModel *etm, ETableSelectionModel *etsm) +{ + g_free(etsm->selection); + etsm->selection = NULL; + etsm->row_count = -1; +} + +static void +model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm) +{ + int box; + int i; + int offset; + if(etsm->row_count >= 0) { + if ((etsm->row_count & 0x1f /*%32*/) == 0) { + etsm->selection = e_realloc(etsm->selection, (etsm->row_count >> 5/* /32 */) + 1); + etsm->selection[etsm->row_count >> 5] = 0; + } + box = row >> 5; + for (i = etsm->row_count >> 5; i > box; i--) { + etsm->selection[i] = (etsm->selection[i] >> 1) & (etsm->selection[i - 1] << 31) + } + offset = row & 0x1f; + etsm->selection[i] = ((etsm->selection[i] >> (32 - offset)) << (31 - offset)) & ((etsm->selection[i] << offset) >> offset); + } +} + +inline static void +add_model(ETableSelectionModel *etsm, ETableModel *model) +{ + etsm->model = model; + if (model) + gtk_object_ref(GTK_OBJECT(model)); +} + +inline static void +drop_model(ETableSelectionModel *etsm) +{ + if (etsm->model) + gtk_object_unref(GTK_OBJECT(etsm->model)); + etsm->model = NULL; +} + +static void +etsm_destroy (GtkObject *object) +{ + ETableSelectionModel *etsm; + + etsm = E_TABLE_SELECTION_MODEL (object); + + g_free(etsm->selction); +} + +static void +e_table_selection_model_init (ETableSelectionModel *selection) +{ + selection->selection = NULL; + selection->row_count = -1; +} + +static void +e_table_selection_model_class_init (ETableSelectionModelClass *klass) +{ + GtkObjectClass *object_class; + + e_table_selection_model_parent_class = gtk_type_class (gtk_object_get_type ()); + + object_class = GTK_OBJECT_CLASS(klass); + + object_class->destroy = etsm_destroy; + + e_table_selection_model_signals [SELECTION_MODEL_CHANGED] = + gtk_signal_new ("selection_model_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_model_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + e_table_selection_model_signals [GROUP_SELECTION_CHANGED] = + gtk_signal_new ("group_selection_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableSelectionModelClass, group_selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + klass->selection_model_changed = NULL; + klass->group_selection_changed = NULL; + + gtk_object_class_add_signals (object_class, e_table_selection_model_signals, LAST_SIGNAL); +} + +E_MAKE_TYPE(e_table_selection_model, "ETableSelectionModel", ETableSelectionModel, + e_table_selection_model_class_init, e_table_selection_model_init, PARENT_TYPE); + +static void +e_table_selection_model_selection_model_changed (ETableSelectionModel *selection) +{ + g_return_if_fail (selection != NULL); + g_return_if_fail (E_IS_TABLE_SELECTION_MODEL (selection)); + + if (selection->frozen) { + selection->selection_model_changed = 1; + } else { + gtk_signal_emit (GTK_OBJECT (selection), + e_table_selection_model_signals [SELECTION_MODEL_CHANGED]); + } +} + +static void +e_table_selection_model_group_selection_changed (ETableSelectionModel *selection) +{ + g_return_if_fail (selection != NULL); + g_return_if_fail (E_IS_TABLE_SELECTION_MODEL (selection)); + + if (selection->frozen) { + selection->group_selection_changed = 1; + } else { + gtk_signal_emit (GTK_OBJECT (selection), + e_table_selection_model_signals [GROUP_SELECTION_CHANGED]); + } +} + +void +e_table_selection_model_freeze (ETableSelectionModel *selection) +{ + selection->frozen = 1; +} + +void +e_table_selection_model_thaw (ETableSelectionModel *selection) +{ + selection->frozen = 0; + if (selection->selection_model_changed) { + selection->selection_model_changed = 0; + e_table_selection_model_selection_model_changed(selection); + } + if (selection->group_selection_changed) { + selection->group_selection_changed = 0; + e_table_selection_model_group_selection_changed(selection); + } +} + + +guint +e_table_selection_model_grouping_get_count (ETableSelectionModel *selection) +{ + return selection->group_count; +} + +static void +e_table_selection_model_grouping_real_truncate (ETableSelectionModel *selection, int length) +{ + if (length < selection->group_count) { + selection->group_count = length; + } + if (length > selection->group_count) { + selection->groupings = g_realloc(selection->groupings, length * sizeof(ETableSortColumn)); + selection->group_count = length; + } +} + +void +e_table_selection_model_grouping_truncate (ETableSelectionModel *selection, int length) +{ + e_table_selection_model_grouping_real_truncate(selection, length); + e_table_selection_model_group_selection_changed(selection); +} + +ETableSortColumn +e_table_selection_model_grouping_get_nth (ETableSelectionModel *selection, int n) +{ + if (n < selection->group_count) { + return selection->groupings[n]; + } else { + ETableSortColumn fake = {0, 0}; + return fake; + } +} + +void +e_table_selection_model_grouping_set_nth (ETableSelectionModel *selection, int n, ETableSortColumn column) +{ + if (n >= selection->group_count) { + e_table_selection_model_grouping_real_truncate(selection, n + 1); + } + selection->groupings[n] = column; + e_table_selection_model_group_selection_changed(selection); +} + + +guint +e_table_selection_model_sorting_get_count (ETableSelectionModel *selection) +{ + return selection->sort_count; +} + +static void +e_table_selection_model_sorting_real_truncate (ETableSelectionModel *selection, int length) +{ + if (length < selection->sort_count) { + selection->sort_count = length; + } + if (length > selection->sort_count) { + selection->sortings = g_realloc(selection->sortings, length * sizeof(ETableSortColumn)); + selection->sort_count = length; + } +} + +void +e_table_selection_model_sorting_truncate (ETableSelectionModel *selection, int length) +{ + e_table_selection_model_sorting_real_truncate (selection, length); + e_table_selection_model_selection_model_changed(selection); +} + +ETableSortColumn +e_table_selection_model_sorting_get_nth (ETableSelectionModel *selection, int n) +{ + if (n < selection->sort_count) { + return selection->sortings[n]; + } else { + ETableSortColumn fake = {0, 0}; + return fake; + } +} + +void +e_table_selection_model_sorting_set_nth (ETableSelectionModel *selection, int n, ETableSortColumn column) +{ + if (n >= selection->sort_count) { + e_table_selection_model_sorting_real_truncate(selection, n + 1); + } + selection->sortings[n] = column; + e_table_selection_model_selection_model_changed(selection); +} + + +ETableSelectionModel * +e_table_selection_model_new (void) +{ + return gtk_type_new (e_table_selection_model_get_type ()); +} diff --git a/widgets/table/e-table-selection-model.h b/widgets/table/e-table-selection-model.h new file mode 100644 index 0000000000..8b7d0a0507 --- /dev/null +++ b/widgets/table/e-table-selection-model.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_SELECTION_MODEL_H_ +#define _E_TABLE_SELECTION_MODEL_H_ + +#include <gtk/gtkobject.h> + +#define E_TABLE_SELECTION_MODEL_TYPE (e_table_selection_model_get_type ()) +#define E_TABLE_SELECTION_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_SELECTION_MODEL_TYPE, ETableSelectionModel)) +#define E_TABLE_SELECTION_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SELECTION_MODEL_TYPE, ETableSelectionModelClass)) +#define E_IS_TABLE_SELECTION_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_SELECTION_MODEL_TYPE)) +#define E_IS_TABLE_SELECTION_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SELECTION_MODEL_TYPE)) + +typedef struct _ETableSortColumn ETableSortColumn; + +struct _ETableSortColumn { + guint column : 31; + guint ascending : 1; +}; + +typedef struct { + GtkObject base; + + ETableModel *model; + + gint row_count; + guint *selection; + + gint cursor_row; + gint cursor_col; + + guint model_changed_id; + guint model_row_inserted_id, model_row_deleted_id; + + guint frozen : 1; + guint selection_model_changed : 1; + guint group_info_changed : 1; +} ETableSelectionModel; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Signals + */ + void (*selection_model_changed) (ETableSelectionModel *selection); + void (*group_model_changed) (ETableSelectionModel *selection); +} ETableSelectionModelClass; + +GtkType e_table_selection_model_get_type (void); + +gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection, + int n); +GList *e_table_selection_model_get_selection_list (ETableSelectionModel *selection); + +ETableSelectionModel *e_table_selection_model_new (void); + +#endif /* _E_TABLE_SELECTION_MODEL_H_ */ diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index 2eb7cfe3c9..c20c7cd21e 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -46,15 +46,15 @@ enum { RIGHT_CLICK, KEY_PRESS, - DRAG_BEGIN, - DRAG_END, - DRAG_DATA_GET, - DRAG_DATA_DELETE, + TABLE_DRAG_BEGIN, + TABLE_DRAG_END, + TABLE_DRAG_DATA_GET, + TABLE_DRAG_DATA_DELETE, - DRAG_LEAVE, - DRAG_MOTION, - DRAG_DROP, - DRAG_DATA_RECEIVED, + TABLE_DRAG_LEAVE, + TABLE_DRAG_MOTION, + TABLE_DRAG_DROP, + TABLE_DRAG_DATA_RECEIVED, LAST_SIGNAL }; @@ -1046,7 +1046,7 @@ et_drag_begin (GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_BEGIN], + et_signals [TABLE_DRAG_BEGIN], et->drag_row, et->drag_col, context); @@ -1058,7 +1058,7 @@ et_drag_end (GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_END], + et_signals [TABLE_DRAG_END], et->drag_row, et->drag_col, context); @@ -1073,7 +1073,7 @@ et_drag_data_get(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DATA_GET], + et_signals [TABLE_DRAG_DATA_GET], et->drag_row, et->drag_col, context, @@ -1088,7 +1088,7 @@ et_drag_data_delete(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DATA_DELETE], + et_signals [TABLE_DRAG_DATA_DELETE], et->drag_row, et->drag_col, context); @@ -1101,7 +1101,7 @@ et_drag_leave(GtkWidget *widget, ETable *et) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, @@ -1129,7 +1129,7 @@ et_drag_motion(GtkWidget *widget, if (et->drop_row >= 0 && et->drop_col >= 0 && row != et->drop_row && col != et->drop_row) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, @@ -1138,7 +1138,7 @@ et_drag_motion(GtkWidget *widget, et->drop_row = row; et->drop_col = col; gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], et->drop_row, et->drop_col, context, @@ -1168,13 +1168,13 @@ et_drag_drop(GtkWidget *widget, if (et->drop_row >= 0 && et->drop_col >= 0 && row != et->drop_row && col != et->drop_row) { gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_LEAVE], + et_signals [TABLE_DRAG_LEAVE], et->drop_row, et->drop_col, context, time); gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], row, col, context, @@ -1186,7 +1186,7 @@ et_drag_drop(GtkWidget *widget, et->drop_row = row; et->drop_col = col; gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_DROP], + et_signals [TABLE_DRAG_DROP], et->drop_row, et->drop_col, context, @@ -1217,7 +1217,7 @@ et_drag_data_received(GtkWidget *widget, &row, &col); gtk_signal_emit (GTK_OBJECT (et), - et_signals [DRAG_MOTION], + et_signals [TABLE_DRAG_MOTION], row, col, context, @@ -1246,15 +1246,15 @@ e_table_class_init (GtkObjectClass *object_class) klass->right_click = NULL; klass->key_press = NULL; - klass->drag_begin = NULL; - klass->drag_end = NULL; - klass->drag_data_get = NULL; - klass->drag_data_delete = NULL; + klass->table_drag_begin = NULL; + klass->table_drag_end = NULL; + klass->table_drag_data_get = NULL; + klass->table_drag_data_delete = NULL; - klass->drag_leave = NULL; - klass->drag_motion = NULL; - klass->drag_drop = NULL; - klass->drag_data_received = NULL; + klass->table_drag_leave = NULL; + klass->table_drag_motion = NULL; + klass->table_drag_drop = NULL; + klass->table_drag_data_received = NULL; et_signals [ROW_SELECTION] = gtk_signal_new ("row_selection", @@ -1296,31 +1296,31 @@ e_table_class_init (GtkObjectClass *object_class) e_marshal_INT__INT_INT_POINTER, GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_POINTER); - et_signals[DRAG_BEGIN] = - gtk_signal_new ("drag_begin", + et_signals[TABLE_DRAG_BEGIN] = + gtk_signal_new ("table_drag_begin", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_begin), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_begin), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_END] = - gtk_signal_new ("drag_end", + et_signals[TABLE_DRAG_END] = + gtk_signal_new ("table_drag_end", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_end), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_end), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_DATA_GET] = - gtk_signal_new ("drag_data_get", + et_signals[TABLE_DRAG_DATA_GET] = + gtk_signal_new ("table_drag_data_get", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_get), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_get), e_marshal_NONE__INT_INT_POINTER_POINTER_UINT_UINT, GTK_TYPE_NONE, 6, GTK_TYPE_INT, @@ -1329,33 +1329,33 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_SELECTION_DATA, GTK_TYPE_UINT, GTK_TYPE_UINT); - et_signals[DRAG_DATA_DELETE] = - gtk_signal_new ("drag_data_delete", + et_signals[TABLE_DRAG_DATA_DELETE] = + gtk_signal_new ("table_drag_data_delete", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_delete), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_delete), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT); - et_signals[DRAG_LEAVE] = - gtk_signal_new ("drag_leave", + et_signals[TABLE_DRAG_LEAVE] = + gtk_signal_new ("table_drag_leave", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_leave), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_leave), e_marshal_NONE__INT_INT_POINTER_UINT, GTK_TYPE_NONE, 4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_DRAG_CONTEXT, GTK_TYPE_UINT); - et_signals[DRAG_MOTION] = - gtk_signal_new ("drag_motion", + et_signals[TABLE_DRAG_MOTION] = + gtk_signal_new ("table_drag_motion", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_motion), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_motion), e_marshal_BOOL__INT_INT_POINTER_INT_INT_UINT, GTK_TYPE_BOOL, 6, GTK_TYPE_INT, @@ -1364,11 +1364,11 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_UINT); - et_signals[DRAG_DROP] = - gtk_signal_new ("drag_drop", + et_signals[TABLE_DRAG_DROP] = + gtk_signal_new ("table_drag_drop", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_drop), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_drop), e_marshal_BOOL__INT_INT_POINTER_INT_INT_UINT, GTK_TYPE_BOOL, 6, GTK_TYPE_INT, @@ -1377,11 +1377,11 @@ e_table_class_init (GtkObjectClass *object_class) GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_UINT); - et_signals[DRAG_DATA_RECEIVED] = - gtk_signal_new ("drag_data_received", + et_signals[TABLE_DRAG_DATA_RECEIVED] = + gtk_signal_new ("table_drag_data_received", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (ETableClass, drag_data_received), + GTK_SIGNAL_OFFSET (ETableClass, table_drag_data_received), e_marshal_NONE__INT_INT_POINTER_INT_INT_POINTER_UINT_UINT, GTK_TYPE_NONE, 8, GTK_TYPE_INT, diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h index 85d0e387bd..7612cddebe 100644 --- a/widgets/table/e-table.h +++ b/widgets/table/e-table.h @@ -88,55 +88,55 @@ typedef struct { GtkAdjustment *vadjustment); /* Source side drag signals */ - void (* drag_begin) (ETable *table, + void (* table_drag_begin) (ETable *table, + int row, + int col, + GdkDragContext *context); + void (* table_drag_end) (ETable *table, int row, int col, GdkDragContext *context); - void (* drag_end) (ETable *table, - int row, - int col, - GdkDragContext *context); - void (* drag_data_get) (ETable *table, - int row, - int col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); - void (* drag_data_delete) (ETable *table, - int row, - int col, - GdkDragContext *context); - + void (* table_drag_data_get) (ETable *table, + int row, + int col, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); + void (* table_drag_data_delete) (ETable *table, + int row, + int col, + GdkDragContext *context); + /* Target side drag signals */ - void (* drag_leave) (ETable *table, - int row, - int col, - GdkDragContext *context, - guint time); - gboolean (* drag_motion) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - guint time); - gboolean (* drag_drop) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - guint time); - void (* drag_data_received) (ETable *table, - int row, - int col, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); + void (* table_drag_leave) (ETable *table, + int row, + int col, + GdkDragContext *context, + guint time); + gboolean (* table_drag_motion) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + guint time); + gboolean (* table_drag_drop) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + guint time); + void (* table_drag_data_received) (ETable *table, + int row, + int col, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); } ETableClass; GtkType e_table_get_type (void); |