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