00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026
00027 #include <gnome.h>
00028 #include <math.h>
00029 #include <string.h>
00030
00031 #include "Transaction.h"
00032 #include "dialog-account.h"
00033 #include "dialog-commodity.h"
00034 #include "dialog-utils.h"
00035 #include "global-options.h"
00036 #include "gnc-amount-edit.h"
00037 #include "gnc-general-select.h"
00038 #include "gnc-commodity.h"
00039 #include "gnc-commodity-edit.h"
00040 #include "gnc-component-manager.h"
00041 #include "gnc-engine-util.h"
00042 #include "gnc-engine.h"
00043 #include "gnc-gui-query.h"
00044 #include "gnc-session.h"
00045 #include "gnc-tree-view-account.h"
00046 #include "gnc-ui.h"
00047 #include "gnc-ui-util.h"
00048 #include "messages.h"
00049
00050
00051 #define DIALOG_NEW_ACCOUNT_CM_CLASS "dialog-new-account"
00052 #define DIALOG_EDIT_ACCOUNT_CM_CLASS "dialog-edit-account"
00053 #define GCONF_SECTION "dialogs/account"
00054
00055 typedef enum
00056 {
00057 NEW_ACCOUNT,
00058 EDIT_ACCOUNT
00059 } AccountDialogType;
00060
00061
00062 typedef struct _AccountWindow
00063 {
00064 gboolean modal;
00065 GtkWidget *dialog;
00066
00067 AccountDialogType dialog_type;
00068
00069 GUID account;
00070 Account *top_level_account;
00071 Account *created_account;
00072
00073 GList *subaccount_names;
00074
00075 GNCAccountType type;
00076
00077 GtkWidget * notebook;
00078
00079 GtkWidget * name_entry;
00080 GtkWidget * description_entry;
00081 GtkWidget * code_entry;
00082 GtkTextBuffer * notes_text_buffer;
00083
00084 GtkWidget * commodity_edit;
00085 dialog_commodity_mode commodity_mode;
00086 GtkWidget * account_scu;
00087
00088 GList * valid_types;
00089 GtkWidget * type_list;
00090 GtkTreeView * parent_tree;
00091
00092 GtkWidget * opening_balance_edit;
00093 GtkWidget * opening_balance_date_edit;
00094 GtkWidget * opening_balance_page;
00095
00096 GtkWidget * opening_equity_radio;
00097 GtkWidget * transfer_account_frame;
00098 GtkWidget * transfer_tree;
00099
00100 GtkWidget * tax_related_button;
00101 GtkWidget * placeholder_button;
00102
00103 gint component_id;
00104 } AccountWindow;
00105
00106
00108 static short module = MOD_GUI;
00109
00110 static int last_used_account_type = BANK;
00111
00112 static GList *ac_destroy_cb_list = NULL;
00113
00115 static void gnc_account_window_set_name (AccountWindow *aw);
00116 static void make_account_changes(GHashTable *change_type);
00117
00118
00121 static void
00122 aw_call_destroy_callbacks (Account* acc)
00123 {
00124 GList *node;
00125 void (*cb)(Account*);
00126
00127 for (node = ac_destroy_cb_list; node; node = node->next) {
00128 cb = node->data;
00129 (cb)(acc);
00130 }
00131 }
00132
00133 static Account *
00134 aw_get_account (AccountWindow *aw)
00135 {
00136 if (!aw)
00137 return NULL;
00138
00139 return xaccAccountLookup (&aw->account, gnc_get_current_book ());
00140 }
00141
00142 static void
00143 gnc_account_commodity_from_type (AccountWindow * aw, gboolean update)
00144 {
00145 dialog_commodity_mode new_mode;
00146
00147 if ((aw->type == STOCK) || (aw->type == MUTUAL))
00148 new_mode = DIAG_COMM_NON_CURRENCY;
00149 else
00150 new_mode = DIAG_COMM_CURRENCY;
00151
00152 if (update && (new_mode != aw->commodity_mode)) {
00153 gnc_general_select_set_selected(GNC_GENERAL_SELECT (aw->commodity_edit),
00154 NULL);
00155 }
00156
00157 aw->commodity_mode = new_mode;
00158 }
00159
00160
00161 static void
00162 gnc_account_to_ui(AccountWindow *aw)
00163 {
00164 Account *account;
00165 gnc_commodity * commodity;
00166 const char *string;
00167 gboolean tax_related, placeholder, nonstd_scu;
00168 gint index;
00169
00170 ENTER("%p", aw);
00171 account = aw_get_account (aw);
00172 if (!account) {
00173 LEAVE("no account");
00174 return;
00175 }
00176
00177 string = xaccAccountGetName (account);
00178 if (string == NULL) string = "";
00179 gtk_entry_set_text(GTK_ENTRY(aw->name_entry), string);
00180
00181 string = xaccAccountGetDescription (account);
00182 if (string == NULL) string = "";
00183 gtk_entry_set_text(GTK_ENTRY(aw->description_entry), string);
00184
00185 commodity = xaccAccountGetCommodity (account);
00186 gnc_general_select_set_selected (GNC_GENERAL_SELECT (aw->commodity_edit),
00187 commodity);
00188 gnc_account_commodity_from_type (aw, FALSE);
00189
00190 nonstd_scu = xaccAccountGetNonStdSCU (account);
00191 if (nonstd_scu) {
00192 index = xaccAccountGetCommoditySCUi(account);
00193 index = log10(index) + 1;
00194 } else {
00195 index = 0;
00196 }
00197 gtk_option_menu_set_history(GTK_OPTION_MENU(aw->account_scu), index);
00198
00199 string = xaccAccountGetCode (account);
00200 if (string == NULL) string = "";
00201 gtk_entry_set_text(GTK_ENTRY(aw->code_entry), string);
00202
00203 string = xaccAccountGetNotes (account);
00204 if (string == NULL) string = "";
00205
00206 gtk_text_buffer_set_text (aw->notes_text_buffer, string, strlen(string));
00207
00208 tax_related = xaccAccountGetTaxRelated (account);
00209 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (aw->tax_related_button),
00210 tax_related);
00211
00212 placeholder = xaccAccountGetPlaceholder (account);
00213 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (aw->placeholder_button),
00214 placeholder);
00215
00216 gtk_tree_view_collapse_all (aw->parent_tree);
00217 gnc_tree_view_account_set_selected_account (GNC_TREE_VIEW_ACCOUNT(aw->parent_tree), account);
00218 LEAVE(" ");
00219 }
00220
00221
00222 static gboolean
00223 gnc_account_create_transfer_balance (Account *account,
00224 Account *transfer,
00225 gnc_numeric balance,
00226 time_t date)
00227 {
00228 Transaction *trans;
00229 Split *split;
00230
00231 if (gnc_numeric_zero_p (balance))
00232 return TRUE;
00233
00234 g_return_val_if_fail (account != NULL, FALSE);
00235 g_return_val_if_fail (transfer != NULL, FALSE);
00236
00237 xaccAccountBeginEdit (account);
00238 xaccAccountBeginEdit (transfer);
00239
00240 trans = xaccMallocTransaction (gnc_get_current_book ());
00241
00242 xaccTransBeginEdit (trans);
00243
00244 xaccTransSetCurrency (trans, xaccAccountGetCommodity (account));
00245 xaccTransSetDateSecs (trans, date);
00246 xaccTransSetDescription (trans, _("Opening Balance"));
00247
00248 split = xaccMallocSplit (gnc_get_current_book ());
00249
00250 xaccTransAppendSplit (trans, split);
00251 xaccAccountInsertSplit (account, split);
00252
00253 xaccSplitSetAmount (split, balance);
00254 xaccSplitSetValue (split, balance);
00255
00256 balance = gnc_numeric_neg (balance);
00257
00258 split = xaccMallocSplit (gnc_get_current_book ());
00259
00260 xaccTransAppendSplit (trans, split);
00261 xaccAccountInsertSplit (transfer, split);
00262
00263 xaccSplitSetAmount (split, balance);
00264 xaccSplitSetValue (split, balance);
00265
00266 xaccTransCommitEdit (trans);
00267 xaccAccountCommitEdit (transfer);
00268 xaccAccountCommitEdit (account);
00269
00270 return TRUE;
00271 }
00272
00273
00274 static void
00275 gnc_ui_to_account(AccountWindow *aw)
00276 {
00277 Account *account;
00278 gnc_commodity *commodity;
00279 Account *parent_account;
00280 const char *old_string;
00281 const char *string;
00282 gboolean tax_related, placeholder;
00283 gnc_numeric balance;
00284 gboolean use_equity, nonstd;
00285 time_t date;
00286 gint index, old_scu, new_scu;
00287 GtkTextIter start, end;
00288
00289 account = aw_get_account (aw);
00290 if (!account) {
00291 LEAVE("no account");
00292 return;
00293 }
00294
00295 xaccAccountBeginEdit (account);
00296
00297 if (aw->type != xaccAccountGetType (account))
00298 xaccAccountSetType (account, aw->type);
00299
00300 string = gtk_entry_get_text (GTK_ENTRY(aw->name_entry));
00301 old_string = xaccAccountGetName (account);
00302 if (safe_strcmp (string, old_string) != 0)
00303 xaccAccountSetName (account, string);
00304
00305 string = gtk_entry_get_text (GTK_ENTRY(aw->description_entry));
00306 old_string = xaccAccountGetDescription (account);
00307 if (safe_strcmp (string, old_string) != 0)
00308 xaccAccountSetDescription (account, string);
00309
00310 commodity = (gnc_commodity *)
00311 gnc_general_select_get_selected (GNC_GENERAL_SELECT (aw->commodity_edit));
00312 if (commodity &&
00313 !gnc_commodity_equiv(commodity, xaccAccountGetCommodity (account))) {
00314 xaccAccountSetCommodity (account, commodity);
00315 old_scu = 0;
00316 } else {
00317 old_scu = xaccAccountGetCommoditySCU(account);
00318 }
00319
00320 index = gnc_option_menu_get_active(aw->account_scu);
00321 nonstd = (index != 0);
00322 if (nonstd != xaccAccountGetNonStdSCU(account))
00323 xaccAccountSetNonStdSCU(account, nonstd);
00324 new_scu = (nonstd ? pow(10,index-1) : gnc_commodity_get_fraction(commodity));
00325 if (old_scu != new_scu)
00326 xaccAccountSetCommoditySCU(account, new_scu);
00327
00328 string = gtk_entry_get_text (GTK_ENTRY(aw->code_entry));
00329 old_string = xaccAccountGetCode (account);
00330 if (safe_strcmp (string, old_string) != 0)
00331 xaccAccountSetCode (account, string);
00332
00333 gtk_text_buffer_get_start_iter (aw->notes_text_buffer, &start);
00334 gtk_text_buffer_get_end_iter (aw->notes_text_buffer, &end);
00335 string = gtk_text_buffer_get_text (aw->notes_text_buffer, &start, &end, FALSE);
00336 old_string = xaccAccountGetNotes (account);
00337 if (safe_strcmp (string, old_string) != 0)
00338 xaccAccountSetNotes (account, string);
00339
00340 tax_related =
00341 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (aw->tax_related_button));
00342 xaccAccountSetTaxRelated (account, tax_related);
00343
00344 placeholder =
00345 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (aw->placeholder_button));
00346 xaccAccountSetPlaceholder (account, placeholder);
00347
00348 parent_account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->parent_tree));
00349 if (parent_account == aw->top_level_account)
00350 parent_account = NULL;
00351
00352 xaccAccountBeginEdit (parent_account);
00353
00354 if (parent_account != NULL)
00355 {
00356 if (parent_account != xaccAccountGetParentAccount (account))
00357 xaccAccountInsertSubAccount (parent_account, account);
00358 }
00359 else
00360 xaccGroupInsertAccount (gnc_get_current_group (), account);
00361
00362 xaccAccountCommitEdit (parent_account);
00363 xaccAccountCommitEdit (account);
00364
00365 balance = gnc_amount_edit_get_amount
00366 (GNC_AMOUNT_EDIT (aw->opening_balance_edit));
00367
00368 if (gnc_numeric_zero_p (balance)) {
00369 LEAVE("zero balance");
00370 return;
00371 }
00372
00373 if (gnc_reverse_balance (account))
00374 balance = gnc_numeric_neg (balance);
00375
00376 date = gnome_date_edit_get_time (
00377 GNOME_DATE_EDIT (aw->opening_balance_date_edit));
00378
00379 use_equity = gtk_toggle_button_get_active
00380 (GTK_TOGGLE_BUTTON (aw->opening_equity_radio));
00381
00382 if (use_equity)
00383 {
00384 if (!gnc_account_create_opening_balance (account, balance, date,
00385 gnc_get_current_book ()))
00386 {
00387 const char *message = _("Could not create opening balance.");
00388 gnc_error_dialog(aw->dialog, message);
00389 }
00390 }
00391 else
00392 {
00393 Account *transfer = NULL;
00394
00395 transfer = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->transfer_tree));
00396 if (!transfer) {
00397 LEAVE("no transfer account");
00398 return;
00399 }
00400
00401 gnc_account_create_transfer_balance (account, transfer, balance, date);
00402 }
00403 LEAVE(" ");
00404 }
00405
00406
00407 static void
00408 gnc_finish_ok (AccountWindow *aw,
00409 GHashTable *change_type)
00410 {
00411 ENTER("aw %p, hash table %p", aw, change_type);
00412 gnc_suspend_gui_refresh ();
00413
00414
00415 make_account_changes (change_type);
00416 gnc_ui_to_account (aw);
00417
00418 gnc_resume_gui_refresh ();
00419
00420
00421 if (aw->dialog_type == NEW_ACCOUNT && aw->subaccount_names)
00422 {
00423 gnc_commodity *commodity;
00424 Account *parent;
00425 Account *account;
00426 GList *node;
00427
00428 gnc_suspend_gui_refresh ();
00429
00430 parent = aw_get_account (aw);
00431 account = xaccMallocAccount (gnc_get_current_book ());
00432 aw->account = *xaccAccountGetGUID (account);
00433 aw->type = xaccAccountGetType (parent);
00434
00435 xaccAccountSetName (account, aw->subaccount_names->data);
00436
00437 node = aw->subaccount_names;
00438 aw->subaccount_names = g_list_remove_link (aw->subaccount_names, node);
00439 g_free (node->data);
00440 g_list_free_1 (node);
00441
00442 gnc_account_to_ui (aw);
00443
00444 gnc_account_window_set_name (aw);
00445
00446 commodity = xaccAccountGetCommodity (parent);
00447 gnc_general_select_set_selected (GNC_GENERAL_SELECT (aw->commodity_edit),
00448 commodity);
00449 gnc_account_commodity_from_type (aw, FALSE);
00450
00451
00452
00453
00454 gnc_resume_gui_refresh ();
00455 LEAVE("1");
00456 return;
00457 }
00458
00459
00460 aw->created_account = aw_get_account (aw);
00461
00462
00463 aw->account = *xaccGUIDNULL ();
00464
00465 gnc_close_gui_component (aw->component_id);
00466 LEAVE("2");
00467 }
00468
00469
00470
00471
00472 static void
00473 gnc_edit_change_account_types(GHashTable *change_type, Account *account,
00474 Account *except, GNCAccountType type)
00475 {
00476 AccountGroup *children;
00477 GList *list;
00478 GList *node;
00479
00480 if ((change_type == NULL) || (account == NULL))
00481 return;
00482
00483 if (account == except)
00484 return;
00485
00486 g_hash_table_insert(change_type, account, GINT_TO_POINTER(type));
00487
00488 children = xaccAccountGetChildren(account);
00489 if (children == NULL)
00490 return;
00491
00492 list = xaccGroupGetAccountList (children);
00493
00494 for (node= list; node; node = node->next)
00495 {
00496 account = node->data;
00497 gnc_edit_change_account_types(change_type, account, except, type);
00498 }
00499 }
00500
00501
00502
00503 static void
00504 change_func (gpointer key, gpointer value, gpointer unused)
00505 {
00506 Account *account = key;
00507 int type;
00508
00509 if (account == NULL)
00510 return;
00511
00512 xaccAccountBeginEdit(account);
00513
00514 type = GPOINTER_TO_INT(value);
00515
00516 if (type == xaccAccountGetType(account))
00517 return;
00518
00519
00520 aw_call_destroy_callbacks (account);
00521
00522 xaccAccountSetType(account, type);
00523
00524 xaccAccountCommitEdit(account);
00525 }
00526
00527
00528
00529 static void
00530 make_account_changes(GHashTable *change_type)
00531 {
00532 if (change_type != NULL)
00533 g_hash_table_foreach(change_type, change_func, NULL);
00534 }
00535
00536
00537 typedef struct
00538 {
00539 Account *account;
00540 GtkCList *list;
00541 guint count;
00542 } FillStruct;
00543
00544 static void
00545 fill_helper(gpointer key, gpointer value, gpointer data)
00546 {
00547 Account *account = key;
00548 FillStruct *fs = data;
00549 gchar *full_name;
00550 gchar *account_field_name;
00551 gchar *account_field_value;
00552 gchar *value_str;
00553
00554 if (fs == NULL) return;
00555 if (fs->account == account) return;
00556
00557 full_name = xaccAccountGetFullName(account, gnc_get_account_separator());
00558 if(!full_name)
00559 full_name = g_strdup("");
00560
00561 account_field_name = g_strdup("Type");
00562 if (!account_field_name)
00563 account_field_name = g_strdup("");
00564
00565 account_field_value =
00566 g_strdup (xaccAccountGetTypeStr(xaccAccountGetType(account)));
00567 if (!account_field_value)
00568 account_field_value = g_strdup("");
00569
00570 value_str = g_strdup(xaccAccountGetTypeStr(GPOINTER_TO_INT(value)));
00571
00572 {
00573 gchar *strings[5];
00574
00575 strings[0] = full_name;
00576 strings[1] = account_field_name;
00577 strings[2] = account_field_value;
00578 strings[3] = value_str;
00579 strings[4] = NULL;
00580
00581 gtk_clist_append(fs->list, strings);
00582 }
00583
00584 g_free(full_name);
00585 g_free(account_field_name);
00586 g_free(account_field_value);
00587 g_free(value_str);
00588 fs->count++;
00589 }
00590
00591 static guint
00592 fill_list(Account *account, GtkCList *list,
00593 GHashTable *change)
00594 {
00595 FillStruct fs;
00596
00597 if (change == NULL)
00598 return 0;
00599
00600 fs.account = account;
00601 fs.list = list;
00602 fs.count = 0;
00603
00604 g_hash_table_foreach(change, fill_helper, &fs);
00605
00606 return fs.count;
00607 }
00608
00609
00610
00611 static gboolean
00612 extra_change_verify (AccountWindow *aw,
00613 GHashTable *change_type)
00614 {
00615 Account *account;
00616 GtkCList *list;
00617 gchar *titles[5];
00618 gboolean result;
00619 guint size;
00620
00621 if (aw == NULL)
00622 return FALSE;
00623
00624 account = aw_get_account (aw);
00625 if (!account)
00626 return FALSE;
00627
00628 titles[0] = _("Account");
00629 titles[1] = _("Field");
00630 titles[2] = _("Old Value");
00631 titles[3] = _("New Value");
00632 titles[4] = NULL;
00633
00634 list = GTK_CLIST(gtk_clist_new_with_titles(4, titles));
00635
00636 size = 0;
00637 size += fill_list(account, list, change_type);
00638
00639 if (size == 0)
00640 {
00641 gtk_widget_destroy(GTK_WIDGET(list));
00642 return TRUE;
00643 }
00644
00645 gtk_clist_column_titles_passive(list);
00646 gtk_clist_set_sort_column(list, 0);
00647 gtk_clist_sort(list);
00648 gtk_clist_columns_autosize(list);
00649
00650 {
00651 GtkWidget *dialog;
00652 GtkWidget *scroll;
00653 GtkWidget *label;
00654 GtkWidget *frame;
00655 GtkWidget *vbox;
00656
00657 dialog = gtk_dialog_new_with_buttons (_("Verify Changes"),
00658 GTK_WINDOW(aw->dialog),
00659 GTK_DIALOG_DESTROY_WITH_PARENT |
00660 GTK_DIALOG_MODAL,
00661 GTK_STOCK_OK, GTK_RESPONSE_OK,
00662 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00663 NULL);
00664
00665 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
00666 gtk_window_set_default_size (GTK_WINDOW (dialog), 0, 300);
00667
00668 vbox = GTK_DIALOG (dialog)->vbox;
00669
00670 label = gtk_label_new(_("The following changes must be made. Continue?"));
00671 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
00672
00673 frame = gtk_frame_new(NULL);
00674 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
00675
00676 scroll = gtk_scrolled_window_new(NULL, NULL);
00677 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
00678 GTK_POLICY_NEVER,
00679 GTK_POLICY_AUTOMATIC);
00680
00681 gtk_container_add(GTK_CONTAINER(frame), scroll);
00682 gtk_container_border_width(GTK_CONTAINER(scroll), 5);
00683 gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(list));
00684
00685 gtk_widget_show_all(vbox);
00686
00687 result = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK);
00688
00689 gtk_widget_destroy(dialog);
00690 }
00691
00692 return result;
00693 }
00694
00695
00696 static gboolean
00697 gnc_filter_parent_accounts (Account *account, gpointer data)
00698 {
00699 AccountWindow *aw = data;
00700 Account *aw_account = aw_get_account (aw);
00701
00702 if (account == NULL)
00703 return FALSE;
00704
00705 if (aw_account == NULL)
00706 return FALSE;
00707
00708 if (account == aw->top_level_account)
00709 return TRUE;
00710
00711 if (account == aw_account)
00712 return FALSE;
00713
00714 if (xaccAccountHasAncestor(account, aw_account))
00715 return FALSE;
00716
00717 return TRUE;
00718 }
00719
00720
00721 static void
00722 gnc_edit_account_ok(AccountWindow *aw)
00723 {
00724 GHashTable *change_type;
00725
00726 gboolean change_children;
00727 gboolean has_children;
00728 gboolean change_all;
00729
00730 Account *new_parent;
00731 Account *account;
00732 AccountGroup *children;
00733
00734 GNCAccountType current_type;
00735
00736 const char *name;
00737 gnc_commodity * commodity;
00738
00739
00740 ENTER("aw %p", aw);
00741 name = gtk_entry_get_text(GTK_ENTRY(aw->name_entry));
00742 if (safe_strcmp(name, "") == 0)
00743 {
00744 const char *message = _("The account must be given a name.");
00745 gnc_error_dialog(aw->dialog, message);
00746 LEAVE(" ");
00747 return;
00748 }
00749
00750
00751 if (aw->type == BAD_TYPE)
00752 {
00753 const char *message = _("You must select an account type.");
00754 gnc_error_dialog(aw->dialog, message);
00755 LEAVE(" ");
00756 return;
00757 }
00758
00759 new_parent = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->parent_tree));
00760
00761
00762 if (!gnc_filter_parent_accounts(new_parent, aw))
00763 {
00764 const char *message = _("You must choose a valid parent account.");
00765 gnc_error_dialog(aw->dialog, message);
00766 LEAVE(" ");
00767 return;
00768 }
00769
00770 commodity = (gnc_commodity *)
00771 gnc_general_select_get_selected (GNC_GENERAL_SELECT (aw->commodity_edit));
00772
00773 if (!commodity)
00774 {
00775 const char *message = _("You must choose a commodity.");
00776 gnc_error_dialog(aw->dialog, message);
00777 LEAVE(" ");
00778 return;
00779 }
00780
00781 account = aw_get_account (aw);
00782 if (!account) {
00783 LEAVE(" ");
00784 return;
00785 }
00786
00787 change_type = g_hash_table_new (NULL, NULL);
00788
00789 children = xaccAccountGetChildren(account);
00790 if (children == NULL)
00791 has_children = FALSE;
00792 else if (xaccGroupGetNumAccounts(children) == 0)
00793 has_children = FALSE;
00794 else
00795 has_children = TRUE;
00796
00797 current_type = xaccAccountGetType(account);
00798
00799
00800
00801 change_children = (has_children &&
00802 !xaccAccountTypesCompatible(current_type, aw->type));
00803
00804
00805
00806 if (new_parent != aw->top_level_account)
00807 {
00808 int parent_type;
00809
00810 parent_type = xaccAccountGetType(new_parent);
00811
00812 if (!xaccAccountTypesCompatible(parent_type, aw->type))
00813 change_all = TRUE;
00814 else
00815 change_all = FALSE;
00816 }
00817 else
00818 change_all = FALSE;
00819
00820 if (change_children)
00821 gnc_edit_change_account_types(change_type, account, NULL, aw->type);
00822
00823 if (change_all)
00824 {
00825 Account *ancestor;
00826 Account *temp;
00827
00828 temp = new_parent;
00829
00830 do
00831 {
00832 ancestor = temp;
00833 temp = xaccAccountGetParentAccount(ancestor);
00834 } while (temp != NULL);
00835
00836 gnc_edit_change_account_types(change_type, ancestor, account, aw->type);
00837 }
00838
00839 if (!extra_change_verify(aw, change_type))
00840 {
00841 g_hash_table_destroy(change_type);
00842 LEAVE(" ");
00843 return;
00844 }
00845
00846 if (current_type != aw->type)
00847
00848 aw_call_destroy_callbacks (account);
00849
00850 gnc_finish_ok (aw, change_type);
00851
00852 g_hash_table_destroy (change_type);
00853 LEAVE(" ");
00854 }
00855
00856
00857 static void
00858 gnc_new_account_ok (AccountWindow *aw)
00859 {
00860 const gnc_commodity * commodity;
00861 Account *parent_account;
00862 gnc_numeric balance;
00863 const gchar *name;
00864
00865
00866 ENTER("aw %p", aw);
00867 name = gtk_entry_get_text(GTK_ENTRY(aw->name_entry));
00868 if (safe_strcmp(name, "") == 0)
00869 {
00870 const char *message = _("The account must be given a name.");
00871 gnc_error_dialog(aw->dialog, message);
00872 LEAVE(" ");
00873 return;
00874 }
00875
00876 parent_account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->parent_tree));
00877
00878 if (parent_account == aw->top_level_account)
00879 parent_account = NULL;
00880
00881
00882 {
00883 Account *account;
00884 AccountGroup *group;
00885 char separator;
00886
00887 group = gnc_get_current_group ();
00888
00889 separator = gnc_get_account_separator();
00890
00891 if (parent_account == NULL)
00892 account = xaccGetAccountFromFullName(group, name, separator);
00893 else
00894 {
00895 char *fullname_parent;
00896 char *fullname;
00897 char sep_string[2];
00898
00899 sep_string[0] = separator;
00900 sep_string[1] = '\0';
00901
00902 fullname_parent = xaccAccountGetFullName(parent_account, separator);
00903 fullname = g_strconcat(fullname_parent, sep_string, name, NULL);
00904
00905 account = xaccGetAccountFromFullName(group, fullname, separator);
00906
00907 g_free(fullname_parent);
00908 g_free(fullname);
00909 }
00910
00911 if (account != NULL)
00912 {
00913 const char *message = _("There is already an account with that name.");
00914 gnc_error_dialog(aw->dialog, message);
00915 LEAVE(" ");
00916 return;
00917 }
00918 }
00919
00920
00921 if (aw->type == BAD_TYPE)
00922 {
00923 const char *message = _("You must select an account type.");
00924 gnc_error_dialog(aw->dialog, message);
00925 LEAVE(" ");
00926 return;
00927 }
00928
00929
00930 commodity = (gnc_commodity *)
00931 gnc_general_select_get_selected (GNC_GENERAL_SELECT (aw->commodity_edit));
00932
00933 if (!commodity)
00934 {
00935 const char *message = _("You must choose a commodity.");
00936 gnc_error_dialog(aw->dialog, message);
00937 LEAVE(" ");
00938 return;
00939 }
00940
00941 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (aw->opening_balance_edit)))
00942 {
00943 const char *message = _("You must enter a valid opening balance "
00944 "or leave it blank.");
00945 gnc_error_dialog(aw->dialog, message);
00946 LEAVE(" ");
00947 return;
00948 }
00949
00950 balance = gnc_amount_edit_get_amount
00951 (GNC_AMOUNT_EDIT (aw->opening_balance_edit));
00952
00953 if (!gnc_numeric_zero_p (balance))
00954 {
00955 gboolean use_equity;
00956
00957 use_equity = gtk_toggle_button_get_active
00958 (GTK_TOGGLE_BUTTON (aw->opening_equity_radio));
00959
00960 if (!use_equity)
00961 {
00962 Account *transfer = NULL;
00963
00964 transfer = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->transfer_tree));
00965 if (!transfer)
00966 {
00967 const char *message = _("You must select a transfer account or choose"
00968 "\nthe opening balances equity account.");
00969 gnc_error_dialog(aw->dialog, message);
00970 LEAVE(" ");
00971 return;
00972 }
00973 }
00974 }
00975
00976 gnc_finish_ok (aw, NULL);
00977 LEAVE(" ");
00978 }
00979
00980 static void
00981 gnc_account_window_response_cb (GtkDialog *dialog,
00982 gint response,
00983 gpointer data)
00984 {
00985 AccountWindow *aw = data;
00986
00987 ENTER("dialog %p, response %d, aw %p", dialog, response, aw);
00988 switch (response) {
00989 case GTK_RESPONSE_OK:
00990 switch (aw->dialog_type) {
00991 case NEW_ACCOUNT:
00992 DEBUG("new acct dialog, OK");
00993 gnc_new_account_ok (aw);
00994 break;
00995 case EDIT_ACCOUNT:
00996 DEBUG("edit acct dialog, OK");
00997 gnc_edit_account_ok (aw);
00998 break;
00999 default:
01000 g_assert_not_reached ();
01001 return;
01002 }
01003 break;
01004 case GTK_RESPONSE_HELP:
01005 switch (aw->dialog_type) {
01006 case NEW_ACCOUNT:
01007 DEBUG("new acct dialog, HELP");
01008 gnc_gnome_help(HF_USAGE, HL_ACC);
01009 break;
01010 case EDIT_ACCOUNT:
01011 DEBUG("edit acct dialog, HELP");
01012 gnc_gnome_help(HF_USAGE, HL_ACCEDIT);
01013 break;
01014 default:
01015 g_assert_not_reached ();
01016 return;
01017 }
01018 break;
01019 case GTK_RESPONSE_CANCEL:
01020 default:
01021 DEBUG("CANCEL");
01022 gnc_close_gui_component (aw->component_id);
01023 break;
01024 }
01025 LEAVE(" ");
01026 }
01027
01028 static void
01029 gnc_account_window_destroy_cb (GtkObject *object, gpointer data)
01030 {
01031 AccountWindow *aw = data;
01032 Account *account;
01033
01034 ENTER("object %p, aw %p", object, aw);
01035 account = aw_get_account (aw);
01036
01037 gnc_suspend_gui_refresh ();
01038
01039 switch (aw->dialog_type)
01040 {
01041 case NEW_ACCOUNT:
01042 if (account != NULL)
01043 {
01044 xaccAccountBeginEdit (account);
01045 xaccAccountDestroy (account);
01046 aw->account = *xaccGUIDNULL ();
01047 }
01048
01049 DEBUG ("account add window destroyed\n");
01050 break;
01051
01052 case EDIT_ACCOUNT:
01053 break;
01054
01055 default:
01056 PERR ("unexpected dialog type\n");
01057 gnc_resume_gui_refresh ();
01058 LEAVE(" ");
01059 return;
01060 }
01061
01062 gnc_unregister_gui_component (aw->component_id);
01063
01064 aw->top_level_account = NULL;
01065
01066 gnc_resume_gui_refresh ();
01067
01068 if (aw->subaccount_names)
01069 {
01070 GList *node;
01071 for (node = aw->subaccount_names; node; node = node->next)
01072 g_free (node->data);
01073 g_list_free (aw->subaccount_names);
01074 aw->subaccount_names = NULL;
01075 }
01076
01077 g_list_free (aw->valid_types);
01078 g_free (aw);
01079 LEAVE(" ");
01080 }
01081
01082
01083 static void
01084 gnc_type_list_select_cb(GtkCList * type_list, gint row, gint column,
01085 GdkEventButton * event, gpointer data)
01086 {
01087 AccountWindow * aw = data;
01088 gboolean sensitive;
01089
01090 if (aw == NULL)
01091 return;
01092
01093 if (!gtk_clist_get_selectable(type_list, row))
01094 {
01095 gtk_clist_unselect_row(type_list, row, 0);
01096 return;
01097 }
01098
01099 aw->type = (GNCAccountType)gtk_clist_get_row_data(type_list, row);
01100
01101 last_used_account_type = aw->type;
01102
01103 sensitive = (aw->type != EQUITY &&
01104 aw->type != CURRENCY &&
01105 aw->type != STOCK &&
01106 aw->type != MUTUAL);
01107
01108 gnc_account_commodity_from_type (aw, TRUE);
01109 gtk_widget_set_sensitive(aw->opening_balance_page, sensitive);
01110 if (!sensitive)
01111 {
01112 gtk_notebook_set_page (GTK_NOTEBOOK (aw->notebook), 0);
01113 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (aw->opening_balance_edit),
01114 gnc_numeric_zero ());
01115 }
01116 }
01117
01118
01119 static void
01120 gnc_type_list_unselect_cb(GtkCList * type_list, gint row, gint column,
01121 GdkEventButton * event, gpointer data)
01122 {
01123 AccountWindow * aw = data;
01124
01125 aw->type = BAD_TYPE;
01126 }
01127
01128
01129 static void
01130 gnc_account_list_fill(GtkCList *type_list, GList *types)
01131 {
01132 gint row, acct_type;
01133 gchar *text[2] = { NULL, NULL };
01134
01135 gtk_clist_freeze(type_list);
01136 gtk_clist_clear(type_list);
01137
01138 if (types == NULL)
01139 {
01140 for (acct_type = 0; acct_type < NUM_ACCOUNT_TYPES; acct_type++)
01141 {
01142 text[0] = (gchar *) xaccAccountGetTypeStr(acct_type);
01143 row = gtk_clist_append(type_list, text);
01144 gtk_clist_set_row_data(type_list, row, GINT_TO_POINTER(acct_type));
01145 }
01146 }
01147 else
01148 {
01149 for ( ; types != NULL; types = types->next )
01150 {
01151 text[0] = (gchar *) xaccAccountGetTypeStr
01152 ((GNCAccountType) (types->data));
01153 row = gtk_clist_append (type_list, text);
01154 gtk_clist_set_row_data(type_list, row, (gpointer)types->data);
01155 }
01156 }
01157 gtk_clist_thaw(type_list);
01158 }
01159
01160 static GNCAccountType
01161 gnc_account_choose_new_acct_type (AccountWindow *aw)
01162 {
01163
01164 if (aw->valid_types == NULL)
01165 return last_used_account_type;
01166
01167 if (g_list_index (aw->valid_types, GINT_TO_POINTER(last_used_account_type)) != -1)
01168 return last_used_account_type;
01169
01170 return ((GNCAccountType)(aw->valid_types->data));
01171 }
01172
01173 static void
01174 gnc_account_type_list_create(AccountWindow *aw)
01175 {
01176 int row;
01177
01178 gnc_account_list_fill(GTK_CLIST(aw->type_list), aw->valid_types);
01179
01180 gtk_clist_columns_autosize(GTK_CLIST(aw->type_list));
01181
01182 gtk_clist_sort(GTK_CLIST(aw->type_list));
01183
01184 g_signal_connect(GTK_OBJECT(aw->type_list), "select-row",
01185 G_CALLBACK(gnc_type_list_select_cb), aw);
01186
01187 g_signal_connect(GTK_OBJECT(aw->type_list), "unselect-row",
01188 G_CALLBACK(gnc_type_list_unselect_cb), aw);
01189
01190 switch (aw->dialog_type)
01191 {
01192 case NEW_ACCOUNT:
01193 aw->type = gnc_account_choose_new_acct_type (aw);
01194 break;
01195 case EDIT_ACCOUNT:
01196 aw->type = xaccAccountGetType (aw_get_account (aw));
01197 break;
01198 }
01199
01200 row = gtk_clist_find_row_from_data(GTK_CLIST(aw->type_list),
01201 (gpointer)aw->type);
01202 gtk_clist_select_row(GTK_CLIST(aw->type_list), row, 0);
01203 gtk_clist_moveto(GTK_CLIST(aw->type_list), row, 0, 0.5, 0);
01204 }
01205
01206 static void
01207 gnc_account_name_changed_cb(GtkWidget *widget, gpointer data)
01208 {
01209 AccountWindow *aw = data;
01210
01211 gnc_account_window_set_name (aw);
01212 }
01213
01214 static void
01215 commodity_changed_cb (GNCGeneralSelect *gsl, gpointer data)
01216 {
01217 AccountWindow *aw = data;
01218 gnc_commodity *currency;
01219 GtkTreeSelection *selection;
01220
01221 currency = (gnc_commodity *) gnc_general_select_get_selected (gsl);
01222 if (!currency)
01223 return;
01224
01225 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (aw->opening_balance_edit),
01226 gnc_commodity_get_fraction (currency));
01227 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (aw->opening_balance_edit),
01228 gnc_commodity_print_info (currency, FALSE));
01229
01230 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->transfer_tree));
01231 gtk_tree_selection_unselect_all (selection);
01232 }
01233
01234 static gboolean
01235 account_commodity_filter (GtkTreeSelection *selection,
01236 GtkTreeModel *unused_model,
01237 GtkTreePath *s_path,
01238 gboolean path_currently_selected,
01239 gpointer user_data)
01240 {
01241 gnc_commodity *commodity;
01242 AccountWindow *aw;
01243 Account *account;
01244
01245 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
01246
01247 aw = user_data;
01248
01249 if (path_currently_selected) {
01250
01251 return TRUE;
01252 }
01253
01254 account = gnc_tree_view_account_get_account_from_path (GNC_TREE_VIEW_ACCOUNT (aw->transfer_tree), s_path);
01255 if (!account) {
01256 return FALSE;
01257 }
01258
01259 commodity = (gnc_commodity *)
01260 gnc_general_select_get_selected (GNC_GENERAL_SELECT (aw->commodity_edit));
01261
01262 return gnc_commodity_equiv (xaccAccountGetCommodity (account), commodity);
01263 }
01264
01265 static void
01266 opening_equity_cb (GtkWidget *w, gpointer data)
01267 {
01268 AccountWindow *aw = data;
01269 gboolean use_equity;
01270
01271 use_equity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
01272
01273 gtk_widget_set_sensitive (aw->transfer_account_frame, !use_equity);
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283 static void
01284 gnc_account_window_create(AccountWindow *aw)
01285 {
01286 GtkDialog *awd;
01287 GtkWidget *amount;
01288 GObject *awo;
01289 GtkWidget *box;
01290 GladeXML *xml;
01291 GtkTreeSelection *selection;
01292
01293 ENTER("aw %p, modal %d", aw, aw->modal);
01294 xml = gnc_glade_xml_new ("account.glade", "Account Dialog");
01295
01296 aw->dialog = glade_xml_get_widget (xml, "Account Dialog");
01297 awo = G_OBJECT (aw->dialog);
01298 awd = GTK_DIALOG (awo);
01299
01300 g_object_set_data (awo, "dialog_info", aw);
01301
01302
01303 gtk_dialog_set_default_response (awd, GTK_RESPONSE_OK);
01304
01305 g_signal_connect (awo, "destroy",
01306 G_CALLBACK (gnc_account_window_destroy_cb), aw);
01307
01308 if (!aw->modal)
01309 g_signal_connect (awo, "response",
01310 G_CALLBACK (gnc_account_window_response_cb), aw);
01311 else
01312 gtk_window_set_modal (GTK_WINDOW (aw->dialog), TRUE);
01313
01314 aw->notebook = glade_xml_get_widget (xml, "account_notebook");
01315
01316 aw->name_entry = glade_xml_get_widget (xml, "name_entry");
01317 g_signal_connect (G_OBJECT (aw->name_entry), "changed",
01318 G_CALLBACK (gnc_account_name_changed_cb), aw);
01319
01320 aw->description_entry = glade_xml_get_widget (xml, "description_entry");
01321 aw->code_entry = glade_xml_get_widget (xml, "code_entry");
01322 aw->notes_text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (glade_xml_get_widget (xml, "notes_text")));
01323
01324 box = glade_xml_get_widget (xml, "commodity_hbox");
01325 aw->commodity_edit = gnc_general_select_new (GNC_GENERAL_SELECT_TYPE_SELECT,
01326 gnc_commodity_edit_get_string,
01327 gnc_commodity_edit_new_select,
01328 &aw->commodity_mode);
01329 gtk_box_pack_start(GTK_BOX(box), aw->commodity_edit, TRUE, TRUE, 0);
01330 gtk_widget_show (aw->commodity_edit);
01331
01332 g_signal_connect (G_OBJECT (aw->commodity_edit), "changed",
01333 G_CALLBACK (commodity_changed_cb), aw);
01334
01335 aw->account_scu = glade_xml_get_widget (xml, "account_scu");
01336 gnc_option_menu_init(aw->account_scu);
01337
01338 box = glade_xml_get_widget (xml, "parent_scroll");
01339
01340
01341 aw->parent_tree = gnc_tree_view_account_new(TRUE);
01342 gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(aw->parent_tree));
01343 gnc_tree_view_configure_columns (GNC_TREE_VIEW(aw->parent_tree), NULL);
01344 gtk_widget_show(GTK_WIDGET(aw->parent_tree));
01345 aw->top_level_account =
01346 gnc_tree_view_account_get_top_level (GNC_TREE_VIEW_ACCOUNT(aw->parent_tree));
01347
01348 aw->tax_related_button = glade_xml_get_widget (xml, "tax_related_button");
01349 aw->placeholder_button = glade_xml_get_widget (xml, "placeholder_button");
01350
01351 box = glade_xml_get_widget (xml, "opening_balance_box");
01352 amount = gnc_amount_edit_new ();
01353 aw->opening_balance_edit = amount;
01354 gtk_box_pack_start(GTK_BOX(box), amount, TRUE, TRUE, 0);
01355 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
01356 gtk_widget_show (amount);
01357
01358 box = glade_xml_get_widget (xml, "opening_balance_date_box");
01359 aw->opening_balance_date_edit = glade_xml_get_widget (xml, "opening_balance_date_edit");
01360
01361 aw->opening_balance_page =
01362 gtk_notebook_get_nth_page (GTK_NOTEBOOK (aw->notebook), 1);
01363
01364 aw->opening_equity_radio = glade_xml_get_widget (xml,
01365 "opening_equity_radio");
01366 g_signal_connect (G_OBJECT (aw->opening_equity_radio), "toggled",
01367 G_CALLBACK (opening_equity_cb), aw);
01368
01369 aw->transfer_account_frame =
01370 glade_xml_get_widget (xml, "transfer_account_frame");
01371
01372 box = glade_xml_get_widget (xml, "transfer_account_scroll");
01373
01374 aw->transfer_tree = GTK_WIDGET(gnc_tree_view_account_new(FALSE));
01375 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(aw->transfer_tree));
01376 gtk_tree_selection_set_select_function(selection, account_commodity_filter, aw, NULL);
01377
01378 gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(aw->transfer_tree));
01379 gtk_widget_show (GTK_WIDGET(aw->transfer_tree));
01380
01381
01382 aw->type_list = glade_xml_get_widget (xml, "type_list");
01383 gnc_account_type_list_create (aw);
01384
01385 gnc_restore_window_size (GCONF_SECTION, GTK_WINDOW(aw->dialog));
01386
01387 gtk_widget_grab_focus(GTK_WIDGET(aw->name_entry));
01388 LEAVE(" ");
01389 }
01390
01391
01392 static char *
01393 get_ui_fullname (AccountWindow *aw)
01394 {
01395 Account *parent_account;
01396 char *fullname;
01397 const gchar *name;
01398
01399 name = gtk_entry_get_text (GTK_ENTRY(aw->name_entry));
01400 if (!name || *name == '\0')
01401 name = _("<No name>");
01402
01403 parent_account = NULL;
01404
01405 parent_account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->parent_tree));
01406 if (parent_account == aw->top_level_account)
01407 parent_account = NULL;
01408
01409 if (parent_account)
01410 {
01411 char *parent_name;
01412 char sep_string[2];
01413
01414 parent_name = xaccAccountGetFullName (parent_account,
01415 gnc_get_account_separator());
01416
01417 sep_string[0] = gnc_get_account_separator ();
01418 sep_string[1] = '\0';
01419
01420 fullname = g_strconcat (parent_name, sep_string, name, NULL);
01421
01422 g_free (parent_name);
01423 }
01424 else
01425 fullname = g_strdup (name);
01426
01427 return fullname;
01428 }
01429
01430 static void
01431 gnc_account_window_set_name (AccountWindow *aw)
01432 {
01433 char *fullname;
01434 char *title;
01435
01436 if (!aw || !aw->parent_tree)
01437 return;
01438
01439 fullname = get_ui_fullname (aw);
01440
01441 if (aw->dialog_type == EDIT_ACCOUNT)
01442 title = g_strconcat(_("Edit Account"), " - ", fullname, NULL);
01443 else if (g_list_length (aw->subaccount_names) > 0)
01444 {
01445 const char *format = _("(%d) New Accounts");
01446 char *prefix;
01447
01448 prefix = g_strdup_printf (format,
01449 g_list_length (aw->subaccount_names) + 1);
01450
01451 title = g_strconcat (prefix, " - ", fullname, " ...", NULL);
01452
01453 g_free (prefix);
01454 }
01455 else
01456 title = g_strconcat (_("New Account"), " - ", fullname, NULL);
01457
01458 gtk_window_set_title (GTK_WINDOW(aw->dialog), title);
01459
01460 g_free (fullname);
01461 g_free (title);
01462 }
01463
01464
01465 static void
01466 close_handler (gpointer user_data)
01467 {
01468 AccountWindow *aw = user_data;
01469
01470 ENTER("aw %p, modal %d", aw, aw->modal);
01471 gnc_save_window_size (GCONF_SECTION, GTK_WINDOW(aw->dialog));
01472
01473 gtk_widget_destroy (GTK_WIDGET (aw->dialog));
01474 LEAVE(" ");
01475 }
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485 static void
01486 gnc_ui_refresh_account_window (AccountWindow *aw)
01487 {
01488 if (aw == NULL)
01489 return;
01490
01491
01492
01493 gnc_account_window_set_name (aw);
01494 }
01495
01496
01497 static void
01498 refresh_handler (GHashTable *changes, gpointer user_data)
01499 {
01500 AccountWindow *aw = user_data;
01501 const EventInfo *info;
01502 Account *account;
01503
01504 account = aw_get_account (aw);
01505 if (!account)
01506 {
01507 gnc_close_gui_component (aw->component_id);
01508 return;
01509 }
01510
01511 if (changes)
01512 {
01513 info = gnc_gui_get_entity_events (changes, &aw->account);
01514 if (info && (info->event_mask & GNC_EVENT_DESTROY))
01515 {
01516 gnc_close_gui_component (aw->component_id);
01517 return;
01518 }
01519 }
01520
01521 gnc_ui_refresh_account_window (aw);
01522 }
01523
01524
01525 static AccountWindow *
01526 gnc_ui_new_account_window_internal (Account *base_account,
01527 GList *subaccount_names,
01528 GList *valid_types,
01529 gnc_commodity * default_commodity,
01530 gboolean modal)
01531 {
01532 gnc_commodity *commodity;
01533 AccountWindow *aw;
01534 Account *account;
01535
01536 aw = g_new0 (AccountWindow, 1);
01537
01538 aw->modal = modal;
01539 aw->dialog_type = NEW_ACCOUNT;
01540 aw->valid_types = g_list_copy (valid_types);
01541
01542 account = xaccMallocAccount (gnc_get_current_book ());
01543 aw->account = *xaccAccountGetGUID (account);
01544
01545 if (base_account)
01546 aw->type = xaccAccountGetType (base_account);
01547 else
01548 aw->type = last_used_account_type;
01549
01550 gnc_suspend_gui_refresh ();
01551
01552 if (subaccount_names)
01553 {
01554 GList *node;
01555
01556 xaccAccountSetName (account, subaccount_names->data);
01557
01558 aw->subaccount_names = g_list_copy (subaccount_names->next);
01559 for (node = aw->subaccount_names; node; node = node->next)
01560 node->data = g_strdup (node->data);
01561 }
01562
01563 gnc_account_window_create (aw);
01564 gnc_account_to_ui (aw);
01565
01566 gnc_resume_gui_refresh ();
01567
01568 if (default_commodity != NULL) {
01569 commodity = default_commodity;
01570 } else if ((aw->type != STOCK) && (aw->type != MUTUAL)) {
01571 commodity = gnc_default_currency ();
01572 } else {
01573 commodity = NULL;
01574 }
01575 gnc_general_select_set_selected (GNC_GENERAL_SELECT (aw->commodity_edit),
01576 commodity);
01577 gnc_account_commodity_from_type (aw, FALSE);
01578
01579 gtk_widget_show (aw->dialog);
01580
01581 if (base_account == NULL) {
01582 base_account = aw->top_level_account;
01583 }
01584
01585 gtk_tree_view_collapse_all (aw->parent_tree);
01586 gnc_tree_view_account_set_selected_account (GNC_TREE_VIEW_ACCOUNT (aw->parent_tree),
01587 base_account);
01588
01589 gnc_window_adjust_for_screen (GTK_WINDOW(aw->dialog));
01590
01591 gnc_account_window_set_name (aw);
01592
01593 aw->component_id = gnc_register_gui_component (DIALOG_NEW_ACCOUNT_CM_CLASS,
01594 refresh_handler,
01595 modal ? NULL : close_handler,
01596 aw);
01597
01598 gnc_gui_component_set_session (aw->component_id, gnc_get_current_session());
01599 gnc_gui_component_watch_entity_type (aw->component_id,
01600 GNC_ID_ACCOUNT,
01601 GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
01602 return aw;
01603 }
01604
01605
01606 static GList *
01607 gnc_split_account_name (const char *in_name, Account **base_account)
01608 {
01609 AccountGroup *group;
01610 GList *names;
01611 char separator;
01612 char *name;
01613
01614 names = NULL;
01615 name = g_strdup (in_name);
01616 *base_account = NULL;
01617 group = gnc_get_current_group ();
01618
01619 separator = gnc_get_account_separator ();
01620
01621 while (name && *name != '\0')
01622 {
01623 Account *account;
01624 char *p;
01625
01626 account = xaccGetAccountFromFullName (group, name, separator);
01627 if (account)
01628 {
01629 *base_account = account;
01630 break;
01631 }
01632
01633 p = strrchr (name, separator);
01634 if (p)
01635 {
01636 *p++ = '\0';
01637
01638 if (*p == '\0')
01639 {
01640 GList *node;
01641 for (node = names; node; node = node->next)
01642 g_free (node->data);
01643 g_list_free (names);
01644 return NULL;
01645 }
01646
01647 names = g_list_prepend (names, g_strdup (p));
01648 }
01649 else
01650 {
01651 names = g_list_prepend (names, g_strdup (name));
01652 break;
01653 }
01654 }
01655
01656 g_free (name);
01657
01658 return names;
01659 }
01660
01661
01662
01663
01664
01665
01666 Account *
01667 gnc_ui_new_accounts_from_name_window (const char *name)
01668 {
01669 return gnc_ui_new_accounts_from_name_with_defaults (name, NULL, NULL, NULL);
01670 }
01671
01672 Account *
01673 gnc_ui_new_accounts_from_name_window_with_types (const char *name,
01674 GList *valid_types)
01675 {
01676 return gnc_ui_new_accounts_from_name_with_defaults(name, valid_types, NULL, NULL);
01677 }
01678
01679 Account * gnc_ui_new_accounts_from_name_with_defaults (const char *name,
01680 GList *valid_types,
01681 gnc_commodity * default_commodity,
01682 Account * parent)
01683 {
01684 AccountWindow *aw;
01685 Account *base_account;
01686 Account *created_account = NULL;
01687 GList * subaccount_names;
01688 GList * node;
01689 gint response;
01690
01691 ENTER("name %s, valid %p, commodity %p, account %p",
01692 name, valid_types, default_commodity, parent);
01693 if (!name || *name == '\0')
01694 {
01695 subaccount_names = NULL;
01696 base_account = NULL;
01697 }
01698 else
01699 subaccount_names = gnc_split_account_name (name, &base_account);
01700
01701 if (parent != NULL)
01702 {
01703 base_account=parent;
01704 }
01705 aw = gnc_ui_new_account_window_internal (base_account, subaccount_names,
01706 valid_types, default_commodity,
01707 TRUE);
01708
01709 for (node = subaccount_names; node; node = node->next)
01710 g_free (node->data);
01711 g_list_free (subaccount_names);
01712
01713 do {
01714 response = gtk_dialog_run (GTK_DIALOG(aw->dialog));
01715
01716
01717 gnc_account_window_response_cb (GTK_DIALOG(aw->dialog), response, (gpointer)aw);
01718
01719 if (response == GTK_RESPONSE_OK)
01720 created_account = aw->created_account;
01721 } while ((response == GTK_RESPONSE_HELP) || (response == GNC_RESPONSE_NEW));
01722
01723 close_handler(aw);
01724 LEAVE("created %s (%p)", xaccAccountGetName(created_account), created_account);
01725 return created_account;
01726 }
01727
01728
01729
01730
01731
01732 static gboolean
01733 find_by_account (gpointer find_data, gpointer user_data)
01734 {
01735 Account *account = find_data;
01736 AccountWindow *aw = user_data;
01737
01738 if (!aw)
01739 return FALSE;
01740
01741 return guid_equal (&aw->account, xaccAccountGetGUID (account));
01742 }
01743
01744
01745
01746
01747
01748
01749
01750 void
01751 gnc_ui_edit_account_window(Account *account)
01752 {
01753 AccountWindow * aw;
01754 Account *parent;
01755
01756 if (account == NULL)
01757 return;
01758
01759 aw = gnc_find_first_gui_component (DIALOG_EDIT_ACCOUNT_CM_CLASS,
01760 find_by_account, account);
01761 if (aw) {
01762 gtk_window_present(GTK_WINDOW(aw->dialog));
01763 return;
01764 }
01765
01766 aw = g_new0 (AccountWindow, 1);
01767
01768 aw->modal = FALSE;
01769 aw->dialog_type = EDIT_ACCOUNT;
01770 aw->account = *xaccAccountGetGUID (account);
01771 aw->subaccount_names = NULL;
01772
01773 gnc_suspend_gui_refresh ();
01774
01775 gnc_account_window_create (aw);
01776 gnc_account_to_ui (aw);
01777
01778 gnc_resume_gui_refresh ();
01779
01780 gtk_widget_show_all (aw->dialog);
01781 gtk_widget_hide (aw->opening_balance_page);
01782
01783 parent = xaccAccountGetParentAccount (account);
01784 if (parent == NULL)
01785 parent = aw->top_level_account;
01786
01787 gnc_tree_view_account_set_selected_account (GNC_TREE_VIEW_ACCOUNT(aw->parent_tree), parent);
01788
01789 gnc_account_window_set_name (aw);
01790
01791 gnc_window_adjust_for_screen(GTK_WINDOW(aw->dialog));
01792
01793 aw->component_id = gnc_register_gui_component (DIALOG_EDIT_ACCOUNT_CM_CLASS,
01794 refresh_handler,
01795 close_handler, aw);
01796
01797 gnc_gui_component_set_session (aw->component_id, gnc_get_current_session());
01798 gnc_gui_component_watch_entity_type (aw->component_id,
01799 GNC_ID_ACCOUNT,
01800 GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
01801
01802 gtk_window_present(GTK_WINDOW(aw->dialog));
01803 }
01804
01805
01806
01807
01808
01809
01810
01811 void
01812 gnc_ui_new_account_window (AccountGroup *this_is_not_used)
01813 {
01814
01815 gnc_ui_new_account_window_internal (NULL, NULL, NULL, NULL, FALSE);
01816 }
01817
01818
01819
01820
01821
01822
01823
01824 void
01825 gnc_ui_new_account_window_with_default(AccountGroup *this_is_not_used,
01826 Account * parent)
01827 {
01828 gnc_ui_new_account_window_internal (parent, NULL, NULL, NULL, FALSE);
01829 }
01830
01831 void
01832 gnc_ui_new_account_with_types( AccountGroup *unused,
01833 GList *valid_types )
01834 {
01835 GList *validTypesCopy = g_list_copy( valid_types );
01836 AccountWindow *aw;
01837
01838 aw = gnc_ui_new_account_window_internal( NULL, NULL, validTypesCopy, NULL, FALSE );
01839 if ( validTypesCopy != NULL ) {
01840
01841
01842 gtk_object_set_data_full( GTK_OBJECT(aw->dialog), "validTypesListCopy",
01843 validTypesCopy, (GDestroyNotify)g_list_free );
01844 }
01845 }
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 void
01858 gnc_ui_register_account_destroy_callback (void (*cb)(Account *))
01859 {
01860 if (!cb)
01861 return;
01862
01863 if (g_list_index (ac_destroy_cb_list, cb) == -1)
01864 ac_destroy_cb_list = g_list_append (ac_destroy_cb_list, cb);
01865
01866 return;
01867 }