00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00036 #include "config.h"
00037
00038 #include <gtk/gtk.h>
00039 #include <glib/gi18n.h>
00040 #include <stdio.h>
00041
00042 #include "dialog-commodity.h"
00043 #include "dialog-utils.h"
00044 #include "gnc-engine.h"
00045 #include "gnc-gtk-utils.h"
00046 #include "gnc-gui-query.h"
00047 #include "gnc-ui-util.h"
00048 #include "gnc-ui.h"
00049
00050 static QofLogModule log_module = GNC_MOD_GUI;
00051
00052 enum {
00053 SOURCE_COL_NAME = 0,
00054 SOURCE_COL_FQ_SUPPORTED,
00055 NUM_SOURCE_COLS
00056 };
00057
00058 struct select_commodity_window {
00059 GtkWidget * dialog;
00060 GtkWidget * namespace_combo;
00061 GtkWidget * commodity_combo;
00062 GtkWidget * select_user_prompt;
00063 GtkWidget * ok_button;
00064
00065 gnc_commodity * selection;
00066
00067 const char * default_cusip;
00068 const char * default_fullname;
00069 const char * default_mnemonic;
00070 int default_fraction;
00071 };
00072
00073 struct commodity_window {
00074 GtkWidget * dialog;
00075 GtkWidget * table;
00076 GtkWidget * fullname_entry;
00077 GtkWidget * mnemonic_entry;
00078 GtkWidget * namespace_combo;
00079 GtkWidget * code_entry;
00080 GtkWidget * fraction_spinbutton;
00081 GtkWidget * get_quote_check;
00082 GtkWidget * source_label;
00083 GtkWidget * source_button[SOURCE_MAX];
00084 GtkWidget * source_menu[SOURCE_MAX];
00085 GtkWidget * quote_tz_label;
00086 GtkWidget * quote_tz_menu;
00087 GtkWidget * ok_button;
00088
00089 guint comm_section_top;
00090 guint comm_section_bottom;
00091 guint fq_section_top;
00092 guint fq_section_bottom;
00093
00094 gboolean is_currency;
00095 gnc_commodity *edit_commodity;
00096 };
00097
00098 typedef struct select_commodity_window SelectCommodityWindow;
00099 typedef struct commodity_window CommodityWindow;
00100
00101 static gnc_commodity_help_callback help_callback = NULL;
00102
00103
00104
00105 static SelectCommodityWindow *
00106 gnc_ui_select_commodity_create(const gnc_commodity * orig_sel,
00107 dialog_commodity_mode mode);
00108 void gnc_ui_select_commodity_new_cb(GtkButton * button,
00109 gpointer user_data);
00110 void gnc_ui_select_commodity_changed_cb(GtkComboBoxEntry *cbe,
00111 gpointer user_data);
00112 void gnc_ui_select_commodity_namespace_changed_cb(GtkComboBoxEntry *cbe,
00113 gpointer user_data);
00114
00115
00116 void gnc_ui_commodity_changed_cb(GtkWidget * dummy, gpointer user_data);
00117 void gnc_ui_commodity_quote_info_cb(GtkWidget *w, gpointer data);
00118 gboolean gnc_ui_commodity_dialog_to_object(CommodityWindow * w);
00119
00120 #if 0
00121 static void gnc_ui_select_commodity_response_cb (GtkDialog * dialog, gint response, gpointer data);
00122 #endif
00123
00124
00125
00126
00127
00128
00129 void
00130 gnc_ui_commodity_set_help_callback (gnc_commodity_help_callback cb)
00131 {
00132 help_callback = cb;
00133 }
00134
00135
00136
00137
00138
00139 gnc_commodity *
00140 gnc_ui_select_commodity_modal_full(gnc_commodity * orig_sel,
00141 GtkWidget * parent,
00142 dialog_commodity_mode mode,
00143 const char * user_message,
00144 const char * cusip,
00145 const char * fullname,
00146 const char * mnemonic)
00147 {
00148 gnc_commodity * retval = NULL;
00149 const gchar *initial;
00150 gchar *user_prompt_text;
00151 SelectCommodityWindow * win;
00152 gboolean done;
00153 gint value;
00154
00155 win = gnc_ui_select_commodity_create(orig_sel, mode);
00156 win->default_cusip=cusip;
00157 win->default_fullname=fullname;
00158 win->default_mnemonic=mnemonic;
00159
00160 if (parent)
00161 gtk_window_set_transient_for (GTK_WINDOW (win->dialog), GTK_WINDOW (parent));
00162
00163 if (user_message != NULL)
00164 initial = user_message;
00165 else if ((cusip != NULL) || (fullname != NULL) || (mnemonic != NULL))
00166 initial = _("\nPlease select a commodity to match:");
00167 else
00168 initial = "";
00169
00170 user_prompt_text =
00171 g_strdup_printf("%s%s%s%s%s%s%s",
00172 initial,
00173 fullname ? _("\nCommodity: ") : "",
00174 fullname ? fullname : "",
00175 cusip ? _("\nExchange code (CUSIP or similar): ") : "",
00176 cusip ? cusip : "",
00177 mnemonic ? _("\nMnemonic(Ticker symbol or similar): ") : "",
00178 mnemonic ? mnemonic : "");
00179 gtk_label_set_text ((GtkLabel *)(win->select_user_prompt),
00180 user_prompt_text);
00181 g_free(user_prompt_text);
00182
00183
00184 done = FALSE;
00185 while (!done) {
00186 switch (value = gtk_dialog_run(GTK_DIALOG(win->dialog))) {
00187 case GTK_RESPONSE_OK:
00188 DEBUG("case OK");
00189 retval = win->selection;
00190 done = TRUE;
00191 break;
00192 case GNC_RESPONSE_NEW:
00193 DEBUG("case NEW");
00194 gnc_ui_select_commodity_new_cb(NULL, win);
00195 break;
00196 default:
00197 DEBUG("default: %d", value);
00198 retval = NULL;
00199 done = TRUE;
00200 break;
00201 }
00202 }
00203 gtk_widget_destroy (GTK_WIDGET (win->dialog));
00204 g_free(win);
00205
00206 return retval;
00207 }
00208
00209
00210
00211
00212
00213 gnc_commodity *
00214 gnc_ui_select_commodity_modal(gnc_commodity * orig_sel,
00215 GtkWidget * parent,
00216 dialog_commodity_mode mode)
00217 {
00218 return gnc_ui_select_commodity_modal_full(orig_sel,
00219 parent,
00220 mode,
00221 NULL,
00222 NULL,
00223 NULL,
00224 NULL);
00225 }
00226
00227
00228
00229
00230
00231
00232 static SelectCommodityWindow *
00233 gnc_ui_select_commodity_create(const gnc_commodity * orig_sel,
00234 dialog_commodity_mode mode)
00235 {
00236 SelectCommodityWindow * retval = g_new0(SelectCommodityWindow, 1);
00237 GladeXML *xml;
00238 const char *title, *text;
00239 gchar *namespace;
00240 GtkWidget *button, *label;
00241
00242 xml = gnc_glade_xml_new ("commodity.glade", "Security Selector Dialog");
00243 glade_xml_signal_autoconnect_full( xml,
00244 gnc_glade_autoconnect_full_func,
00245 retval );
00246
00247 retval->dialog = glade_xml_get_widget (xml, "Security Selector Dialog");
00248 retval->namespace_combo = glade_xml_get_widget (xml, "namespace_cbe");
00249 retval->commodity_combo = glade_xml_get_widget (xml, "commodity_cbe");
00250 retval->select_user_prompt = glade_xml_get_widget (xml, "select_user_prompt");
00251 retval->ok_button = glade_xml_get_widget (xml, "ok_button");
00252 label = glade_xml_get_widget (xml, "item_label");
00253
00254 gtk_combo_box_remove_text(GTK_COMBO_BOX(retval->namespace_combo), 0);
00255 gtk_combo_box_remove_text(GTK_COMBO_BOX(retval->commodity_combo), 0);
00256 gnc_cbe_require_list_item(GTK_COMBO_BOX_ENTRY(retval->namespace_combo));
00257 gnc_cbe_require_list_item(GTK_COMBO_BOX_ENTRY(retval->commodity_combo));
00258
00259 gtk_label_set_text (GTK_LABEL (retval->select_user_prompt), "");
00260
00261 #ifdef DRH
00262 g_signal_connect (G_OBJECT (retval->dialog), "close",
00263 G_CALLBACK (select_commodity_close), retval);
00264 g_signal_connect (G_OBJECT (retval->dialog), "response",
00265 G_CALLBACK (gnc_ui_select_commodity_response_cb), retval);
00266 #endif
00267
00268 switch (mode) {
00269 case DIAG_COMM_ALL:
00270 title = _("Select security/currency");
00271 text = _("_Security/currency:");
00272 break;
00273 case DIAG_COMM_NON_CURRENCY:
00274 title = _("Select security");
00275 text = _("_Security:");
00276 break;
00277 case DIAG_COMM_CURRENCY:
00278 default:
00279 title = _("Select currency");
00280 text = _("Cu_rrency:");
00281 button = glade_xml_get_widget (xml, "new_button");
00282 gtk_widget_destroy(button);
00283 break;
00284 }
00285 gtk_window_set_title (GTK_WINDOW(retval->dialog), title);
00286 gtk_label_set_text_with_mnemonic (GTK_LABEL(label), text);
00287
00288
00289 gnc_ui_update_namespace_picker(retval->namespace_combo,
00290 gnc_commodity_get_namespace(orig_sel),
00291 mode);
00292 namespace = gnc_ui_namespace_picker_ns(retval->namespace_combo);
00293 gnc_ui_update_commodity_picker(retval->commodity_combo, namespace,
00294 gnc_commodity_get_printname(orig_sel));
00295 g_free(namespace);
00296 return retval;
00297 }
00298
00299
00314 void
00315 gnc_ui_select_commodity_new_cb(GtkButton * button,
00316 gpointer user_data)
00317 {
00318 SelectCommodityWindow * w = user_data;
00319
00320 gchar * namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00321
00322 const gnc_commodity * new_commodity =
00323 gnc_ui_new_commodity_modal_full(namespace,
00324 w->dialog,
00325 w->default_cusip,
00326 w->default_fullname,
00327 w->default_mnemonic,
00328 w->default_fraction);
00329 if(new_commodity) {
00330 gnc_ui_update_namespace_picker(w->namespace_combo,
00331 gnc_commodity_get_namespace(new_commodity),
00332 DIAG_COMM_ALL);
00333 gnc_ui_update_commodity_picker(w->commodity_combo,
00334 gnc_commodity_get_namespace(new_commodity),
00335 gnc_commodity_get_printname(new_commodity));
00336 }
00337 g_free(namespace);
00338 }
00339
00340
00356 void
00357 gnc_ui_select_commodity_changed_cb (GtkComboBoxEntry *cbe,
00358 gpointer user_data)
00359 {
00360 SelectCommodityWindow * w = user_data;
00361 gchar *namespace, *fullname;
00362 gboolean ok;
00363
00364 ENTER("cbe=%p, user_data=%p", cbe, user_data);
00365 namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00366 fullname = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w->commodity_combo));
00367 DEBUG("namespace=%s, name=%s", namespace, fullname);
00368 w->selection = gnc_commodity_table_find_full(gnc_get_current_commodities(),
00369 namespace, fullname);
00370 g_free(fullname);
00371 g_free(namespace);
00372
00373 ok = (w->selection != NULL);
00374 gtk_widget_set_sensitive(w->ok_button, ok);
00375 gtk_dialog_set_default_response(GTK_DIALOG(w->dialog), ok ? 0 : 2);
00376 LEAVE("sensitive=%d, default = %d", ok, ok ? 0 : 2);
00377 }
00378
00379
00396 void
00397 gnc_ui_select_commodity_namespace_changed_cb (GtkComboBoxEntry *cbe,
00398 gpointer user_data)
00399 {
00400 SelectCommodityWindow * w = user_data;
00401 gchar *namespace;
00402
00403 ENTER("cbe=%p, user_data=%p", cbe, user_data);
00404 namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00405 DEBUG("namespace=%s", namespace);
00406 gnc_ui_update_commodity_picker(w->commodity_combo, namespace, NULL);
00407 g_free(namespace);
00408 LEAVE(" ");
00409 }
00410
00411
00412
00413
00414
00415 static int
00416 collate(gconstpointer a, gconstpointer b)
00417 {
00418 if (!a)
00419 return -1;
00420 if (!b)
00421 return 1;
00422 return g_utf8_collate(a, b);
00423 }
00424
00425
00426 void
00427 gnc_ui_update_commodity_picker (GtkWidget *cbe,
00428 const gchar * namespace,
00429 const gchar * init_string)
00430 {
00431 GList * commodities;
00432 GList * iterator = NULL;
00433 GList * commodity_items = NULL;
00434 GtkComboBox *combo_box;
00435 GtkTreeModel *model;
00436 gnc_commodity_table *table;
00437 gint current = 0, match = 0;
00438 gchar *name;
00439
00440 g_return_if_fail(GTK_IS_COMBO_BOX_ENTRY(cbe));
00441 g_return_if_fail(namespace);
00442
00443
00444 combo_box = GTK_COMBO_BOX(cbe);
00445 model = gtk_combo_box_get_model(combo_box);
00446 gtk_list_store_clear(GTK_LIST_STORE(model));
00447 gtk_combo_box_set_active(combo_box, -1);
00448
00449 table = gnc_book_get_commodity_table (gnc_get_current_book ());
00450 commodities = gnc_commodity_table_get_commodities(table, namespace);
00451 for(iterator = commodities; iterator; iterator = iterator->next) {
00452 commodity_items =
00453 g_list_append(commodity_items,
00454 (gpointer) gnc_commodity_get_printname(iterator->data));
00455 }
00456 g_list_free(commodities);
00457
00458 commodity_items = g_list_sort(commodity_items, collate);
00459 for (iterator = commodity_items; iterator; iterator = iterator->next) {
00460 name = (char *)iterator->data;
00461 gtk_combo_box_append_text(combo_box, name);
00462 if (init_string && g_utf8_collate(name, init_string) == 0)
00463 match = current;
00464 current++;
00465 }
00466
00467 gtk_combo_box_set_active(combo_box, match);
00468 g_list_free(commodity_items);
00469 }
00470
00471
00472
00473
00474
00475
00476 #if 0
00477 void
00478 gnc_ui_select_commodity_destroy(SelectCommodityWindow * w) {
00479 g_return_if_fail (w != NULL);
00480
00481 gtk_widget_destroy (GTK_WIDGET (w->dialog));
00482 }
00483
00484
00485
00486
00487
00488 static void
00489 gnc_ui_select_commodity_response_cb (GtkDialog * dialog, gint response, gpointer data)
00490 {
00491 SelectCommodityWindow * w = data;
00492 gchar *namespace;
00493 const gchar *fullname;
00494 gnc_commodity *commodity = NULL;
00495
00496 switch (response) {
00497 case GTK_RESPONSE_OK:
00498 namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00499 fullname = gtk_entry_get_text (GTK_ENTRY (w->commodity_entry));
00500
00501 commodity = gnc_commodity_table_find_full (gnc_get_current_commodities (),
00502 namespace, fullname);
00503 g_free(namespace);
00504
00505 if (commodity != NULL) {
00506 if (w->callback != NULL)
00507 (w->callback) (commodity, w->callback_data);
00508 gnc_ui_select_commodity_destroy (w);
00509 } else {
00510 gnc_warning_dialog (dialog,
00511 _("You must select a commodity. "
00512 "To create a new one, click \"New\""));
00513 }
00514 break;
00515 case GNC_RESPONSE_NEW:
00516 namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00517
00518 commodity = gnc_ui_new_commodity_modal_full (namespace,
00519 w->dialog,
00520 w->default_cusip,
00521 w->default_fullname,
00522 w->default_mnemonic,
00523 w->default_fraction);
00524 if (commodity != NULL) {
00525 namespace =
00526 gnc_ui_update_namespace_picker (w->namespace_combo,
00527 gnc_commodity_get_namespace
00528 (commodity), TRUE, FALSE);
00529 gnc_ui_update_commodity_picker (w->commodity_combo,
00530 gnc_commodity_get_namespace (commodity),
00531 gnc_commodity_get_printname (commodity));
00532 }
00533 g_free(namespace);
00534 break;
00535 default:
00536 if (w->callback != NULL)
00537 (w->callback) (NULL, w->callback_data);
00538
00539 gnc_ui_select_commodity_destroy (w);
00540 break;
00541 }
00542 }
00543 #endif
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 static void
00554 gnc_set_commodity_section_sensitivity (GtkWidget *widget, gpointer user_data)
00555 {
00556 CommodityWindow *cw = user_data;
00557 guint offset = 0;
00558
00559 gtk_container_child_get(GTK_CONTAINER(cw->table), widget,
00560 "top-attach", &offset,
00561 NULL);
00562
00563 if ((offset < cw->comm_section_top) || (offset >= cw->comm_section_bottom))
00564 return;
00565 gtk_widget_set_sensitive(widget, !cw->is_currency);
00566 }
00567
00568 static void
00569 gnc_ui_update_commodity_info (CommodityWindow *cw)
00570 {
00571 gtk_container_foreach(GTK_CONTAINER(cw->table),
00572 gnc_set_commodity_section_sensitivity, cw);
00573 }
00574
00575 static void
00576 gnc_set_fq_sensitivity (GtkWidget *widget, gpointer user_data)
00577 {
00578 CommodityWindow *cw = user_data;
00579 guint offset = 0;
00580
00581 gtk_container_child_get(GTK_CONTAINER(cw->table), widget,
00582 "top-attach", &offset,
00583 NULL);
00584
00585 if ((offset < cw->fq_section_top) || (offset >= cw->fq_section_bottom))
00586 return;
00587 g_object_set(widget, "sensitive", FALSE, NULL);
00588 }
00589
00590 static void
00591 gnc_ui_update_fq_info (CommodityWindow *cw)
00592 {
00593 gtk_container_foreach(GTK_CONTAINER(cw->table),
00594 gnc_set_fq_sensitivity, cw);
00595 }
00596
00597
00598
00599
00600
00601 void
00602 gnc_ui_update_namespace_picker (GtkWidget *cbe,
00603 const char * init_string,
00604 dialog_commodity_mode mode)
00605 {
00606 GtkComboBox *combo_box;
00607 GtkTreeModel *model;
00608 GList *namespaces, *node;
00609 gint current = 0, match = 0;
00610
00611 g_return_if_fail(GTK_IS_COMBO_BOX_ENTRY(cbe));
00612
00613
00614 combo_box = GTK_COMBO_BOX(cbe);
00615 model = gtk_combo_box_get_model(combo_box);
00616 gtk_list_store_clear(GTK_LIST_STORE(model));
00617 gtk_combo_box_set_active(combo_box, -1);
00618
00619
00620 switch (mode) {
00621 case DIAG_COMM_ALL:
00622 namespaces =
00623 gnc_commodity_table_get_namespaces (gnc_get_current_commodities());
00624 break;
00625
00626 case DIAG_COMM_NON_CURRENCY:
00627 namespaces =
00628 gnc_commodity_table_get_namespaces (gnc_get_current_commodities());
00629 node = g_list_find_custom (namespaces, GNC_COMMODITY_NS_CURRENCY, collate);
00630 if (node) {
00631 namespaces = g_list_remove_link (namespaces, node);
00632 g_list_free_1 (node);
00633 }
00634
00635 if (gnc_commodity_namespace_is_iso (init_string))
00636 init_string = NULL;
00637 break;
00638
00639 case DIAG_COMM_CURRENCY:
00640 default:
00641 namespaces = g_list_prepend (NULL, GNC_COMMODITY_NS_CURRENCY);
00642 break;
00643 }
00644
00645
00646 namespaces = g_list_sort(namespaces, collate);
00647 for (node = namespaces; node; node = node->next) {
00648 if (g_utf8_collate(node->data, GNC_COMMODITY_NS_LEGACY) == 0)
00649 continue;
00650 gtk_combo_box_append_text(combo_box, node->data);
00651 if (init_string && (g_utf8_collate(node->data, init_string) == 0))
00652 match = current;
00653 current++;
00654 }
00655
00656 gtk_combo_box_set_active(combo_box, match);
00657 g_list_free(namespaces);
00658 }
00659
00660 gchar *
00661 gnc_ui_namespace_picker_ns (GtkWidget *cbe)
00662 {
00663 char *namespace;
00664
00665 g_return_val_if_fail(GTK_IS_COMBO_BOX_ENTRY (cbe), NULL);
00666
00667 namespace = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cbe));
00668
00669 if (safe_strcmp (namespace, GNC_COMMODITY_NS_ISO) == 0) {
00670
00671 g_free(namespace);
00672 return strdup(GNC_COMMODITY_NS_CURRENCY);
00673 } else
00674 return namespace;
00675 }
00676
00677
00678
00679 void
00680 gnc_ui_commodity_quote_info_cb (GtkWidget *w, gpointer data)
00681 {
00682 CommodityWindow *cw = data;
00683 gboolean get_quote, allow_src, active;
00684 gchar *text;
00685 gint i;
00686
00687 ENTER(" ");
00688 get_quote = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
00689
00690 text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw->namespace_combo));
00691 allow_src = !gnc_commodity_namespace_is_iso(text);
00692 g_free(text);
00693 gtk_widget_set_sensitive(cw->source_label, get_quote && allow_src);
00694
00695 for (i = SOURCE_SINGLE; i < SOURCE_MAX; i++) {
00696 if (!cw->source_button[i])
00697 continue;
00698 active =
00699 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw->source_button[i]));
00700 gtk_widget_set_sensitive(cw->source_button[i], get_quote && allow_src);
00701 gtk_widget_set_sensitive(cw->source_menu[i], get_quote && allow_src && active);
00702 }
00703 gtk_widget_set_sensitive(cw->quote_tz_label, get_quote);
00704 gtk_widget_set_sensitive(cw->quote_tz_menu, get_quote);
00705 LEAVE(" ");
00706 }
00707
00708 void
00709 gnc_ui_commodity_changed_cb(GtkWidget * dummy, gpointer user_data)
00710 {
00711 CommodityWindow * w = user_data;
00712 gchar *namespace;
00713 const char * fullname;
00714 const char * mnemonic;
00715 gboolean ok;
00716
00717 ENTER("widget=%p, user_data=%p", dummy, user_data);
00718 if (!w->is_currency) {
00719 namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
00720 fullname = gtk_entry_get_text(GTK_ENTRY(w->fullname_entry));
00721 mnemonic = gtk_entry_get_text(GTK_ENTRY(w->mnemonic_entry));
00722 DEBUG("namespace=%s, name=%s, mnemonic=%s", namespace, fullname, mnemonic);
00723 ok = (fullname && namespace && mnemonic &&
00724 fullname[0] && namespace[0] && mnemonic[0]);
00725 g_free(namespace);
00726 } else {
00727 ok = TRUE;
00728 }
00729 gtk_widget_set_sensitive(w->ok_button, ok);
00730 gtk_dialog_set_default_response(GTK_DIALOG(w->dialog), ok ? 0 : 1);
00731 LEAVE("sensitive=%d, default = %d", ok, ok ? 0 : 1);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 static GtkWidget *
00742 gnc_ui_source_menu_create(QuoteSourceType type)
00743 {
00744 gint i, max;
00745 const gchar *name;
00746 gboolean supported;
00747 GtkListStore *store;
00748 GtkTreeIter iter;
00749 GtkWidget *combo;
00750 GtkCellRenderer *renderer;
00751 gnc_quote_source *source;
00752
00753 store = gtk_list_store_new(NUM_SOURCE_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN);
00754 if (type == SOURCE_CURRENCY) {
00755 gtk_list_store_append(store, &iter);
00756 gtk_list_store_set(store, &iter,
00757 SOURCE_COL_NAME, _("Currency"),
00758 SOURCE_COL_FQ_SUPPORTED, TRUE,
00759 -1);
00760 } else {
00761 max = gnc_quote_source_num_entries(type);
00762 for (i = 0; i < max; i++) {
00763 source = gnc_quote_source_lookup_by_ti(type, i);
00764 if (source == NULL)
00765 break;
00766 name = gnc_quote_source_get_user_name(source);
00767 supported = gnc_quote_source_get_supported(source);
00768 gtk_list_store_append(store, &iter);
00769 gtk_list_store_set(store, &iter,
00770 SOURCE_COL_NAME, name,
00771 SOURCE_COL_FQ_SUPPORTED, supported,
00772 -1);
00773 }
00774 }
00775
00776 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
00777 g_object_unref(store);
00778 renderer = gtk_cell_renderer_text_new();
00779 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
00780 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
00781 "text", SOURCE_COL_NAME);
00782 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
00783 "sensitive", SOURCE_COL_FQ_SUPPORTED);
00784 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
00785 gtk_widget_show(combo);
00786 return combo;
00787 }
00788
00789
00790
00791
00792
00793 static gchar *
00794 known_timezones[] =
00795 {
00796 "Asia/Tokyo",
00797 "Australia/Sydney",
00798 "America/New_York",
00799 "America/Chicago",
00800 "Europe/London",
00801 "Europe/Paris",
00802 NULL
00803 };
00804
00805 static guint
00806 gnc_find_timezone_menu_position(const gchar *timezone)
00807 {
00808
00809 gboolean found = FALSE;
00810 guint i = 0;
00811 while(!found && known_timezones[i]) {
00812 if(safe_strcmp(timezone, known_timezones[i]) != 0) {
00813 i++;
00814 } else {
00815 found = TRUE;
00816 }
00817 }
00818 if(found) return i + 1;
00819 return 0;
00820 }
00821
00822 static gchar *
00823 gnc_timezone_menu_position_to_string(guint pos)
00824 {
00825 if(pos == 0) return NULL;
00826 return known_timezones[pos - 1];
00827 }
00828
00829 static GtkWidget *
00830 gnc_ui_quote_tz_menu_create(void)
00831 {
00832 GtkWidget *combo;
00833 gchar **itemstr;
00834
00835
00836
00837
00838
00839
00840
00841 combo = gtk_combo_box_new_text();
00842 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Use local time"));
00843 for(itemstr = &known_timezones[0]; *itemstr; itemstr++) {
00844 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), *itemstr);
00845 }
00846
00847 gtk_widget_show(combo);
00848 return combo;
00849 }
00850
00853 static CommodityWindow *
00854 gnc_ui_build_commodity_dialog(const char * selected_namespace,
00855 GtkWidget *parent,
00856 const char * fullname,
00857 const char * mnemonic,
00858 const char * cusip,
00859 int fraction,
00860 gboolean edit)
00861 {
00862 CommodityWindow * retval = g_new0(CommodityWindow, 1);
00863 GtkWidget *help_button;
00864 GtkWidget *box;
00865 GtkWidget *menu;
00866 GtkWidget *widget, *sec_label;
00867 GladeXML *xml;
00868 gboolean include_iso;
00869 const gchar *title;
00870 gchar *text;
00871
00872 ENTER(" ");
00873 xml = gnc_glade_xml_new ("commodity.glade", "Security Dialog");
00874
00875 glade_xml_signal_autoconnect_full( xml,
00876 gnc_glade_autoconnect_full_func,
00877 retval );
00878
00879 retval->dialog = glade_xml_get_widget (xml, "Security Dialog");
00880 if (parent != NULL)
00881 gtk_window_set_transient_for (GTK_WINDOW (retval->dialog), GTK_WINDOW (parent));
00882 retval->edit_commodity = NULL;
00883
00884 help_button = glade_xml_get_widget (xml, "help_button");
00885 if (!help_callback)
00886 gtk_widget_hide (help_button);
00887
00888
00889 retval->table = glade_xml_get_widget (xml, "edit_table");
00890 sec_label = glade_xml_get_widget (xml, "security_label");
00891 gtk_container_child_get(GTK_CONTAINER(retval->table), sec_label,
00892 "bottom-attach", &retval->comm_section_top, NULL);
00893 widget = glade_xml_get_widget (xml, "quote_label");
00894 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
00895 "top-attach", &retval->comm_section_bottom, NULL);
00896
00897
00898 retval->fullname_entry = glade_xml_get_widget (xml, "fullname_entry");
00899 retval->mnemonic_entry = glade_xml_get_widget (xml, "mnemonic_entry");
00900 retval->namespace_combo = glade_xml_get_widget (xml, "namespace_cbe");
00901 retval->code_entry = glade_xml_get_widget (xml, "code_entry");
00902 retval->fraction_spinbutton = glade_xml_get_widget (xml,
00903 "fraction_spinbutton");
00904 retval->ok_button = glade_xml_get_widget (xml, "ok_button");
00905 retval->get_quote_check = glade_xml_get_widget (xml, "get_quote_check");
00906 retval->source_label = glade_xml_get_widget (xml, "source_label");
00907 retval->source_button[SOURCE_SINGLE] = glade_xml_get_widget (xml, "single_source_button");
00908 retval->source_button[SOURCE_MULTI] = glade_xml_get_widget (xml, "multi_source_button");
00909 retval->quote_tz_label = glade_xml_get_widget (xml, "quote_tz_label");
00910
00911
00912
00913 box = glade_xml_get_widget (xml, "single_source_box");
00914 if (gnc_commodity_namespace_is_iso(selected_namespace)) {
00915 menu = gnc_ui_source_menu_create(SOURCE_CURRENCY);
00916 } else {
00917 menu = gnc_ui_source_menu_create(SOURCE_SINGLE);
00918 }
00919 retval->source_menu[SOURCE_SINGLE] = menu;
00920 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
00921
00922 box = glade_xml_get_widget (xml, "multi_source_box");
00923 menu = gnc_ui_source_menu_create(SOURCE_MULTI);
00924 retval->source_menu[SOURCE_MULTI] = menu;
00925 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
00926
00927 if (gnc_quote_source_num_entries(SOURCE_UNKNOWN)) {
00928 retval->source_button[SOURCE_UNKNOWN] =
00929 glade_xml_get_widget (xml, "unknown_source_button");
00930 box = glade_xml_get_widget (xml, "unknown_source_box");
00931 menu = gnc_ui_source_menu_create(SOURCE_UNKNOWN);
00932 retval->source_menu[SOURCE_UNKNOWN] = menu;
00933 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
00934 } else {
00935 guint row;
00936
00937 widget = glade_xml_get_widget (xml, "unknown_source_alignment");
00938 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
00939 "top-attach", &row, NULL);
00940 gtk_table_set_row_spacing(GTK_TABLE(retval->table), row, 0);
00941 gtk_widget_destroy(widget);
00942 widget = glade_xml_get_widget (xml, "unknown_source_box");
00943 gtk_widget_destroy(widget);
00944 }
00945
00946 box = glade_xml_get_widget (xml, "quote_tz_box");
00947 retval->quote_tz_menu = gnc_ui_quote_tz_menu_create();
00948 gtk_box_pack_start(GTK_BOX(box), retval->quote_tz_menu, TRUE, TRUE, 0);
00949
00950
00951
00952 if (gnc_commodity_namespace_is_iso(selected_namespace)) {
00953 retval->is_currency = TRUE;
00954 gnc_ui_update_commodity_info (retval);
00955 include_iso = TRUE;
00956 title = _("Edit currency");
00957 text = g_strdup_printf("<b>%s</b>", _("Currency Information"));
00958 } else {
00959 include_iso = FALSE;
00960 title = edit ? _("Edit security") : _("New security");
00961 text = g_strdup_printf("<b>%s</b>", _("Security Information"));
00962 }
00963 gtk_window_set_title(GTK_WINDOW(retval->dialog), title);
00964 gtk_label_set_markup(GTK_LABEL(sec_label), text);
00965 g_free(text);
00966
00967
00968 if (gnc_quote_source_fq_installed()) {
00969 gtk_widget_destroy(glade_xml_get_widget (xml, "finance_quote_warning"));
00970 } else {
00971
00972 widget = glade_xml_get_widget (xml, "fq_warning_alignment");
00973 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
00974 "bottom-attach", &retval->fq_section_top, NULL);
00975 widget = glade_xml_get_widget (xml, "quote_tz_alignment");
00976 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
00977 "bottom-attach", &retval->fq_section_bottom, NULL);
00978 gnc_ui_update_fq_info (retval);
00979 }
00980
00981
00982 #ifdef DRH
00983 g_signal_connect (G_OBJECT (retval->dialog), "close",
00984 G_CALLBACK (commodity_close), retval);
00985 #endif
00986
00987
00988 gtk_entry_set_text (GTK_ENTRY (retval->fullname_entry), fullname ? fullname : "");
00989 gtk_entry_set_text (GTK_ENTRY (retval->mnemonic_entry), mnemonic ? mnemonic : "");
00990 gnc_cbe_add_completion(GTK_COMBO_BOX_ENTRY(retval->namespace_combo));
00991 gtk_combo_box_remove_text(GTK_COMBO_BOX(retval->namespace_combo), 0);
00992 gnc_ui_update_namespace_picker(retval->namespace_combo,
00993 selected_namespace,
00994 include_iso ? DIAG_COMM_ALL : DIAG_COMM_NON_CURRENCY);
00995 gtk_entry_set_text (GTK_ENTRY (retval->code_entry), cusip ? cusip : "");
00996 if (fraction > 0)
00997 gtk_spin_button_set_value (GTK_SPIN_BUTTON (retval->fraction_spinbutton),
00998 fraction);
00999
01000 LEAVE(" ");
01001 return retval;
01002 }
01003
01004
01005 static void
01006 gnc_ui_commodity_update_quote_info(CommodityWindow *win,
01007 gnc_commodity *commodity)
01008 {
01009 gnc_quote_source *source;
01010 QuoteSourceType type;
01011 gboolean has_quote_src;
01012 const char *quote_tz;
01013 int pos = 0;
01014
01015 ENTER(" ");
01016 has_quote_src = gnc_commodity_get_quote_flag (commodity);
01017 source = gnc_commodity_get_quote_source (commodity);
01018 if (source == NULL)
01019 source = gnc_commodity_get_default_quote_source (commodity);
01020 quote_tz = gnc_commodity_get_quote_tz (commodity);
01021
01022 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (win->get_quote_check),
01023 has_quote_src);
01024 if (!gnc_commodity_is_iso(commodity)) {
01025 type = gnc_quote_source_get_type(source);
01026 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->source_button[type]), TRUE);
01027 gtk_combo_box_set_active(GTK_COMBO_BOX(win->source_menu[type]),
01028 gnc_quote_source_get_index(source));
01029 }
01030
01031 if (quote_tz) {
01032 pos = gnc_find_timezone_menu_position(quote_tz);
01033
01034
01035
01036
01037 }
01038 gtk_combo_box_set_active(GTK_COMBO_BOX(win->quote_tz_menu), pos);
01039 LEAVE(" ");
01040 }
01041
01042
01043 static gnc_commodity *
01044 gnc_ui_common_commodity_modal(gnc_commodity *commodity,
01045 GtkWidget * parent,
01046 const char * namespace,
01047 const char * cusip,
01048 const char * fullname,
01049 const char * mnemonic,
01050 int fraction)
01051 {
01052 CommodityWindow * win;
01053 gnc_commodity *retval = NULL;
01054 gboolean done;
01055 gint value;
01056
01057 ENTER(" ");
01058
01059
01060 if (commodity) {
01061 namespace = gnc_commodity_get_namespace (commodity);
01062 fullname = gnc_commodity_get_fullname (commodity);
01063 mnemonic = gnc_commodity_get_mnemonic (commodity);
01064 cusip = gnc_commodity_get_cusip (commodity);
01065 fraction = gnc_commodity_get_fraction (commodity);
01066 } else {
01067
01068 if (gnc_commodity_namespace_is_iso(namespace)) {
01069 namespace = NULL;
01070 }
01071 }
01072
01073 win = gnc_ui_build_commodity_dialog(namespace, parent, fullname,
01074 mnemonic, cusip, fraction,
01075 (commodity != NULL));
01076
01077
01078 gnc_ui_commodity_update_quote_info(win, commodity);
01079 win->edit_commodity = commodity;
01080
01081
01082 gnc_ui_commodity_quote_info_cb(win->get_quote_check, win);
01083
01084
01085 done = FALSE;
01086 while (!done) {
01087 value = gtk_dialog_run(GTK_DIALOG(win->dialog));
01088 switch (value) {
01089 case GTK_RESPONSE_OK:
01090 DEBUG("case OK");
01091 done = gnc_ui_commodity_dialog_to_object(win);
01092 retval = win->edit_commodity;
01093 break;
01094 case GTK_RESPONSE_HELP:
01095 DEBUG("case HELP");
01096 if (help_callback)
01097 help_callback ();
01098 break;
01099 default:
01100 DEBUG("default: %d", value);
01101 retval = NULL;
01102 done = TRUE;
01103 break;
01104 }
01105 }
01106 gtk_widget_destroy (GTK_WIDGET (win->dialog));
01107 g_free(win);
01108
01109 LEAVE(" ");
01110 return retval;
01111 }
01112
01113
01114
01117 gnc_commodity *
01118 gnc_ui_new_commodity_modal_full(const char * namespace,
01119 GtkWidget * parent,
01120 const char * cusip,
01121 const char * fullname,
01122 const char * mnemonic,
01123 int fraction)
01124 {
01125 gnc_commodity *result;
01126
01127 ENTER(" ");
01128 result = gnc_ui_common_commodity_modal(NULL, parent, namespace, cusip,
01129 fullname, mnemonic, 10000);
01130 LEAVE(" ");
01131 return result;
01132 }
01133
01136 gnc_commodity *
01137 gnc_ui_new_commodity_modal(const char * default_namespace,
01138 GtkWidget * parent)
01139 {
01140 gnc_commodity *result;
01141
01142 ENTER(" ");
01143 result = gnc_ui_common_commodity_modal(NULL, parent, default_namespace, NULL,
01144 NULL, NULL, 0);
01145 LEAVE(" ");
01146 return result;
01147 }
01148
01149
01150
01151
01152
01158 gboolean
01159 gnc_ui_edit_commodity_modal(gnc_commodity *commodity,
01160 GtkWidget * parent)
01161 {
01162 gnc_commodity *result;
01163
01164 ENTER(" ");
01165 result = gnc_ui_common_commodity_modal(commodity, parent, NULL, NULL,
01166 NULL, NULL, 0);
01167 LEAVE(" ");
01168 return result != NULL;
01169 }
01170
01171
01172
01173
01174
01175
01176 gboolean
01177 gnc_ui_commodity_dialog_to_object(CommodityWindow * w)
01178 {
01179 gnc_quote_source *source;
01180 QuoteSourceType type;
01181 const char * fullname = gtk_entry_get_text(GTK_ENTRY(w->fullname_entry));
01182 gchar *namespace = gnc_ui_namespace_picker_ns (w->namespace_combo);
01183 const char * mnemonic = gtk_entry_get_text(GTK_ENTRY(w->mnemonic_entry));
01184 const char * code = gtk_entry_get_text(GTK_ENTRY(w->code_entry));
01185 QofBook * book = gnc_get_current_book ();
01186 int fraction = gtk_spin_button_get_value_as_int
01187 (GTK_SPIN_BUTTON(w->fraction_spinbutton));
01188 const char *string;
01189 gnc_commodity * c;
01190 gint selection;
01191
01192 ENTER(" ");
01193
01194 if (gnc_commodity_namespace_is_iso (namespace)) {
01195 if (w->edit_commodity) {
01196 c = w->edit_commodity;
01197 gnc_commodity_begin_edit(c);
01198 gnc_commodity_user_set_quote_flag (c, gtk_toggle_button_get_active
01199 (GTK_TOGGLE_BUTTON (w->get_quote_check)));
01200 selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->quote_tz_menu));
01201 string = gnc_timezone_menu_position_to_string(selection);
01202 gnc_commodity_set_quote_tz(c, string);
01203 gnc_commodity_commit_edit(c);
01204 return TRUE;
01205 }
01206 gnc_warning_dialog(w->dialog,
01207 _("You may not create a new national currency."));
01208 return FALSE;
01209 }
01210
01211 if(fullname && fullname[0] &&
01212 namespace && namespace[0] &&
01213 mnemonic && mnemonic[0]) {
01214 c = gnc_commodity_table_lookup (gnc_get_current_commodities(),
01215 namespace, mnemonic);
01216
01217 if ((!w->edit_commodity && c) ||
01218 (w->edit_commodity && c && (c != w->edit_commodity))) {
01219 gnc_warning_dialog (w->dialog, _("That commodity already exists."));
01220 g_free(namespace);
01221 return