GncPluginPage * gnc_plugin_page_owner_tree_new (GncOwnerType owner_type) { GncPluginPageOwnerTree *plugin_page; GncPluginPageOwnerTreePrivate *priv; const GList *item; GtkActionGroup *action_group; GtkAction *action; GValue gvalue = { 0 }; gint i; g_return_val_if_fail( (owner_type != GNC_OWNER_UNDEFINED) && (owner_type != GNC_OWNER_NONE), NULL); ENTER(" "); /* Is there an existing page? */ item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_OWNER_TREE_NAME); for ( ; item; item = g_list_next(item)) { plugin_page = (GncPluginPageOwnerTree *)item->data; priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page); if (priv->owner_type == owner_type) { LEAVE("existing %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page); return GNC_PLUGIN_PAGE(plugin_page); } } plugin_page = g_object_new(GNC_TYPE_PLUGIN_PAGE_OWNER_TREE, NULL); priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page); priv->owner_type = owner_type; /* Hide menu and toolbar items that are not relevant for the active owner list */ action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(plugin_page)); g_value_init (&gvalue, G_TYPE_BOOLEAN); for (i = 0; action_owners[i].action_name; i++) { action = gtk_action_group_get_action (action_group, action_owners[i].action_name); g_value_set_boolean (&gvalue, (priv->owner_type == action_owners[i].owner_type) ); g_object_set_property (G_OBJECT(action), "visible", &gvalue); } LEAVE("new %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page); return GNC_PLUGIN_PAGE(plugin_page); }
GtkTreeModel * gnc_tree_model_owner_new (GncOwnerType owner_type) { GncTreeModelOwner *model; GncTreeModelOwnerPrivate *priv; const GList *item; ENTER("owner_type %d", owner_type); item = gnc_gobject_tracking_get_list(GNC_TREE_MODEL_OWNER_NAME); for ( ; item; item = g_list_next(item)) { model = (GncTreeModelOwner *)item->data; priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model); if (priv->owner_type == owner_type) { g_object_ref(G_OBJECT(model)); LEAVE("returning existing model %p", model); return GTK_TREE_MODEL(model); } } model = g_object_new (GNC_TYPE_TREE_MODEL_OWNER, NULL); priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model); priv->book = gnc_get_current_book(); priv->owner_type = owner_type; priv->owner_list = gncBusinessGetOwnerList (priv->book, gncOwnerTypeToQofIdType(owner_type), TRUE); priv->event_handler_id = qof_event_register_handler ((QofEventHandler)gnc_tree_model_owner_event_handler, model); LEAVE("model %p", model); return GTK_TREE_MODEL (model); }
/** Select the row in the tree that was selected when the user last * quit gnucash. Its job is to map from owner name to tree row and * select the row. * * @param tree A pointer to the GncTreeViewOwner embedded. * * @param owner_name A pointer to the full owner name. */ static void tree_restore_selected_row (GncTreeViewOwner *view, GncOwnerType owner_type, const gchar *owner_guid_str) { GncOwner *owner = gncOwnerNew(); QofBook *book; GncGUID owner_guid; book = qof_session_get_book (gnc_get_current_session()); if (string_to_guid (owner_guid_str, &owner_guid)) if (gncOwnerGetOwnerFromTypeGuid (book, owner, gncOwnerTypeToQofIdType(owner_type), &owner_guid)) gnc_tree_view_owner_set_selected_owner(view, owner); }
/** This function is the handler for all event messages from the * engine. Its purpose is to update the owner tree model any time * an owner is added to the engine or deleted from the engine. * This change to the model is then propagated to any/all overlying * filters and views. This function listens to the ADD, REMOVE, and * DESTROY events. * * @internal * * @warning There is a "Catch 22" situation here. * gtk_tree_model_row_deleted() can't be called until after the item * has been deleted from the real model (which is the engine's * owner tree for us), but once the owner has been deleted from * the engine we have no way to determine the path to pass to * row_deleted(). This is a PITA, but the only other choice is to * have this model mirror the engine's owners instead of * referencing them directly. * * @param entity The guid of the affected item. * * @param type The type of the affected item. This function only * cares about items of type "owner". * * @param event type The type of the event. This function only cares * about items of type ADD, REMOVE, MODIFY, and DESTROY. * * @param user_data A pointer to the owner tree model. */ static void gnc_tree_model_owner_event_handler (QofInstance *entity, QofEventId event_type, GncTreeModelOwner *model, GncEventData *ed) { GncTreeModelOwnerPrivate *priv; GtkTreePath *path = NULL; GtkTreeIter iter; GncOwner owner; g_return_if_fail(model); /* Required */ if (!GNC_IS_OWNER(entity)) return; ENTER("entity %p of type %d, model %p, event_data %p", entity, event_type, model, ed); priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model); qofOwnerSetEntity (&owner, entity); if (gncOwnerGetType(&owner) != priv->owner_type) { LEAVE("model type and owner type differ"); return; } if (qof_instance_get_book (entity) != priv->book) { LEAVE("not in this book"); return; } /* What to do, that to do. */ switch (event_type) { case QOF_EVENT_ADD: /* Tell the filters/views where the new owner was added. */ DEBUG("add owner %p (%s)", &owner, gncOwnerGetName(&owner)); /* First update our copy of the owner list. This isn't done automatically */ priv->owner_list = gncBusinessGetOwnerList (priv->book, gncOwnerTypeToQofIdType(priv->owner_type), TRUE); increment_stamp(model); if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter)) { LEAVE("can't generate iter"); break; } path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter); if (!path) { DEBUG("can't generate path"); break; } gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter); break; case QOF_EVENT_REMOVE: if (!ed) /* Required for a remove. */ break; DEBUG("remove owner %d (%s) from owner_list %p", ed->idx, gncOwnerGetName(&owner), priv->owner_list); path = gtk_tree_path_new(); if (!path) { DEBUG("can't generate path"); break; } increment_stamp(model); gtk_tree_path_append_index (path, ed->idx); gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path); break; case QOF_EVENT_MODIFY: DEBUG("modify owner %p (%s)", &owner, gncOwnerGetName(&owner)); if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter)) { LEAVE("can't generate iter"); return; } path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter); if (!path) { DEBUG("can't generate path"); break; } gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter); break; default: LEAVE("unknown event type"); return; } if (path) gtk_tree_path_free(path); LEAVE(" "); return; }
static void gnc_tree_model_owner_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, int column, GValue *value) { GncTreeModelOwner *model = GNC_TREE_MODEL_OWNER (tree_model); GncOwner *owner; gboolean negative; /* used to set "deficit style" also known as red numbers */ gchar *string = NULL; g_return_if_fail (GNC_IS_TREE_MODEL_OWNER (model)); g_return_if_fail (iter != NULL); g_return_if_fail (iter->user_data != NULL); g_return_if_fail (iter->stamp == model->stamp); ENTER("model %p, iter %s, col %d", tree_model, iter_to_string(iter), column); owner = (GncOwner *) iter->user_data; switch (column) { case GNC_TREE_MODEL_OWNER_COL_NAME: g_value_init (value, G_TYPE_STRING); g_value_set_string (value, gncOwnerGetName (owner)); break; case GNC_TREE_MODEL_OWNER_COL_TYPE: g_value_init (value, G_TYPE_STRING); g_value_set_string (value, gncOwnerTypeToQofIdType (gncOwnerGetType (owner))); break; case GNC_TREE_MODEL_OWNER_COL_ID: g_value_init (value, G_TYPE_STRING); g_value_set_string (value, gncOwnerGetID (owner)); break; case GNC_TREE_MODEL_OWNER_COL_CURRENCY: g_value_init (value, G_TYPE_STRING); g_value_set_string (value, gnc_commodity_get_fullname(gncOwnerGetCurrency (owner))); break; case GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetName (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_ADDRESS_1: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetAddr1 (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_ADDRESS_2: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetAddr2 (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_ADDRESS_3: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetAddr3 (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_ADDRESS_4: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetAddr4 (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_PHONE: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetPhone (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_FAX: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetFax (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_EMAIL: g_value_init (value, G_TYPE_STRING); string = g_strdup (gncAddressGetEmail (gncOwnerGetAddr (owner))); if (string) g_value_take_string (value, string); else g_value_set_static_string (value, ""); break; case GNC_TREE_MODEL_OWNER_COL_BALANCE: g_value_init (value, G_TYPE_STRING); string = gnc_ui_owner_get_print_balance(owner, &negative); g_value_take_string (value, string); break; case GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT: g_value_init (value, G_TYPE_STRING); string = gnc_ui_owner_get_print_report_balance(owner, &negative); g_value_take_string (value, string); break; case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE: g_value_init (value, G_TYPE_STRING); string = gnc_ui_owner_get_print_balance(owner, &negative); gnc_tree_model_owner_set_color(model, negative, value); g_free(string); break; case GNC_TREE_MODEL_OWNER_COL_NOTES: g_value_init (value, G_TYPE_STRING); switch (gncOwnerGetType (owner)) { case GNC_OWNER_NONE: case GNC_OWNER_UNDEFINED: case GNC_OWNER_EMPLOYEE: case GNC_OWNER_JOB: default: g_value_set_static_string (value, ""); break; case GNC_OWNER_VENDOR: g_value_set_string (value, gncVendorGetNotes (gncOwnerGetVendor (owner))); break; case GNC_OWNER_CUSTOMER: g_value_set_string (value, gncCustomerGetNotes (gncOwnerGetCustomer (owner))); break; } break; case GNC_TREE_MODEL_OWNER_COL_ACTIVE: g_value_init (value, G_TYPE_BOOLEAN); g_value_set_boolean (value, gncOwnerGetActive (owner)); break; default: g_assert_not_reached (); } LEAVE(" "); }
QofIdTypeConst qofOwnerGetType(const GncOwner *owner) { return gncOwnerTypeToQofIdType(owner->type); }
/* * Create a new owner tree view for one type of owners. * This view will be based on a model that is common to all views of * the same set of books, but will have its own private filter on that * model. */ GtkTreeView * gnc_tree_view_owner_new (GncOwnerType owner_type) { GncTreeView *view; GtkTreeModel *model, *f_model, *s_model; const gchar *sample_type, *sample_currency; GncTreeViewOwnerPrivate *priv; GtkTreeViewColumn *tax_info_column; GtkCellRenderer *renderer; ENTER(" "); /* Create our view */ view = g_object_new (GNC_TYPE_TREE_VIEW_OWNER, "name", "owner_tree", NULL); priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(GNC_TREE_VIEW_OWNER (view)); /* Create/get a pointer to the existing model for this set of books. */ model = gnc_tree_model_owner_new (owner_type); /* Set up the view private filter layer on the common model. */ f_model = gtk_tree_model_filter_new (model, NULL); /* A GncTreeModelOwner is based on a GncTreeModel, which is a * GObject that provides a GtkTreeModel interface. */ g_object_unref(G_OBJECT(model)); /* Set up the view private sort layer on the common model. */ s_model = gtk_tree_model_sort_new_with_model(f_model); g_object_unref(G_OBJECT(f_model)); gnc_tree_view_set_model (view, s_model); g_object_unref(G_OBJECT(s_model)); /* Set default visibilities */ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE); sample_type = gncOwnerTypeToQofIdType (GNC_OWNER_CUSTOMER); sample_currency = gnc_commodity_get_fullname(gnc_default_currency()); priv->name_column = gnc_tree_view_add_text_column(view, _("Owner Name"), GNC_OWNER_TREE_NAME_COL, NULL, "GnuCash Inc.", GNC_TREE_MODEL_OWNER_COL_NAME, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Type"), GNC_OWNER_TREE_TYPE_COL, NULL, sample_type, GNC_TREE_MODEL_OWNER_COL_TYPE, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); priv->id_column = gnc_tree_view_add_text_column(view, _("Owner ID"), GNC_OWNER_TREE_ID_COL, NULL, "1-123-1234", GNC_TREE_MODEL_OWNER_COL_ID, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Currency"), GNC_OWNER_TREE_CURRENCY_COL, NULL, sample_currency, GNC_TREE_MODEL_OWNER_COL_CURRENCY, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Address Name"), GNC_OWNER_TREE_ADDRESS_NAME_COL, NULL, "GnuCash Inc.", GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Address 1"), GNC_OWNER_TREE_ADDRESS_1_COL, NULL, "Free Software Foundation", GNC_TREE_MODEL_OWNER_COL_ADDRESS_1, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Address 2"), GNC_OWNER_TREE_ADDRESS_2_COL, NULL, "51 Franklin Street, Fifth Floor", GNC_TREE_MODEL_OWNER_COL_ADDRESS_2, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Address 3"), GNC_OWNER_TREE_ADDRESS_3_COL, NULL, "Boston, MA 02110-1301", GNC_TREE_MODEL_OWNER_COL_ADDRESS_3, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Address 4"), GNC_OWNER_TREE_ADDRESS_4_COL, NULL, "USA", GNC_TREE_MODEL_OWNER_COL_ADDRESS_4, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Phone"), GNC_OWNER_TREE_PHONE_COL, NULL, "+1-617-542-5942", GNC_TREE_MODEL_OWNER_COL_PHONE, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("Fax"), GNC_OWNER_TREE_FAX_COL, NULL, "+1-617-542-2652", GNC_TREE_MODEL_OWNER_COL_FAX, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_text_column(view, _("E-mail"), GNC_OWNER_TREE_EMAIL_COL, NULL, "*****@*****.**", GNC_TREE_MODEL_OWNER_COL_EMAIL, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_numeric_column(view, _("Balance"), GNC_OWNER_TREE_BALANCE_COL, SAMPLE_OWNER_VALUE, GNC_TREE_MODEL_OWNER_COL_BALANCE, GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_balance_value); priv->balance_report_column = gnc_tree_view_add_numeric_column(view, _("Balance"), GNC_OWNER_TREE_BALANCE_REPORT_COL, SAMPLE_OWNER_VALUE, GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT, GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_balance_value); priv->notes_column = gnc_tree_view_add_text_column(view, _("Notes"), GNC_OWNER_TREE_NOTES_COL, NULL, "Sample owner notes.", GNC_TREE_MODEL_OWNER_COL_NOTES, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_string); gnc_tree_view_add_toggle_column (view, _("Active"), /* Translators: This string has a context prefix; the translation must only contain the part after the | character. */ Q_("Column letter for 'Active'|A"), GNC_OWNER_TREE_ACTIVE_COL, GNC_TREE_MODEL_OWNER_COL_ACTIVE, GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, sort_by_boolean, gnc_tree_view_owner_active_toggled); /* Update column titles to use the currency name. */ gtvo_update_column_names(view); /* By default only the first column is visible. */ gnc_tree_view_configure_columns(view); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model), gnc_tree_view_owner_filter_helper, view, NULL); /* Default the sorting to owner name */ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model), GNC_TREE_MODEL_OWNER_COL_NAME, GTK_SORT_ASCENDING); gtk_widget_show(GTK_WIDGET(view)); LEAVE("%p", view); return GTK_TREE_VIEW(view); }