|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * gnc-tree-view-owner.c -- GtkTreeView implementation to display * 00003 * owners in a GtkTreeView. * 00004 * Copyright (C) 2011 Geert Janssens <geert@kobaltwit.be> * 00005 * * 00006 * This program is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU General Public License as * 00008 * published by the Free Software Foundation; either version 2 of * 00009 * the License, or (at your option) any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License* 00017 * along with this program; if not, contact: * 00018 * * 00019 * Free Software Foundation Voice: +1-617-542-5942 * 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00021 * Boston, MA 02110-1301, USA gnu@gnu.org * 00022 * * 00023 \********************************************************************/ 00024 00025 #include "config.h" 00026 00027 #include <gtk/gtk.h> 00028 #include <glib/gi18n.h> 00029 #include <string.h> 00030 00031 #include "gnc-tree-view.h" 00032 #include "gnc-tree-model-owner.h" 00033 #include "gnc-tree-view-owner.h" 00034 00035 #include "gncOwner.h" 00036 #include "gnc-accounting-period.h" 00037 #include "gnc-commodity.h" 00038 #include "gnc-component-manager.h" 00039 #include "gnc-engine.h" 00040 #include "gnc-glib-utils.h" 00041 #include "gnc-gobject-utils.h" 00042 #include "gnc-hooks.h" 00043 #include "gnc-session.h" 00044 #include "gnc-icons.h" 00045 #include "gnc-ui-balances.h" 00046 #include "dialog-utils.h" 00047 #include "window-main-summarybar.h" 00048 #include "assistant-utils.h" 00049 00050 #define SAMPLE_OWNER_VALUE "$1,000,000.00" 00051 00054 /* This static indicates the debugging module that this .o belongs to. */ 00055 static QofLogModule log_module = GNC_MOD_GUI; 00056 00058 static void gnc_tree_view_owner_class_init (GncTreeViewOwnerClass *klass); 00059 static void gnc_tree_view_owner_init (GncTreeViewOwner *view); 00060 static void gnc_tree_view_owner_finalize (GObject *object); 00061 00062 static void gtvo_update_column_names (GncTreeView *view); 00063 static void gtvo_currency_changed_cb (void); 00064 00065 static gboolean gnc_tree_view_owner_filter_helper (GtkTreeModel *model, 00066 GtkTreeIter *iter, 00067 gpointer data); 00068 00069 static void gtvo_setup_column_renderer_edited_cb(GncTreeViewOwner *owner_view, 00070 GtkTreeViewColumn *column, 00071 GtkCellRenderer *renderer, 00072 GncTreeViewOwnerColumnTextEdited col_edited_cb); 00073 00074 typedef struct GncTreeViewOwnerPrivate 00075 { 00076 OwnerViewInfo ovi; 00077 00078 gnc_tree_view_owner_filter_func filter_fn; 00079 gpointer filter_data; 00080 GtkFunction filter_destroy; 00081 00082 GtkTreeViewColumn *name_column; 00083 GtkTreeViewColumn *id_column; 00084 GtkTreeViewColumn *balance_report_column; 00085 GtkTreeViewColumn *notes_column; 00086 } GncTreeViewOwnerPrivate; 00087 00088 #define GNC_TREE_VIEW_OWNER_GET_PRIVATE(o) \ 00089 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_VIEW_OWNER, GncTreeViewOwnerPrivate)) 00090 00091 00092 /************************************************************/ 00093 /* g_object required functions */ 00094 /************************************************************/ 00095 00096 static GObjectClass *parent_class = NULL; 00097 00098 GType 00099 gnc_tree_view_owner_get_type (void) 00100 { 00101 static GType gnc_tree_view_owner_type = 0; 00102 00103 if (gnc_tree_view_owner_type == 0) 00104 { 00105 static const GTypeInfo our_info = 00106 { 00107 sizeof (GncTreeViewOwnerClass), 00108 NULL, 00109 NULL, 00110 (GClassInitFunc) gnc_tree_view_owner_class_init, 00111 NULL, 00112 NULL, 00113 sizeof (GncTreeViewOwner), 00114 0, 00115 (GInstanceInitFunc) gnc_tree_view_owner_init 00116 }; 00117 00118 gnc_tree_view_owner_type = g_type_register_static ( 00119 GNC_TYPE_TREE_VIEW, GNC_TREE_VIEW_OWNER_NAME, 00120 &our_info, 0); 00121 } 00122 00123 return gnc_tree_view_owner_type; 00124 } 00125 00126 static void 00127 gnc_tree_view_owner_class_init (GncTreeViewOwnerClass *klass) 00128 { 00129 GObjectClass *o_class; 00130 00131 parent_class = g_type_class_peek_parent (klass); 00132 00133 /* GObject signals */ 00134 o_class = G_OBJECT_CLASS (klass); 00135 o_class->finalize = gnc_tree_view_owner_finalize; 00136 00137 g_type_class_add_private(klass, sizeof(GncTreeViewOwnerPrivate)); 00138 00139 gnc_hook_add_dangler(HOOK_CURRENCY_CHANGED, 00140 (GFunc)gtvo_currency_changed_cb, NULL); 00141 } 00142 00143 /********************************************************************\ 00144 * gnc_init_owner_view_info * 00145 * initialize an owner view info structure with default values * 00146 * * 00147 * Args: ovi - structure to initialize * 00148 * Returns: nothing * 00149 \********************************************************************/ 00150 static void 00151 gnc_init_owner_view_info(OwnerViewInfo *ovi) 00152 { 00153 ovi->show_inactive = FALSE; 00154 } 00155 00156 static void 00157 gnc_tree_view_owner_init (GncTreeViewOwner *view) 00158 { 00159 GncTreeViewOwnerPrivate *priv; 00160 00161 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(view); 00162 gnc_init_owner_view_info(&priv->ovi); 00163 } 00164 00165 static void 00166 gnc_tree_view_owner_finalize (GObject *object) 00167 { 00168 GncTreeViewOwner *owner_view; 00169 GncTreeViewOwnerPrivate *priv; 00170 00171 ENTER("view %p", object); 00172 g_return_if_fail (object != NULL); 00173 g_return_if_fail (GNC_IS_TREE_VIEW_OWNER (object)); 00174 00175 owner_view = GNC_TREE_VIEW_OWNER (object); 00176 00177 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(owner_view); 00178 if (priv->filter_destroy) 00179 { 00180 priv->filter_destroy(priv->filter_data); 00181 priv->filter_destroy = NULL; 00182 } 00183 priv->filter_fn = NULL; 00184 00185 if (G_OBJECT_CLASS (parent_class)->finalize) 00186 (* G_OBJECT_CLASS (parent_class)->finalize) (object); 00187 LEAVE(" "); 00188 } 00189 00190 00191 /************************************************************ 00192 * Callbacks * 00193 ************************************************************/ 00194 static void 00195 gnc_tree_view_owner_active_toggled (GtkCellRendererToggle *cell, 00196 const gchar *s_path_str, 00197 gpointer user_data) 00198 { 00199 GncTreeViewOwner *tree_view; 00200 GtkTreePath *s_path; 00201 GncOwner *owner; 00202 gboolean active; 00203 00204 /* Change the requested owner */ 00205 tree_view = user_data; 00206 s_path = gtk_tree_path_new_from_string (s_path_str); 00207 owner = gnc_tree_view_owner_get_owner_from_path (tree_view, s_path); 00208 if (owner) 00209 { 00210 active = !gtk_cell_renderer_toggle_get_active (cell); // hasn't changed yet. 00211 gncOwnerSetActive (owner, active); 00212 } 00213 00214 /* Clean up */ 00215 gtk_tree_path_free (s_path); 00216 } 00217 00218 00219 /************************************************************/ 00220 /* sort functions */ 00221 /************************************************************/ 00222 00223 static GtkTreeModel * 00224 sort_cb_setup_w_iters (GtkTreeModel *f_model, 00225 GtkTreeIter *f_iter_a, 00226 GtkTreeIter *f_iter_b, 00227 GtkTreeIter *iter_a, 00228 GtkTreeIter *iter_b, 00229 const GncOwner **owner_a, 00230 const GncOwner **owner_b) 00231 { 00232 GtkTreeModel *model; 00233 00234 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00235 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model), 00236 iter_a, 00237 f_iter_a); 00238 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model), 00239 iter_b, 00240 f_iter_b); 00241 *owner_a = gnc_tree_model_owner_get_owner (GNC_TREE_MODEL_OWNER(model), iter_a); 00242 *owner_b = gnc_tree_model_owner_get_owner (GNC_TREE_MODEL_OWNER(model), iter_b); 00243 return model; 00244 } 00245 00246 static void 00247 sort_cb_setup (GtkTreeModel *f_model, 00248 GtkTreeIter *f_iter_a, 00249 GtkTreeIter *f_iter_b, 00250 const GncOwner **owner_a, 00251 const GncOwner **owner_b) 00252 { 00253 GtkTreeIter iter_a, iter_b; 00254 00255 sort_cb_setup_w_iters (f_model, f_iter_a, f_iter_b, 00256 &iter_a, &iter_b, owner_a, owner_b); 00257 } 00258 00259 static gint 00260 sort_by_string (GtkTreeModel *f_model, 00261 GtkTreeIter *f_iter1, 00262 GtkTreeIter *f_iter2, 00263 gpointer user_data) 00264 { 00265 GtkTreeModel *model; 00266 GtkTreeIter iter1, iter2; 00267 const GncOwner *owner1, *owner2; 00268 gchar *str1, *str2; 00269 gint column = GPOINTER_TO_INT(user_data); 00270 gint result; 00271 00272 model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2); 00273 00274 /* Get the strings. */ 00275 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &str1, -1); 00276 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &str2, -1); 00277 00278 result = safe_utf8_collate(str1, str2); 00279 g_free(str1); 00280 g_free(str2); 00281 if (result != 0) 00282 return result; 00283 return gncOwnerCompare(owner1, owner2); 00284 } 00285 00286 static gint 00287 sort_by_boolean (GtkTreeModel *f_model, 00288 GtkTreeIter *f_iter1, 00289 GtkTreeIter *f_iter2, 00290 gpointer user_data) 00291 { 00292 GtkTreeModel *model; 00293 GtkTreeIter iter1, iter2; 00294 const GncOwner *owner1, *owner2; 00295 gboolean *bool1, *bool2; 00296 gint column = GPOINTER_TO_INT(user_data); 00297 00298 model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2); 00299 00300 /* Get the booleans. */ 00301 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &bool1, -1); 00302 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &bool2, -1); 00303 00304 if (bool1) 00305 { 00306 if (!bool2) 00307 return 1; /* bool1 > bool2 */ 00308 } 00309 else 00310 { 00311 if (bool2) 00312 return -1; /* bool2 > bool1 */ 00313 } 00314 return gncOwnerCompare(owner1, owner2); 00315 } 00316 00317 static gint 00318 sort_by_xxx_value (GtkTreeModel *f_model, 00319 GtkTreeIter *f_iter_a, 00320 GtkTreeIter *f_iter_b, 00321 gpointer user_data) 00322 { 00323 GncOwner *owner_a, *owner_b; 00324 gnc_numeric balance_a, balance_b; 00325 gint result; 00326 00327 /* Find the owners */ 00328 sort_cb_setup (f_model, f_iter_a, f_iter_b, (const GncOwner**)&owner_a, (const GncOwner**)&owner_b); 00329 00330 balance_a = gnc_ui_owner_get_balance_full(owner_a, NULL, NULL); 00331 balance_b = gnc_ui_owner_get_balance_full(owner_b, NULL, NULL); 00332 00333 result = gnc_numeric_compare(balance_a, balance_b); 00334 if (result != 0) 00335 return result; 00336 return gncOwnerCompare(owner_a, owner_b); 00337 } 00338 00339 static gint 00340 sort_by_balance_value (GtkTreeModel *f_model, 00341 GtkTreeIter *f_iter_a, 00342 GtkTreeIter *f_iter_b, 00343 gpointer user_data) 00344 { 00345 return sort_by_xxx_value (f_model, f_iter_a, f_iter_b, user_data); 00346 } 00347 00348 00349 /************************************************************/ 00350 /* New View Creation */ 00351 /************************************************************/ 00352 00353 /* 00354 * Create a new owner tree view for one type of owners. 00355 * This view will be based on a model that is common to all views of 00356 * the same set of books, but will have its own private filter on that 00357 * model. 00358 */ 00359 GtkTreeView * 00360 gnc_tree_view_owner_new (GncOwnerType owner_type) 00361 { 00362 GncTreeView *view; 00363 GtkTreeModel *model, *f_model, *s_model; 00364 const gchar *sample_type, *sample_currency; 00365 GncTreeViewOwnerPrivate *priv; 00366 GtkTreeViewColumn *tax_info_column; 00367 GtkCellRenderer *renderer; 00368 00369 ENTER(" "); 00370 /* Create our view */ 00371 view = g_object_new (GNC_TYPE_TREE_VIEW_OWNER, 00372 "name", "owner_tree", NULL); 00373 00374 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(GNC_TREE_VIEW_OWNER (view)); 00375 00376 /* Create/get a pointer to the existing model for this set of books. */ 00377 model = gnc_tree_model_owner_new (owner_type); 00378 00379 /* Set up the view private filter layer on the common model. */ 00380 f_model = gtk_tree_model_filter_new (model, NULL); 00381 /* A GncTreeModelOwner is based on a GncTreeModel, which is a 00382 * GObject that provides a GtkTreeModel interface. */ 00383 g_object_unref(G_OBJECT(model)); 00384 00385 /* Set up the view private sort layer on the common model. */ 00386 s_model = gtk_tree_model_sort_new_with_model(f_model); 00387 g_object_unref(G_OBJECT(f_model)); 00388 gnc_tree_view_set_model (view, s_model); 00389 g_object_unref(G_OBJECT(s_model)); 00390 00391 /* Set default visibilities */ 00392 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE); 00393 00394 sample_type = gncOwnerTypeToQofIdType (GNC_OWNER_CUSTOMER); 00395 sample_currency = gnc_commodity_get_fullname(gnc_default_currency()); 00396 00397 priv->name_column 00398 = gnc_tree_view_add_text_column(view, _("Owner Name"), GNC_OWNER_TREE_NAME_COL, 00399 NULL, "GnuCash Inc.", 00400 GNC_TREE_MODEL_OWNER_COL_NAME, 00401 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00402 sort_by_string); 00403 gnc_tree_view_add_text_column(view, _("Type"), GNC_OWNER_TREE_TYPE_COL, 00404 NULL, sample_type, 00405 GNC_TREE_MODEL_OWNER_COL_TYPE, 00406 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00407 sort_by_string); 00408 priv->id_column 00409 = gnc_tree_view_add_text_column(view, _("Owner ID"), GNC_OWNER_TREE_ID_COL, 00410 NULL, "1-123-1234", 00411 GNC_TREE_MODEL_OWNER_COL_ID, 00412 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00413 sort_by_string); 00414 gnc_tree_view_add_text_column(view, _("Currency"), GNC_OWNER_TREE_CURRENCY_COL, 00415 NULL, sample_currency, 00416 GNC_TREE_MODEL_OWNER_COL_CURRENCY, 00417 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00418 sort_by_string); 00419 gnc_tree_view_add_text_column(view, _("Address Name"), GNC_OWNER_TREE_ADDRESS_NAME_COL, 00420 NULL, "GnuCash Inc.", 00421 GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME, 00422 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00423 sort_by_string); 00424 gnc_tree_view_add_text_column(view, _("Address 1"), GNC_OWNER_TREE_ADDRESS_1_COL, 00425 NULL, "Free Software Foundation", 00426 GNC_TREE_MODEL_OWNER_COL_ADDRESS_1, 00427 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00428 sort_by_string); 00429 gnc_tree_view_add_text_column(view, _("Address 2"), GNC_OWNER_TREE_ADDRESS_2_COL, 00430 NULL, "51 Franklin Street, Fifth Floor", 00431 GNC_TREE_MODEL_OWNER_COL_ADDRESS_2, 00432 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00433 sort_by_string); 00434 gnc_tree_view_add_text_column(view, _("Address 3"), GNC_OWNER_TREE_ADDRESS_3_COL, 00435 NULL, "Boston, MA 02110-1301", 00436 GNC_TREE_MODEL_OWNER_COL_ADDRESS_3, 00437 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00438 sort_by_string); 00439 gnc_tree_view_add_text_column(view, _("Address 4"), GNC_OWNER_TREE_ADDRESS_4_COL, 00440 NULL, "USA", 00441 GNC_TREE_MODEL_OWNER_COL_ADDRESS_4, 00442 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00443 sort_by_string); 00444 gnc_tree_view_add_text_column(view, _("Phone"), GNC_OWNER_TREE_PHONE_COL, 00445 NULL, "+1-617-542-5942", 00446 GNC_TREE_MODEL_OWNER_COL_PHONE, 00447 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00448 sort_by_string); 00449 gnc_tree_view_add_text_column(view, _("Fax"), GNC_OWNER_TREE_FAX_COL, 00450 NULL, "+1-617-542-2652", 00451 GNC_TREE_MODEL_OWNER_COL_FAX, 00452 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00453 sort_by_string); 00454 gnc_tree_view_add_text_column(view, _("E-mail"), GNC_OWNER_TREE_EMAIL_COL, 00455 NULL, "gnu@gnu.org", 00456 GNC_TREE_MODEL_OWNER_COL_EMAIL, 00457 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00458 sort_by_string); 00459 gnc_tree_view_add_numeric_column(view, _("Balance"), GNC_OWNER_TREE_BALANCE_COL, 00460 SAMPLE_OWNER_VALUE, 00461 GNC_TREE_MODEL_OWNER_COL_BALANCE, 00462 GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE, 00463 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00464 sort_by_balance_value); 00465 00466 priv->balance_report_column 00467 = gnc_tree_view_add_numeric_column(view, _("Balance"), GNC_OWNER_TREE_BALANCE_REPORT_COL, 00468 SAMPLE_OWNER_VALUE, 00469 GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT, 00470 GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE, 00471 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00472 sort_by_balance_value); 00473 00474 priv->notes_column 00475 = gnc_tree_view_add_text_column(view, _("Notes"), GNC_OWNER_TREE_NOTES_COL, NULL, 00476 "Sample owner notes.", 00477 GNC_TREE_MODEL_OWNER_COL_NOTES, 00478 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00479 sort_by_string); 00480 gnc_tree_view_add_toggle_column (view, _("Active"), 00481 /* Translators: This string has a context prefix; the translation 00482 must only contain the part after the | character. */ 00483 Q_("Column letter for 'Active'|A"), 00484 GNC_OWNER_TREE_ACTIVE_COL, 00485 GNC_TREE_MODEL_OWNER_COL_ACTIVE, 00486 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 00487 sort_by_boolean, 00488 gnc_tree_view_owner_active_toggled); 00489 00490 /* Update column titles to use the currency name. */ 00491 gtvo_update_column_names(view); 00492 00493 /* By default only the first column is visible. */ 00494 gnc_tree_view_configure_columns(view); 00495 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model), 00496 gnc_tree_view_owner_filter_helper, 00497 view, 00498 NULL); 00499 00500 /* Default the sorting to owner name */ 00501 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model), 00502 GNC_TREE_MODEL_OWNER_COL_NAME, 00503 GTK_SORT_ASCENDING); 00504 00505 gtk_widget_show(GTK_WIDGET(view)); 00506 LEAVE("%p", view); 00507 return GTK_TREE_VIEW(view); 00508 } 00509 00510 /************************************************************/ 00511 /* Auxiliary Functions */ 00512 /************************************************************/ 00513 00514 #define debug_path(fn, path) { \ 00515 gchar *path_string = gtk_tree_path_to_string(path); \ 00516 fn("tree path %s", path_string); \ 00517 g_free(path_string); \ 00518 } 00519 00520 static GtkTreePath * 00521 gnc_tree_view_owner_get_path_from_owner (GncTreeViewOwner *view, 00522 GncOwner *owner) 00523 { 00524 GtkTreeModel *model, *f_model, *s_model; 00525 GtkTreePath *path, *f_path, *s_path; 00526 00527 ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner)); 00528 00529 if (owner == NULL) 00530 { 00531 LEAVE("no owner"); 00532 return NULL; 00533 } 00534 00535 /* Reach down to the real model and get a path for this owner */ 00536 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); 00537 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00538 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00539 path = gnc_tree_model_owner_get_path_from_owner (GNC_TREE_MODEL_OWNER(model), owner); 00540 if (path == NULL) 00541 { 00542 LEAVE("no path"); 00543 return NULL; 00544 } 00545 00546 /* convert back to a filtered path */ 00547 f_path = gtk_tree_model_filter_convert_child_path_to_path (GTK_TREE_MODEL_FILTER (f_model), path); 00548 gtk_tree_path_free(path); 00549 if (!f_path) 00550 { 00551 LEAVE("no filter path"); 00552 return NULL; 00553 } 00554 00555 /* convert back to a sorted path */ 00556 s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model), f_path); 00557 gtk_tree_path_free(f_path); 00558 debug_path(LEAVE, s_path); 00559 return s_path; 00560 } 00561 00562 static gboolean 00563 gnc_tree_view_owner_get_iter_from_owner (GncTreeViewOwner *view, 00564 GncOwner *owner, 00565 GtkTreeIter *s_iter) 00566 { 00567 GtkTreeModel *model, *f_model, *s_model; 00568 GtkTreeIter iter, f_iter; 00569 00570 g_return_val_if_fail(GNC_IS_TREE_VIEW_OWNER(view), FALSE); 00571 g_return_val_if_fail(owner != NULL, FALSE); 00572 g_return_val_if_fail(s_iter != NULL, FALSE); 00573 00574 ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner)); 00575 00576 /* Reach down to the real model and get an iter for this owner */ 00577 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); 00578 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00579 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00580 if (!gnc_tree_model_owner_get_iter_from_owner ( 00581 GNC_TREE_MODEL_OWNER(model), owner, &iter)) 00582 { 00583 LEAVE("model_get_iter_from_owner failed"); 00584 return FALSE; 00585 } 00586 00587 /* convert back to a sort iter */ 00588 gtk_tree_model_filter_convert_child_iter_to_iter ( 00589 GTK_TREE_MODEL_FILTER(f_model), &f_iter, &iter); 00590 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model), 00591 s_iter, &f_iter); 00592 LEAVE(" "); 00593 return TRUE; 00594 } 00595 00596 /************************************************************/ 00597 /* Owner Tree View Filter Functions */ 00598 /************************************************************/ 00599 00600 static gboolean 00601 gnc_tree_view_owner_filter_helper (GtkTreeModel *model, 00602 GtkTreeIter *iter, 00603 gpointer data) 00604 { 00605 GncOwner *owner; 00606 GncTreeViewOwner *view = data; 00607 GncTreeViewOwnerPrivate *priv; 00608 00609 g_return_val_if_fail (GNC_IS_TREE_MODEL_OWNER (model), FALSE); 00610 g_return_val_if_fail (iter != NULL, FALSE); 00611 00612 owner = gnc_tree_model_owner_get_owner ( 00613 GNC_TREE_MODEL_OWNER(model), iter); 00614 00615 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(view); 00616 if (priv->filter_fn) 00617 return priv->filter_fn(owner, priv->filter_data); 00618 else return TRUE; 00619 } 00620 00621 /* 00622 * Set an GtkTreeModel visible filter on this owner. This filter will be 00623 * called for each owner that the tree is about to show, and the 00624 * owner will be passed to the callback function. 00625 * 00626 * Use NULL as func to remove filter. 00627 */ 00628 void 00629 gnc_tree_view_owner_set_filter (GncTreeViewOwner *view, 00630 gnc_tree_view_owner_filter_func func, 00631 gpointer data, 00632 GtkFunction destroy) 00633 { 00634 GncTreeViewOwnerPrivate *priv; 00635 00636 ENTER("view %p, filter func %p, data %p, destroy %p", 00637 view, func, data, destroy); 00638 00639 g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view)); 00640 00641 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(view); 00642 if (priv->filter_destroy) 00643 { 00644 priv->filter_destroy(priv->filter_data); 00645 } 00646 priv->filter_destroy = destroy; 00647 priv->filter_data = data; 00648 priv->filter_fn = func; 00649 00650 gnc_tree_view_owner_refilter(view); 00651 LEAVE(" "); 00652 } 00653 00654 /* 00655 * Forces the entire owner tree to be re-evaluated for visibility. 00656 */ 00657 void 00658 gnc_tree_view_owner_refilter (GncTreeViewOwner *view) 00659 { 00660 GtkTreeModel *f_model, *s_model; 00661 00662 g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view)); 00663 00664 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); 00665 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00666 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model)); 00667 } 00668 00669 /************************************************************/ 00670 /* Owner Tree View Get/Set Functions */ 00671 /************************************************************/ 00672 00673 /* 00674 * Retrieve the selected owner from an owner tree view. The 00675 * owner tree must be in single selection mode. 00676 */ 00677 GncOwner * 00678 gnc_tree_view_owner_get_owner_from_path (GncTreeViewOwner *view, 00679 GtkTreePath *s_path) 00680 { 00681 GtkTreeModel *model, *f_model, *s_model; 00682 GtkTreePath *path, *f_path; 00683 GtkTreeIter iter; 00684 GncOwner *owner; 00685 00686 ENTER("view %p", view); 00687 g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL); 00688 g_return_val_if_fail (s_path != NULL, NULL); 00689 00690 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); 00691 f_path = gtk_tree_model_sort_convert_path_to_child_path ( 00692 GTK_TREE_MODEL_SORT (s_model), s_path); 00693 if (!f_path) 00694 { 00695 LEAVE("no filter path"); 00696 return NULL; 00697 } 00698 00699 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00700 path = gtk_tree_model_filter_convert_path_to_child_path ( 00701 GTK_TREE_MODEL_FILTER (f_model), f_path); 00702 gtk_tree_path_free(f_path); 00703 if (!path) 00704 { 00705 LEAVE("no path"); 00706 return NULL; 00707 } 00708 00709 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00710 if (!gtk_tree_model_get_iter (model, &iter, path)) 00711 { 00712 LEAVE("no iter"); 00713 return NULL; 00714 } 00715 00716 owner = iter.user_data; 00717 gtk_tree_path_free(path); 00718 LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner)); 00719 return owner; 00720 } 00721 00722 00723 GncOwner * 00724 gnc_tree_view_owner_get_owner_from_iter (GtkTreeModel *s_model, 00725 GtkTreeIter *s_iter) 00726 { 00727 GtkTreeModel *model, *f_model; 00728 GtkTreeIter iter, f_iter; 00729 GncOwner *owner; 00730 00731 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT(s_model), NULL); 00732 g_return_val_if_fail (s_iter != NULL, NULL); 00733 00734 ENTER("model %p, iter %p", s_model, s_iter); 00735 00736 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(s_model), 00737 &f_iter, 00738 s_iter); 00739 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00740 gtk_tree_model_filter_convert_iter_to_child_iter ( 00741 GTK_TREE_MODEL_FILTER(f_model), &iter, &f_iter); 00742 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00743 owner = gnc_tree_model_owner_get_owner ( 00744 GNC_TREE_MODEL_OWNER(model), &iter); 00745 LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner)); 00746 return owner; 00747 } 00748 00749 00750 /* 00751 * Retrieve the selected owner from an owner tree view. The 00752 * owner tree must be in single selection mode. 00753 */ 00754 GncOwner * 00755 gnc_tree_view_owner_get_selected_owner (GncTreeViewOwner *view) 00756 { 00757 GtkTreeSelection *selection; 00758 GtkTreeModel *f_model, *s_model; 00759 GtkTreeIter iter, f_iter, s_iter; 00760 GncOwner *owner; 00761 GtkSelectionMode mode; 00762 00763 ENTER("view %p", view); 00764 g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL); 00765 00766 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view)); 00767 mode = gtk_tree_selection_get_mode(selection); 00768 if ((mode != GTK_SELECTION_SINGLE) && (mode != GTK_SELECTION_BROWSE)) 00769 { 00770 return NULL; 00771 } 00772 if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter)) 00773 { 00774 LEAVE("no owner, get_selected failed"); 00775 return FALSE; 00776 } 00777 00778 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), 00779 &f_iter, &s_iter); 00780 00781 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00782 gtk_tree_model_filter_convert_iter_to_child_iter ( 00783 GTK_TREE_MODEL_FILTER (f_model), &iter, &f_iter); 00784 00785 owner = iter.user_data; 00786 LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner)); 00787 return owner; 00788 } 00789 00790 /* 00791 * Selects a single owner in the owner tree view. The owner 00792 * tree must be in single selection mode. 00793 */ 00794 void 00795 gnc_tree_view_owner_set_selected_owner (GncTreeViewOwner *view, 00796 GncOwner *owner) 00797 { 00798 GtkTreeModel *model, *f_model, *s_model; 00799 GtkTreePath *path, *f_path, *s_path, *parent_path; 00800 GtkTreeSelection *selection; 00801 00802 ENTER("view %p, owner %p (%s)", view, 00803 owner, gncOwnerGetName (owner)); 00804 g_return_if_fail (GNC_IS_TREE_VIEW_OWNER (view)); 00805 00806 /* Clear any existing selection. */ 00807 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); 00808 gtk_tree_selection_unselect_all (selection); 00809 00810 if (owner == NULL) 00811 return; 00812 00813 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); 00814 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00815 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); 00816 00817 path = gnc_tree_model_owner_get_path_from_owner ( 00818 GNC_TREE_MODEL_OWNER(model), owner); 00819 if (path == NULL) 00820 { 00821 LEAVE("no path"); 00822 return; 00823 } 00824 debug_path(DEBUG, path); 00825 00826 f_path = gtk_tree_model_filter_convert_child_path_to_path ( 00827 GTK_TREE_MODEL_FILTER (f_model), path); 00828 gtk_tree_path_free(path); 00829 if (f_path == NULL) 00830 { 00831 LEAVE("no filter path"); 00832 return; 00833 } 00834 debug_path(DEBUG, f_path); 00835 00836 s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model), 00837 f_path); 00838 gtk_tree_path_free(f_path); 00839 if (s_path == NULL) 00840 { 00841 LEAVE("no sort path"); 00842 return; 00843 } 00844 00845 gtk_tree_selection_select_path (selection, s_path); 00846 00847 /* give gtk+ a chance to resize the tree view first by handling pending 00848 * configure events */ 00849 while (gtk_events_pending ()) 00850 gtk_main_iteration (); 00851 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(view), s_path, NULL, FALSE, 0.0, 0.0); 00852 debug_path(LEAVE, s_path); 00853 gtk_tree_path_free(s_path); 00854 } 00855 00856 /* Information re selection process */ 00857 typedef struct 00858 { 00859 GList* return_list; 00860 GncTreeViewOwnerPrivate* priv; 00861 } GncTreeViewSelectionInfo; 00862 00863 /* 00864 * This helper function is called once for each row in the tree view 00865 * that is currently selected. Its task is to append the corresponding 00866 * owner to the end of a glist. 00867 */ 00868 static void 00869 get_selected_owners_helper (GtkTreeModel *s_model, 00870 GtkTreePath *s_path, 00871 GtkTreeIter *s_iter, 00872 gpointer data) 00873 { 00874 GncTreeViewSelectionInfo *gtvsi = data; 00875 GtkTreeModel *f_model; 00876 GtkTreeIter iter, f_iter; 00877 GncOwner *owner; 00878 00879 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), 00880 &f_iter, s_iter); 00881 00882 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); 00883 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model), 00884 &iter, &f_iter); 00885 owner = iter.user_data; 00886 00887 /* Only selected if it passes the filter */ 00888 if (gtvsi->priv->filter_fn == NULL || gtvsi->priv->filter_fn(owner, gtvsi->priv->filter_data)) 00889 { 00890 gtvsi->return_list = g_list_append(gtvsi->return_list, owner); 00891 } 00892 } 00893 00894 /************************************************************/ 00895 /* Owner Tree View Add Column Functions */ 00896 /************************************************************/ 00897 00898 static void 00899 gtvo_update_column_name (GtkTreeViewColumn *column, 00900 const gchar *fmt, 00901 const gchar *mnemonic) 00902 { 00903 gchar *name; 00904 00905 g_return_if_fail(column); 00906 00907 name = g_strdup_printf(fmt, mnemonic); 00908 gtk_tree_view_column_set_title(column, name); 00909 g_free(name); 00910 } 00911 00912 00913 static void 00914 gtvo_update_column_names (GncTreeView *view) 00915 { 00916 GncTreeViewOwnerPrivate *priv; 00917 const gchar *mnemonic; 00918 00919 priv = GNC_TREE_VIEW_OWNER_GET_PRIVATE(view); 00920 mnemonic = gnc_commodity_get_mnemonic(gnc_default_report_currency()); 00921 00922 gtvo_update_column_name(priv->balance_report_column, 00923 /* Translators: %s is a currency mnemonic.*/ 00924 _("Balance (%s)"), mnemonic); 00925 gnc_tree_view_set_show_column_menu(view, FALSE); 00926 gnc_tree_view_set_show_column_menu(view, TRUE); 00927 } 00928 00929 00930 static void 00931 gtvo_currency_changed_cb (void) 00932 { 00933 const GList *views, *ptr; 00934 00935 views = gnc_gobject_tracking_get_list (GNC_TREE_VIEW_OWNER_NAME); 00936 for (ptr = views; ptr; ptr = g_list_next(ptr)) 00937 { 00938 gtvo_update_column_names (ptr->data); 00939 } 00940 } 00941 /* This function implements a custom mapping between an owner's KVP 00942 * and the cell renderer's 'text' property. */ 00943 static void 00944 owner_cell_kvp_data_func (GtkTreeViewColumn *tree_column, 00945 GtkCellRenderer *cell, 00946 GtkTreeModel *s_model, 00947 GtkTreeIter *s_iter, 00948 gpointer key) 00949 { 00950 GncOwner *owner; 00951 kvp_frame * frame; 00952 00953 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model)); 00954 owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter); 00955 frame = gncOwnerGetSlots(owner); 00956 00957 g_object_set (G_OBJECT (cell), 00958 "text", kvp_frame_get_string(frame, (gchar *)key), 00959 "xalign", 0.0, 00960 NULL); 00961 00962 } 00963 00964 static void col_edited_helper(GtkCellRendererText *cell, gchar *path_string, 00965 gchar *new_text, gpointer _s_model) 00966 { 00967 GncOwner *owner; 00968 GtkTreeModel *s_model; 00969 GtkTreeIter s_iter; 00970 GncTreeViewOwnerColumnTextEdited col_edited_cb; 00971 GtkTreeViewColumn *col; 00972 00973 col_edited_cb = g_object_get_data(G_OBJECT(cell), 00974 "column_edited_callback"); 00975 col = GTK_TREE_VIEW_COLUMN(g_object_get_data(G_OBJECT(cell), 00976 "column_view")); 00977 s_model = GTK_TREE_MODEL(_s_model); 00978 00979 if (!gtk_tree_model_get_iter_from_string(s_model, &s_iter, path_string)) 00980 return; 00981 00982 owner = gnc_tree_view_owner_get_owner_from_iter(s_model, &s_iter); 00983 col_edited_cb(owner, col, new_text); 00984 } 00985 00986 static void col_source_helper(GtkTreeViewColumn *col, GtkCellRenderer *cell, 00987 GtkTreeModel *s_model, GtkTreeIter *s_iter, 00988 gpointer _col_source_cb) 00989 { 00990 GncOwner *owner; 00991 gchar *text; 00992 GncTreeViewOwnerColumnSource col_source_cb; 00993 00994 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model)); 00995 col_source_cb = (GncTreeViewOwnerColumnSource) _col_source_cb; 00996 owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter); 00997 text = col_source_cb(owner, col, cell); 00998 g_object_set (G_OBJECT (cell), "text", text, "xalign", 1.0, NULL); 00999 g_free(text); 01000 } 01001 01006 void 01007 gtvo_setup_column_renderer_edited_cb(GncTreeViewOwner *owner_view, 01008 GtkTreeViewColumn *column, 01009 GtkCellRenderer *renderer, 01010 GncTreeViewOwnerColumnTextEdited col_edited_cb) 01011 { 01012 GtkTreeModel *s_model; 01013 01014 if (col_edited_cb == NULL) 01015 { 01016 g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL); 01017 g_object_set_data(G_OBJECT(renderer), "column_edited_callback", col_edited_cb); 01018 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view)); 01019 g_signal_handlers_disconnect_by_func(G_OBJECT(renderer), col_edited_cb, s_model); 01020 g_object_set_data(G_OBJECT(renderer), "column_view", column); 01021 } 01022 else 01023 { 01024 g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); 01025 g_object_set_data(G_OBJECT(renderer), "column_edited_callback", 01026 col_edited_cb); 01027 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view)); 01028 g_signal_connect(G_OBJECT(renderer), "edited", 01029 (GCallback) col_edited_helper, s_model); 01030 g_object_set_data(G_OBJECT(renderer), "column_view", column); 01031 } 01032 } 01033 01034 /* BEGIN FILTER FUNCTIONS */ 01035 #define FILTER_TREE_VIEW "types_tree_view" 01036 01048 gboolean 01049 gnc_plugin_page_owner_tree_filter_owners (GncOwner *owner, 01050 gpointer user_data) 01051 { 01052 OwnerFilterDialog *fd = user_data; 01053 gnc_numeric total; 01054 01055 ENTER("owner %p:%s", owner, gncOwnerGetName(owner)); 01056 01057 if (!fd->show_inactive && !gncOwnerGetActive (owner)) 01058 { 01059 LEAVE(" hide: inactive"); 01060 return FALSE; 01061 } 01062 01063 if (!fd->show_zero_total) 01064 { 01065 /* FIXME I'm not aware of any functions to get an owner's "balance" yet. 01066 * This should be implemented before this function does anything useful. 01067 * The code below is copied from the tree-view-account source to serve 01068 * as an example. 01069 total = gncOwnerGetBalanceInCurrency (owner, NULL, TRUE); 01070 */ 01071 total = gnc_numeric_zero(); 01072 if (gnc_numeric_zero_p(total)) 01073 { 01074 LEAVE(" hide: zero balance"); 01075 return FALSE; 01076 } 01077 } 01078 01079 return TRUE; 01080 } 01081 01088 void 01089 gppot_filter_show_inactive_toggled_cb (GtkToggleButton *button, 01090 OwnerFilterDialog *fd) 01091 { 01092 g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button)); 01093 01094 ENTER("button %p", button); 01095 fd->show_inactive = gtk_toggle_button_get_active(button); 01096 gnc_tree_view_owner_refilter(fd->tree_view); 01097 LEAVE("show_inactive %d", fd->show_inactive); 01098 } 01099 01106 void 01107 gppot_filter_show_zero_toggled_cb (GtkToggleButton *button, 01108 OwnerFilterDialog *fd) 01109 { 01110 g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button)); 01111 01112 ENTER("button %p", button); 01113 fd->show_zero_total = gtk_toggle_button_get_active(button); 01114 gnc_tree_view_owner_refilter(fd->tree_view); 01115 LEAVE("show_zero %d", fd->show_zero_total); 01116 } 01117 01127 void 01128 gppot_filter_response_cb (GtkWidget *dialog, 01129 gint response, 01130 OwnerFilterDialog *fd) 01131 { 01132 gpointer gptemp; 01133 01134 g_return_if_fail(GTK_IS_DIALOG(dialog)); 01135 01136 ENTER("dialog %p, response %d", dialog, response); 01137 01138 if (response != GTK_RESPONSE_OK) 01139 { 01140 fd->show_inactive = fd->original_show_inactive; 01141 fd->show_zero_total = fd->original_show_zero_total; 01142 gnc_tree_view_owner_refilter(fd->tree_view); 01143 } 01144 01145 /* Clean up and delete dialog */ 01146 gptemp = (gpointer *)fd->dialog; 01147 g_atomic_pointer_compare_and_exchange(&gptemp, 01148 dialog, NULL); 01149 fd->dialog = gptemp; 01150 gtk_widget_destroy(dialog); 01151 LEAVE(""); 01152 } 01153 01154 void 01155 owner_filter_dialog_create(OwnerFilterDialog *fd, GncPluginPage *page) 01156 { 01157 GtkWidget *dialog, *button; 01158 GtkBuilder *builder; 01159 gchar *title; 01160 01161 ENTER("(fd %p, page %p)", fd, page); 01162 01163 if (fd->dialog) 01164 { 01165 gtk_window_present(GTK_WINDOW(fd->dialog)); 01166 LEAVE("existing dialog"); 01167 return; 01168 } 01169 01170 /* Create the dialog */ 01171 builder = gtk_builder_new(); 01172 gnc_builder_add_from_file (builder, "gnc-tree-view-owner.glade", "Filter By"); 01173 dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Filter By")); 01174 fd->dialog = dialog; 01175 gtk_window_set_transient_for(GTK_WINDOW(dialog), 01176 GTK_WINDOW(GNC_PLUGIN_PAGE(page)->window)); 01177 /* Translators: The %s is the name of the plugin page */ 01178 title = g_strdup_printf(_("Filter %s by..."), 01179 gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page))); 01180 gtk_window_set_title(GTK_WINDOW(dialog), title); 01181 g_free(title); 01182 01183 /* Remember current state */ 01184 fd->original_show_inactive = fd->show_inactive; 01185 fd->original_show_zero_total = fd->show_zero_total; 01186 01187 /* Update the dialog widgets for the current state */ 01188 button = GTK_WIDGET(gtk_builder_get_object (builder, "show_inactive")); 01189 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), 01190 fd->show_inactive); 01191 button = GTK_WIDGET(gtk_builder_get_object (builder, "show_zero")); 01192 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), 01193 fd->show_zero_total); 01194 01195 /* Wire up the rest of the callbacks */ 01196 gtk_builder_connect_signals (builder, fd); 01197 g_object_unref(G_OBJECT(builder)); 01198 01199 /* Show it */ 01200 gtk_widget_show_all (dialog); 01201 LEAVE(" "); 01202 } 01203 01204 #define OWNER_SELECTED_LABEL "SelectedOwner" 01205 #define SHOW_INACTIVE_LABEL "ShowInactive" 01206 #define SHOW_ZERO_LABEL "ShowZeroTotal" 01207 01208 typedef struct foo 01209 { 01210 GKeyFile *key_file; 01211 const gchar *group_name; 01212 } bar_t; 01213 01224 static void 01225 tree_save_selected_row (GncTreeViewOwner *view, 01226 gpointer user_data) 01227 { 01228 GncOwner *owner; 01229 GncOwnerType owner_type; 01230 bar_t *bar = user_data; 01231 const gchar *owner_name; 01232 01233 owner = gnc_tree_view_owner_get_selected_owner(view); 01234 if (owner == NULL) 01235 return; 01236 01237 owner_name = gncOwnerGetName (owner); 01238 if (owner_name == NULL) 01239 return; 01240 01241 g_key_file_set_string(bar->key_file, bar->group_name, OWNER_SELECTED_LABEL, 01242 owner_name); 01243 } 01244 01245 void 01246 gnc_tree_view_owner_save(GncTreeViewOwner *view, 01247 OwnerFilterDialog *fd, 01248 GKeyFile *key_file, const gchar *group_name) 01249 { 01250 bar_t bar; 01251 01252 g_return_if_fail (key_file != NULL); 01253 g_return_if_fail (group_name != NULL); 01254 01255 ENTER("view %p, key_file %p, group_name %s", view, key_file, 01256 group_name); 01257 01258 g_key_file_set_boolean(key_file, group_name, SHOW_INACTIVE_LABEL, 01259 fd->show_inactive); 01260 g_key_file_set_boolean(key_file, group_name, SHOW_ZERO_LABEL, 01261 fd->show_zero_total); 01262 01263 bar.key_file = key_file; 01264 bar.group_name = group_name; 01265 tree_save_selected_row(view, &bar); 01266 LEAVE(" "); 01267 01268 } 01269 01277 static void 01278 tree_restore_selected_row (GncTreeViewOwner *view, 01279 GncOwnerType owner_type, 01280 const gchar *owner_guid_str) 01281 { 01282 GncOwner *owner = gncOwnerNew(); 01283 QofBook *book; 01284 GncGUID owner_guid; 01285 01286 book = qof_session_get_book (gnc_get_current_session()); 01287 if (string_to_guid (owner_guid_str, &owner_guid)) 01288 if (gncOwnerGetOwnerFromTypeGuid (book, owner, gncOwnerTypeToQofIdType(owner_type), &owner_guid)) 01289 gnc_tree_view_owner_set_selected_owner(view, owner); 01290 } 01291 01292 void 01293 gnc_tree_view_owner_restore(GncTreeViewOwner *view, 01294 OwnerFilterDialog *fd, 01295 GKeyFile *key_file, const gchar *group_name, 01296 GncOwnerType owner_type) 01297 { 01298 GError *error = NULL; 01299 gchar *key, *value; 01300 gint i, count; 01301 gboolean show; 01302 01303 /* Filter information. Ignore missing keys. */ 01304 show = g_key_file_get_boolean(key_file, group_name, SHOW_INACTIVE_LABEL, &error); 01305 if (error) 01306 { 01307 g_warning("error reading group %s key %s: %s", 01308 group_name, SHOW_INACTIVE_LABEL, error->message); 01309 g_error_free(error); 01310 error = NULL; 01311 show = TRUE; 01312 } 01313 fd->show_inactive = show; 01314 01315 show = g_key_file_get_boolean(key_file, group_name, SHOW_ZERO_LABEL, &error); 01316 if (error) 01317 { 01318 g_warning("error reading group %s key %s: %s", 01319 group_name, SHOW_ZERO_LABEL, error->message); 01320 g_error_free(error); 01321 error = NULL; 01322 show = TRUE; 01323 } 01324 fd->show_zero_total = show; 01325 01326 /* Selected owner (if any) */ 01327 value = g_key_file_get_string(key_file, group_name, OWNER_SELECTED_LABEL, NULL); 01328 if (value) 01329 { 01330 tree_restore_selected_row(view, owner_type, value); 01331 g_free(value); 01332 } 01333 01334 /* Update tree view for any changes */ 01335 gnc_tree_view_owner_refilter(view); 01336 } 01337 01338 static void 01339 gtvo_set_column_editor(GncTreeViewOwner *view, 01340 GtkTreeViewColumn *column, 01341 GncTreeViewOwnerColumnTextEdited edited_cb) 01342 { 01343 GList *renderers_orig, *renderers; 01344 GtkCellRenderer *renderer; 01345 01346 // look for the first text-renderer; on the 0th column of the owner tree, 01347 // there are two renderers: pixbuf and text. So find the text one. 01348 for (renderers_orig = renderers = gtk_tree_view_column_get_cell_renderers(column); 01349 renderers && !GTK_IS_CELL_RENDERER_TEXT(renderers->data); 01350 renderers = renderers->next); 01351 renderer = GTK_CELL_RENDERER(renderers->data); 01352 g_list_free(renderers_orig); 01353 g_return_if_fail(renderer != NULL); 01354 gtvo_setup_column_renderer_edited_cb(GNC_TREE_VIEW_OWNER(view), column, renderer, edited_cb); 01355 }
1.7.4