struct _EAddressbookTableAdapterPrivate {
EAddressbookModel *model;
gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
GHashTable *emails;
};
#define PARENT_TYPE e_table_model_get_type()
static ETableModelClass *parent_class;
#define COLS (E_CONTACT_FIELD_LAST)
static void
unlink_model (EAddressbookTableAdapter *adapter)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
g_signal_handler_disconnect (priv->model,
priv->create_contact_id);
g_signal_handler_disconnect (priv->model,
priv->remove_contact_id);
g_signal_handler_disconnect (priv->model,
priv->modify_contact_id);
g_signal_handler_disconnect (priv->model,
priv->model_changed_id);
priv->create_contact_id = 0;
priv->remove_contact_id = 0;
priv->modify_contact_id = 0;
priv->model_changed_id = 0;
g_object_unref (priv->model);
priv->model = NULL;
}
static void
addressbook_dispose (GObject *object)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (object);
if (adapter->priv) {
unlink_model (adapter);
g_hash_table_remove_all (adapter->priv->emails);
g_hash_table_destroy (adapter->priv->emails);
g_free (adapter->priv);
adapter->priv = NULL;
}
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
/* This function returns the number of columns in our ETableModel. */
static gint
addressbook_col_count (ETableModel *etc)
{
return COLS;
}
/* This function returns the number of rows in our ETableModel. */
static gint
addressbook_row_count (ETableModel *etc)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
return e_addressbook_model_contact_count (priv->model);
}
/* This function returns the value at a particular point in our ETableModel. */
static gpointer
addressbook_value_at (ETableModel *etc, gint col, gint row)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
const gchar *value;
if (col >= COLS || row >= e_addressbook_model_contact_count (priv->model))
return NULL;
value = e_contact_get_const ((EContact*)e_addressbook_model_contact_at (priv->model, row), col);
if (value && *value && (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) {
gchar *val = g_hash_table_lookup (priv->emails, value);
if (val) {
/* we have this already cached, so use value from the cache */
value = val;
} else {
gchar *name = NULL, *mail = NULL;
if (eab_parse_qp_email (value, &name, &mail))
val = g_strdup_printf ("%s <%s>", name, mail);
else
val = g_strdup (value);
g_free (name);
g_free (mail);
g_hash_table_insert (priv->emails, g_strdup (value), val);
value = val;
}
}
return (gpointer)(value ? value : "");
}
/* This function sets the value at a particular point in our ETableModel. */
static void
contact_modified_cb (EBook* book, const GError *error,
gpointer user_data)
{
if (error)
eab_error_dialog (_("Error modifying card"), error);
}
static void
addressbook_set_value_at (ETableModel *etc, gint col, gint row, gconstpointer val)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
if (e_addressbook_model_get_editable (priv->model)) {
EContact *contact;
if (col >= COLS || row >= e_addressbook_model_contact_count (priv->model))
return;
contact = e_addressbook_model_get_contact (priv->model, row);
if (!contact)
return;
e_table_model_pre_change (etc);
if (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3) {
const gchar *old_value = e_contact_get_const (contact, col);
/* remove old value from cache and use new one */
if (old_value && *old_value)
g_hash_table_remove (priv->emails, old_value);
}
e_contact_set (contact, col, (gpointer) val);
eab_merging_book_commit_contact (e_addressbook_model_get_book (priv->model),
contact, contact_modified_cb, etc);
g_object_unref (contact);
/* XXX do we need this? shouldn't the commit_contact 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, gint col, gint row)
{
#if 0
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
const EContact *contact;
if (row >= 0 && row < e_addressbook_model_contact_count (priv->model))
contact = e_addressbook_model_contact_at (priv->model, row);
else
contact = NULL;
if (!e_addressbook_model_editable (priv->model))
return FALSE;
else if (contact && e_contact_get ((EContact *) contact, E_CONTACT_IS_LIST))
/* we only allow editing of the name and file as for
lists */
return col == E_CONTACT_FULL_NAME || col == E_CONTACT_FILE_AS;
else
return col < E_CONTACT_LAST_SIMPLE_STRING;
#endif
return FALSE;
}
static void
addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (etm);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
EContact *contact;
gint col;
contact = e_contact_new ();
for (col = 1; col < E_CONTACT_LAST_SIMPLE_STRING; col++) {
gconstpointer val = e_table_model_value_at (source, col, row);
e_contact_set (contact, col, (gpointer) val);
}
eab_merging_book_add_contact (e_addressbook_model_get_book (priv->model), contact, NULL, NULL);
g_object_unref (contact);
}
/* This function duplicates the value passed to it. */
static gpointer
addressbook_duplicate_value (ETableModel *etc, gint col, gconstpointer value)
{
return g_strdup (value);
}
/* This function frees the value passed to it. */
static void
addressbook_free_value (ETableModel *etc, gint col, gpointer value)
{
g_free (value);
}
static gpointer
addressbook_initialize_value (ETableModel *etc, gint col)
{
return g_strdup("");
}
static gboolean
addressbook_value_is_empty (ETableModel *etc, gint col, gconstpointer value)
{
return !(value && *(gchar *)value);
}
static gchar *
addressbook_value_to_string (ETableModel *etc, gint col, gconstpointer value)
{
return g_strdup (value);
}
static void
eab_table_adapter_class_init (GObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
parent_class = g_type_class_peek_parent (object_class);
object_class->dispose = addressbook_dispose;
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
eab_table_adapter_init (GObject *object)
{
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER (object);
EAddressbookTableAdapterPrivate *priv;
priv = adapter->priv = g_new0 (EAddressbookTableAdapterPrivate, 1);
priv->create_contact_id = 0;
priv->remove_contact_id = 0;
priv->modify_contact_id = 0;
priv->model_changed_id = 0;
}
static void
create_contact (EAddressbookModel *model,
gint index, gint count,
EAddressbookTableAdapter *adapter)
{
e_table_model_pre_change (E_TABLE_MODEL (adapter));
e_table_model_rows_inserted (E_TABLE_MODEL (adapter), index, count);
}
static void
remove_contacts (EAddressbookModel *model,
gpointer data,
EAddressbookTableAdapter *adapter)
{
GArray *indices = (GArray *) data;
gint count = indices->len;
/* clear whole cache */
g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
if (count == 1)
e_table_model_rows_deleted (E_TABLE_MODEL (adapter), g_array_index (indices, gint, 0), 1);
else
e_table_model_changed (E_TABLE_MODEL (adapter));
}
static void
modify_contact (EAddressbookModel *model,
gint index,
EAddressbookTableAdapter *adapter)
{
/* clear whole cache */
g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
e_table_model_row_changed (E_TABLE_MODEL (adapter), index);
}
static void
model_changed (EAddressbookModel *model,
EAddressbookTableAdapter *adapter)
{
/* clear whole cache */
g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
e_table_model_changed (E_TABLE_MODEL (adapter));
}
GType
eab_table_adapter_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
sizeof (EAddressbookTableAdapterClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) eab_table_adapter_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EAddressbookTableAdapter),
0, /* n_preallocs */
(GInstanceInitFunc) eab_table_adapter_init,
};
type = g_type_register_static (PARENT_TYPE, "EAddressbookTableAdapter", &info, 0);
}
return type;
}
void
eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
EAddressbookModel *model)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
priv->model = model;
g_object_ref (priv->model);
priv->create_contact_id = g_signal_connect (priv->model,
"contact_added",
G_CALLBACK (create_contact),
adapter);
priv->remove_contact_id = g_signal_connect (priv->model,
"contacts_removed",
G_CALLBACK (remove_contacts),
adapter);
priv->modify_contact_id = g_signal_connect (priv->model,
"contact_changed",
G_CALLBACK (modify_contact),
adapter);
priv->model_changed_id = g_signal_connect (priv->model,
"model_changed",
G_CALLBACK (model_changed),
adapter);
priv->emails = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_free);
}
ETableModel *
eab_table_adapter_new (EAddressbookModel *model)
{
EAddressbookTableAdapter *et;
et = g_object_new (E_TYPE_AB_TABLE_ADAPTER, NULL);
eab_table_adapter_construct (et, model);
return E_TABLE_MODEL (et);
}
a>dinoex | 2009-07-31 | 1 | -0/+1 |
* | Update to 4.0.4. | mezz | 2009-05-10 | 3 | -4/+6 |
* | Update to 4.0.2. | mezz | 2009-01-02 | 3 | -4/+7 |
* | Update to 4.0.1. | mezz | 2008-12-16 | 4 | -75/+82 |
* | Fix the plist, bump the PORTREVISION. | mezz | 2008-12-05 | 2 | -15/+16 |
* | Update to 4.0.0. | mezz | 2008-12-05 | 4 | -78/+203 |
* | Update to 3.6.5. See Changelog for details: | mezz | 2008-07-09 | 4 | -6/+23 |
* | Bump portrevision due to upgrade of devel/gettext. | edwin | 2008-06-06 | 1 | -1/+1 |
* | Remove USE_XLIB, bump the PORTREVISION on homebank and comix. As for the buoh, | mezz | 2008-03-22 | 1 | -1/+1 |
* | Update to 3.6.4, see changelog for details: | mezz | 2007-05-29 | 3 | -5/+6 |
* | - Welcome X.org 7.2 \o/. | flz | 2007-05-20 | 2 | -11/+1 |
* | Update to 3.6.3, see changelog for details: | mezz | 2007-03-18 | 3 | -4/+5 |
* | Update to 3.6.2. | mezz | 2007-02-04 | 3 | -4/+5 |
* | Update to 3.6.1. | mezz | 2006-11-04 | 2 | -6/+5 |
* | Chase the GNOME X11BASE to LOCALBASE move, and fix the build with the | marcus | 2006-10-14 | 2 | -2/+15 |
* | Update to 3.6, see changelog for details: | mezz | 2006-10-04 | 3 | -9/+11 |
* | Update to 3.5.1, see changelog for details: | mezz | 2006-08-26 | 3 | -7/+18 |
* | Update to 3.4, see changelog for details: | mezz | 2006-08-01 | 3 | -4/+16 |
* | Update to 3.3, see changelog for details: | mezz | 2006-07-05 | 3 | -11/+13 |
* | Update to 3.2.1, see changelog for details: | mezz | 2006-06-25 | 2 | -4/+4 |
* | Update to 3.2, see changelog for details: | mezz | 2006-06-14 | 3 | -4/+7 |
* | Update to 3.1.3, see changelog for details: | mezz | 2006-05-21 | 3 | -4/+5 |
* | Update to 3.1.2, see changelog for details: | mezz | 2006-05-20 | 2 | -4/+5 |
* | Update to 3.1, see changelog for detail: | mezz | 2006-05-08 | 3 | -4/+5 |
* | Update to 3.0.1. | mezz | 2006-04-15 | 3 | -5/+5 |
* | Add INSTALLS_ICONS, bump the PORTREVISION. | mezz | 2006-04-12 | 1 | -0/+2 |
* | Update to 3.0, see changelog for details: | mezz | 2006-04-05 | 3 | -5/+8 |
* | portlint: | mezz | 2006-04-01 | 1 | -1/+1 |
* | Update to 2.9, see changelog for details: | mezz | 2006-02-22 | 2 | -4/+4 |
* | - Update to 2.8. | mezz | 2006-02-12 | 3 | -19/+43 |
* | Update to 2.7, see changelog for details: | mezz | 2006-01-31 | 3 | -7/+22 |
* | Replace ugly "@unexec rmdir %D... 2>/dev/null || true" with @dirrmtry | edwin | 2006-01-22 | 1 | -1/+1 |
* | Update to 2.6, see changelog for detail. | mezz | 2006-01-17 | 2 | -4/+4 |
* | Update to 2.5. | mezz | 2006-01-10 | 2 | -4/+4 |
* | Update to 2.4.1. | mezz | 2006-01-03 | 3 | -4/+7 |
* | Update to 2.3. | mezz | 2005-12-21 | 3 | -5/+12 |
* | Update to 2.2.1. | mezz | 2005-12-12 | 2 | -4/+4 |