From 934524b95cb86abae6b1457ff5d4853fb702cb87 Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Wed, 16 May 2001 05:17:09 +0000 Subject: MinicardViewModel -> ReflowAdapter name change. (get_card_list): same. 2001-05-15 Chris Toshok * gui/widgets/e-minicard-view.c (add_to_list): MinicardViewModel -> ReflowAdapter name change. (get_card_list): same. (e_minicard_view_drag_begin): same. (supported_fields_cb): model -> adapter. (adapter_changed): hook up signals and set the empty message on our adapter. (e_minicard_view_set_arg): add support for "adapter", and set model -> adapter. (e_minicard_view_get_arg): same. (disconnect_signals): no more status_message. (do_remove): track to use adapter. (e_minicard_view_class_init): add adapter arg, and remove status_message. (e_minicard_view_init): all the code here is in adapter_changed now. * gui/widgets/e-minicard-view.h (struct _EMinicardView): EMinicardViewModel -> EAddressbookReflowAdapter. (struct _EMinicardViewClass): get rid of status_message. * gui/widgets/e-minicard-view-widget.c (e_minicard_view_widget_class_init): remove the status_message signal. (e_minicard_view_widget_new): take the adapter as our argument, and store it away for when we create the view. (e_minicard_view_widget_realize): when we create the view just set the adapter field on it. also, don't connect to status_message. * gui/widgets/e-minicard-view-widget.h (struct _EMinicardViewWidget): add our adapter here, so we can pass it into the view when we create it. (struct _EMinicardViewWidgetClass): remove status_message. * gui/widgets/e-addressbook-view.c (status_message): new function, no more propagating status messages! (e_addressbook_view_init): create our model and conenct to its status_message signal. (book_writable_cb): set "editable" on the model, not our object. (e_addressbook_view_set_arg): same, but with "book" and "query" as well. (create_minicard_view): create our reflow adapter and pass it to the minicard view widget. also, call e_reflow_model_changed so it'll pick up any already present cards. (table_double_click): ADDRESSBOOK_MODEL -> TABLE_ADAPTER. (get_card_list_1): remove the cast, since we don't need it any longer. (table_right_click): ADDRESSBOOK_MODEL -> TABLE_ADAPTER. (table_drag_data_get): same. (create_table_view): create the table adapter, and use it as our ETableModel. (change_view_type): remove the status_message hook up and setting of query/book/editable. (e_addressbook_view_stop): just call e_addressbook_model_stop here instead of switching on the view type. * gui/widgets/e-addressbook-view.h (struct _EAddressbookView): add our EAddressbookModel. * gui/widgets/Makefile.am (libeminicard_a_SOURCES): add the adapter files, and remove e-minicard-view-model.[ch]. * gui/widgets/e-minicard-view-model.[ch]: removed. * gui/widgets/e-addressbook-table-adapter.c: new file. * gui/widgets/e-addressbook-table-adapter.h: new file. * gui/widgets/e-addressbook-reflow-adapter.c: new file. * gui/widgets/e-addressbook-reflow-adapter.h: new file. * gui/widgets/e-addressbook-model.c: rework this class to now subclass from ETableModel anymore. It not subclasses from GtkObject, and we use table and reflow adapters to get at the data. * gui/widgets/e-addressbook-model.h: same. svn path=/trunk/; revision=9837 --- .../gui/widgets/e-addressbook-table-adapter.c | 353 +++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 addressbook/gui/widgets/e-addressbook-table-adapter.c (limited to 'addressbook/gui/widgets/e-addressbook-table-adapter.c') diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c new file mode 100644 index 0000000000..01337bf8e3 --- /dev/null +++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c @@ -0,0 +1,353 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +#include +#include "e-addressbook-model.h" +#include "e-addressbook-table-adapter.h" +#include +#include +#include +#include + +struct _EAddressbookTableAdapterPrivate { + EAddressbookModel *model; + + ECardSimple **simples; + int count; + + int create_card_id, remove_card_id, modify_card_id, model_changed_id; +}; + +#define PARENT_TYPE e_table_model_get_type() +ETableModelClass *parent_class; + +#define COLS (E_CARD_SIMPLE_FIELD_LAST) + +static void +unlink_model(EAddressbookTableAdapter *adapter) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + + gtk_signal_disconnect(GTK_OBJECT (priv->model), + priv->create_card_id); + gtk_signal_disconnect(GTK_OBJECT (priv->model), + priv->remove_card_id); + gtk_signal_disconnect(GTK_OBJECT (priv->model), + priv->modify_card_id); + gtk_signal_disconnect(GTK_OBJECT (priv->model), + priv->model_changed_id); + + priv->create_card_id = 0; + priv->remove_card_id = 0; + priv->modify_card_id = 0; + priv->model_changed_id = 0; + + gtk_object_unref(GTK_OBJECT(priv->model)); + + priv->model = NULL; +} + +static void +build_simple_mapping(EAddressbookTableAdapter *adapter) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + int i; + + /* free up the existing mapping if there is one */ + if (priv->simples) { + for (i = 0; i < priv->count; i ++) + gtk_object_unref (GTK_OBJECT (priv->simples[i])); + g_free (priv->simples); + } + + /* build up our mapping to ECardSimple*'s */ + priv->count = e_addressbook_model_card_count (priv->model); + priv->simples = g_new (ECardSimple*, priv->count); + for (i = 0; i < priv->count; i ++) { + priv->simples[i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, i)); + gtk_object_ref (GTK_OBJECT (priv->simples[i])); + } +} + +static void +addressbook_destroy(GtkObject *object) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object); + + unlink_model(adapter); +} + +/* This function returns the number of columns in our ETableModel. */ +static int +addressbook_col_count (ETableModel *etc) +{ + return COLS; +} + +/* This function returns the number of rows in our ETableModel. */ +static int +addressbook_row_count (ETableModel *etc) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc); + EAddressbookTableAdapterPrivate *priv = adapter->priv; + + return e_addressbook_model_card_count (priv->model); +} + +/* This function returns the value at a particular point in our ETableModel. */ +static void * +addressbook_value_at (ETableModel *etc, int col, int row) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc); + EAddressbookTableAdapterPrivate *priv = adapter->priv; + const char *value; + if ( col >= COLS || row >= e_addressbook_model_card_count (priv->model) ) + return NULL; + + value = e_card_simple_get_const(priv->simples[row], col); + return (void *)(value ? value : ""); +} + +/* This function sets the value at a particular point in our ETableModel. */ +static void +addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc); + EAddressbookTableAdapterPrivate *priv = adapter->priv; + if (e_addressbook_model_editable (priv->model)) { + ECard *card; + + if ( col >= COLS|| row >= e_addressbook_model_card_count (priv->model) ) + return; + + e_card_simple_set(priv->simples[row], + col, + val); + gtk_object_get(GTK_OBJECT(priv->simples[row]), + "card", &card, + NULL); + + e_book_commit_card(e_addressbook_model_get_ebook(priv->model), + card, NULL, NULL); + + /* XXX do we need this? shouldn't the commit_card generate a changed signal? */ + e_table_model_cell_changed(etc, col, row); + } +} + +/* This function returns whether a particular cell is editable. */ +static gboolean +addressbook_is_cell_editable (ETableModel *etc, int col, int row) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc); + EAddressbookTableAdapterPrivate *priv = adapter->priv; + return e_addressbook_model_editable(priv->model) && col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; +} + +static void +addressbook_append_row (ETableModel *etm, ETableModel *source, gint row) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etm); + EAddressbookTableAdapterPrivate *priv = adapter->priv; + ECard *card; + ECardSimple *simple; + int col; + + card = e_card_new(""); + simple = e_card_simple_new(card); + + for (col = 0; col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; col++) { + const void *val = e_table_model_value_at(source, col, row); + e_card_simple_set(simple, col, val); + } + e_card_simple_sync_card(simple); + e_book_add_card (e_addressbook_model_get_ebook (priv->model), card, NULL, NULL); + gtk_object_unref(GTK_OBJECT(simple)); + gtk_object_unref(GTK_OBJECT(card)); +} + +/* This function duplicates the value passed to it. */ +static void * +addressbook_duplicate_value (ETableModel *etc, int col, const void *value) +{ + return g_strdup(value); +} + +/* This function frees the value passed to it. */ +static void +addressbook_free_value (ETableModel *etc, int col, void *value) +{ + g_free(value); +} + +static void * +addressbook_initialize_value (ETableModel *etc, int col) +{ + return g_strdup(""); +} + +static gboolean +addressbook_value_is_empty (ETableModel *etc, int col, const void *value) +{ + return !(value && *(char *)value); +} + +static char * +addressbook_value_to_string (ETableModel *etc, int col, const void *value) +{ + return g_strdup(value); +} + +static void +e_addressbook_table_adapter_class_init (GtkObjectClass *object_class) +{ + ETableModelClass *model_class = (ETableModelClass *) object_class; + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = addressbook_destroy; + + model_class->column_count = addressbook_col_count; + model_class->row_count = addressbook_row_count; + model_class->value_at = addressbook_value_at; + model_class->set_value_at = addressbook_set_value_at; + model_class->is_cell_editable = addressbook_is_cell_editable; + model_class->append_row = addressbook_append_row; + model_class->duplicate_value = addressbook_duplicate_value; + model_class->free_value = addressbook_free_value; + model_class->initialize_value = addressbook_initialize_value; + model_class->value_is_empty = addressbook_value_is_empty; + model_class->value_to_string = addressbook_value_to_string; +} + +static void +e_addressbook_table_adapter_init (GtkObject *object) +{ + EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object); + EAddressbookTableAdapterPrivate *priv; + + priv = adapter->priv = g_new0 (EAddressbookTableAdapterPrivate, 1); + + priv->create_card_id = 0; + priv->remove_card_id = 0; + priv->modify_card_id = 0; + priv->model_changed_id = 0; + priv->simples = NULL; + priv->count = 0; +} + + +static void +create_card (EAddressbookModel *model, + gint index, gint count, + EAddressbookTableAdapter *adapter) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + int i; + + priv->count += count; + priv->simples = g_renew(ECardSimple *, priv->simples, priv->count); + memmove (priv->simples + index + count - 1, priv->simples + index, count * sizeof (ECardSimple*)); + + e_table_model_pre_change (E_TABLE_MODEL (adapter)); + for (i = 0; i < count; i ++) { + priv->simples[index + i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index + i)); + gtk_object_ref (GTK_OBJECT (priv->simples[index + i])); + e_table_model_row_inserted (E_TABLE_MODEL (adapter), index + i); + } +} + +static void +remove_card (EAddressbookModel *model, + gint index, + EAddressbookTableAdapter *adapter) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + gtk_object_unref (GTK_OBJECT (priv->simples[index])); + if (priv->count > 1) + memmove (priv->simples + index, priv->simples + index + 1, (priv->count - index - 1) * sizeof (ECardSimple*)); + priv->count --; + e_table_model_rows_deleted (E_TABLE_MODEL (adapter), index, 1); +} + +static void +modify_card (EAddressbookModel *model, + gint index, + EAddressbookTableAdapter *adapter) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + e_table_model_row_changed (E_TABLE_MODEL (adapter), index); + gtk_object_unref (GTK_OBJECT (priv->simples[index])); + priv->simples[index] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index)); + gtk_object_ref (GTK_OBJECT (priv->simples[index])); +} + +static void +model_changed (EAddressbookModel *model, + EAddressbookTableAdapter *adapter) +{ + build_simple_mapping (adapter); + e_table_model_changed (E_TABLE_MODEL (adapter)); +} + +GtkType +e_addressbook_table_adapter_get_type (void) +{ + static GtkType type = 0; + + if (!type){ + GtkTypeInfo info = { + "EAddressbookTableAdapter", + sizeof (EAddressbookTableAdapter), + sizeof (EAddressbookTableAdapterClass), + (GtkClassInitFunc) e_addressbook_table_adapter_class_init, + (GtkObjectInitFunc) e_addressbook_table_adapter_init, + NULL, /* reserved 1 */ + NULL, /* reserved 2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +void +e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter, + EAddressbookModel *model) +{ + EAddressbookTableAdapterPrivate *priv = adapter->priv; + + priv->model = model; + + priv->create_card_id = gtk_signal_connect(GTK_OBJECT(priv->model), + "card_added", + GTK_SIGNAL_FUNC(create_card), + adapter); + priv->remove_card_id = gtk_signal_connect(GTK_OBJECT(priv->model), + "card_removed", + GTK_SIGNAL_FUNC(remove_card), + adapter); + priv->modify_card_id = gtk_signal_connect(GTK_OBJECT(priv->model), + "card_changed", + GTK_SIGNAL_FUNC(modify_card), + adapter); + priv->model_changed_id = gtk_signal_connect(GTK_OBJECT(priv->model), + "model_changed", + GTK_SIGNAL_FUNC(model_changed), + adapter); + + build_simple_mapping (adapter); +} + +ETableModel * +e_addressbook_table_adapter_new (EAddressbookModel *model) +{ + EAddressbookTableAdapter *et; + + et = gtk_type_new (e_addressbook_table_adapter_get_type ()); + + e_addressbook_table_adapter_construct (et, model); + + return E_TABLE_MODEL(et); +} -- cgit v1.2.3