GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-commodity.cpp
1/********************************************************************
2 * dialog-commodity.c -- "select" and "new" commodity windows *
3 * (GnuCash) *
4 * Copyright (C) 2000 Bill Gribble <grib@billgribble.com> *
5 * Copyright (c) 2006 David Hampton <hampton@employees.org> *
6 * Copyright (c) 2011 Robert Fewell *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation; either version 2 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License*
19 * along with this program; if not, contact: *
20 * *
21 * Free Software Foundation Voice: +1-617-542-5942 *
22 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
23 * Boston, MA 02110-1301, USA gnu@gnu.org *
24 ********************************************************************/
25
37#include <config.h>
38
39#include <gtk/gtk.h>
40#include <glib/gi18n.h>
41#include <stdio.h>
42
43#include "dialog-commodity.h"
44#include "dialog-utils.h"
45#include "gnc-engine.h"
46#include "gnc-gtk-utils.h"
47#include "gnc-gui-query.h"
48#include "gnc-ui-util.h"
49#include "gnc-ui.h"
50
51/* This static indicates the debugging module that this .o belongs to. */
52static QofLogModule log_module = GNC_MOD_GUI;
53
54enum
55{
56 SOURCE_COL_NAME = 0,
57 SOURCE_COL_FQ_SUPPORTED,
58 NUM_SOURCE_COLS
59};
60
62{
63 GtkWidget * dialog;
64 GtkWidget * namespace_combo;
65 GtkWidget * commodity_combo;
66 GtkWidget * select_user_prompt;
67 GtkWidget * ok_button;
68
69 gnc_commodity * selection;
70
71 const char * default_cusip;
72 const char * default_fullname;
73 const char * default_mnemonic;
74 const char * default_user_symbol;
75 int default_fraction;
76};
77
79{
80 GtkWidget * dialog;
81 GtkWidget * table;
82 GtkWidget * fullname_entry;
83 GtkWidget * mnemonic_entry;
84 GtkWidget * user_symbol_entry;
85 GtkWidget * namespace_combo;
86 GtkWidget * code_entry;
87 GtkWidget * fraction_spinbutton;
88 GtkWidget * get_quote_check;
89 GtkWidget * source_label;
90 GtkWidget * source_button[SOURCE_MAX];
91 GtkWidget * source_menu[SOURCE_MAX];
92 GtkWidget * quote_tz_label;
93 GtkWidget * quote_tz_menu;
94 GtkWidget * ok_button;
95
96 guint comm_section_top;
97 guint comm_section_bottom;
98 guint comm_symbol_line;
99 guint fq_section_top;
100 guint fq_section_bottom;
101
102 gboolean is_currency;
103 gnc_commodity *edit_commodity;
104};
105
106typedef struct select_commodity_window SelectCommodityWindow;
107typedef struct commodity_window CommodityWindow;
108
109/* The commodity selection window */
110static SelectCommodityWindow *
111gnc_ui_select_commodity_create(const gnc_commodity * orig_sel,
113void gnc_ui_select_commodity_new_cb(GtkButton * button,
114 gpointer user_data);
115extern "C" {
116void gnc_ui_select_commodity_changed_cb(GtkComboBox *cbwe,
117 gpointer user_data);
119 gpointer user_data);
120
121/* The commodity creation window */
122void gnc_ui_commodity_changed_cb(GtkWidget * dummy, gpointer user_data);
123void gnc_ui_commodity_quote_info_cb(GtkWidget *w, gpointer data);
124}
125gboolean gnc_ui_commodity_dialog_to_object(CommodityWindow * w);
126
127#if 0
128static void gnc_ui_select_commodity_response_cb (GtkDialog * dialog, gint response, gpointer data);
129#endif
130
131/********************************************************************
132 * gnc_ui_select_commodity_modal_full()
133 ********************************************************************/
134gnc_commodity *
135gnc_ui_select_commodity_modal_full(gnc_commodity * orig_sel,
136 GtkWidget * parent,
138 const char * user_message,
139 const char * cusip,
140 const char * fullname,
141 const char * mnemonic)
142{
143 gnc_commodity * retval = nullptr;
144 const gchar *initial;
145 gchar *user_prompt_text;
146 SelectCommodityWindow * win;
147 gboolean done;
148 gint value;
149
150 win = gnc_ui_select_commodity_create(orig_sel, mode);
151 win->default_cusip = cusip;
152 win->default_fullname = fullname;
153 win->default_mnemonic = mnemonic;
154 win->default_user_symbol = "";
155
156 if (parent)
157 gtk_window_set_transient_for (GTK_WINDOW (win->dialog), GTK_WINDOW (parent));
158
159 if (user_message != nullptr)
160 initial = user_message;
161 else if ((cusip != nullptr) || (fullname != nullptr) || (mnemonic != nullptr))
162 initial = _("\nPlease select a commodity to match");
163 else
164 initial = "";
165
166 user_prompt_text =
167 g_strdup_printf("%s%s%s%s%s%s%s",
168 initial,
169 fullname ? _("\nCommodity: ") : "",
170 fullname ? fullname : "",
171 /* Translators: Replace here and later CUSIP by the name of your local
172 National Securities Identifying Number
173 like gb:SEDOL, de:WKN, ch:Valorennummer, fr:SICOVAM ...
174 See https://en.wikipedia.org/wiki/ISIN and
175 https://en.wikipedia.org/wiki/National_numbering_agency for hints. */
176 cusip ? _("\nExchange code (ISIN, CUSIP or similar): ") : "",
177 cusip ? cusip : "",
178 mnemonic ? _("\nMnemonic (Ticker symbol or similar): ") : "",
179 mnemonic ? mnemonic : "");
180 gtk_label_set_text ((GtkLabel *)(win->select_user_prompt),
181 user_prompt_text);
182 g_free(user_prompt_text);
183
184 /* Run the dialog, handling the terminal conditions. */
185 done = FALSE;
186 while (!done)
187 {
188 switch (value = gtk_dialog_run(GTK_DIALOG(win->dialog)))
189 {
190 case GTK_RESPONSE_OK:
191 DEBUG("case OK");
192 retval = win->selection;
193 done = TRUE;
194 break;
195 case GNC_RESPONSE_NEW:
196 DEBUG("case NEW");
197 gnc_ui_select_commodity_new_cb (nullptr, win);
198 break;
199 default: /* Cancel, Escape, Close, etc. */
200 DEBUG("default: %d", value);
201 retval = nullptr;
202 done = TRUE;
203 break;
204 }
205 }
206 gtk_widget_destroy (GTK_WIDGET (win->dialog)); /* Close and destroy */
207 g_free(win);
208
209 return retval;
210}
211
212
213/********************************************************************
214 * gnc_ui_select_commodity_modal()
215 ********************************************************************/
216gnc_commodity *
217gnc_ui_select_commodity_modal(gnc_commodity * orig_sel,
218 GtkWidget * parent,
220{
222 parent,
223 mode,
224 nullptr,
225 nullptr,
226 nullptr,
227 nullptr);
228}
229
230
231/********************************************************************
232 * gnc_ui_select_commodity_create()
233 ********************************************************************/
234static SelectCommodityWindow *
235gnc_ui_select_commodity_create(const gnc_commodity * orig_sel,
237{
238 SelectCommodityWindow * retval = g_new0(SelectCommodityWindow, 1);
239 GtkBuilder *builder;
240 const char *title, *text;
241 gchar *name_space;
242 GtkWidget *button, *label;
243
244 builder = gtk_builder_new();
245 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "liststore1");
246 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "liststore2");
247 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "security_selector_dialog");
248
249 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, retval);
250
251 retval->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "security_selector_dialog"));
252 retval->namespace_combo = GTK_WIDGET(gtk_builder_get_object (builder, "ss_namespace_cbwe"));
253 retval->commodity_combo = GTK_WIDGET(gtk_builder_get_object (builder, "ss_commodity_cbwe"));
254 retval->select_user_prompt = GTK_WIDGET(gtk_builder_get_object (builder, "select_user_prompt"));
255 retval->ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "ss_ok_button"));
256 label = GTK_WIDGET(gtk_builder_get_object (builder, "item_label"));
257
258 // Set the name for this dialog so it can be easily manipulated with css
259 gtk_widget_set_name (GTK_WIDGET(retval->dialog), "gnc-id-security-select");
260 gnc_widget_style_context_add_class (GTK_WIDGET(retval->dialog), "gnc-class-securities");
261
262 gnc_cbwe_require_list_item(GTK_COMBO_BOX(retval->namespace_combo));
263 gnc_cbwe_require_list_item(GTK_COMBO_BOX(retval->commodity_combo));
264
265 gtk_label_set_text (GTK_LABEL (retval->select_user_prompt), "");
266
267#ifdef DRH
268 g_signal_connect (G_OBJECT (retval->dialog), "close",
269 G_CALLBACK (select_commodity_close), retval);
270 g_signal_connect (G_OBJECT (retval->dialog), "response",
271 G_CALLBACK (gnc_ui_select_commodity_response_cb), retval);
272#endif
273
274 switch (mode)
275 {
276 case DIAG_COMM_ALL:
277 title = _("Select security/currency");
278 text = _("_Security/currency");
279 break;
282 title = _("Select security");
283 text = _("_Security");
284 break;
286 default:
287 title = _("Select currency");
288 text = _("Cu_rrency");
289 button = GTK_WIDGET(gtk_builder_get_object (builder, "ss_new_button"));
290 gtk_widget_destroy(button);
291 break;
292 }
293 gtk_window_set_title (GTK_WINDOW(retval->dialog), title);
294 gtk_label_set_text_with_mnemonic (GTK_LABEL(label), text);
295
296 /* build the menus of namespaces and commodities */
297 gnc_ui_update_namespace_picker(retval->namespace_combo,
299 mode);
300 name_space = gnc_ui_namespace_picker_ns(retval->namespace_combo);
301 gnc_ui_update_commodity_picker(retval->commodity_combo, name_space,
303
304 g_object_unref(G_OBJECT(builder));
305
306 g_free(name_space);
307 return retval;
308}
309
310
325void
327 gpointer user_data)
328{
329 auto w = static_cast<SelectCommodityWindow*>(user_data);
330
331 gchar * name_space = gnc_ui_namespace_picker_ns (w->namespace_combo);
332
333 const gnc_commodity * new_commodity =
335 w->dialog,
336 w->default_cusip,
337 w->default_fullname,
338 w->default_mnemonic,
339 w->default_user_symbol,
340 w->default_fraction);
341 if (new_commodity)
342 {
343 gnc_ui_update_namespace_picker(w->namespace_combo,
344 gnc_commodity_get_namespace(new_commodity),
346 gnc_ui_update_commodity_picker(w->commodity_combo,
347 gnc_commodity_get_namespace(new_commodity),
348 gnc_commodity_get_printname(new_commodity));
349 }
350 g_free(name_space);
351}
352
353
369void
371 gpointer user_data)
372{
373 auto w = static_cast<SelectCommodityWindow*>(user_data);
374 gchar *name_space;
375 const gchar *fullname;
376 gboolean ok;
377
378 ENTER("cbwe=%p, user_data=%p", cbwe, user_data);
379 name_space = gnc_ui_namespace_picker_ns (w->namespace_combo);
380 fullname = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (GTK_COMBO_BOX(w->commodity_combo)))));
381
382 DEBUG("namespace=%s, name=%s", name_space, fullname);
383 w->selection = gnc_commodity_table_find_full(gnc_get_current_commodities(),
384 name_space, fullname);
385 g_free(name_space);
386
387 ok = (w->selection != nullptr);
388 gtk_widget_set_sensitive(w->ok_button, ok);
389 gtk_dialog_set_default_response(GTK_DIALOG(w->dialog), ok ? 0 : 2);
390 LEAVE("sensitive=%d, default = %d", ok, ok ? 0 : 2);
391}
392
393
410void
412 gpointer user_data)
413{
414 auto w = static_cast<SelectCommodityWindow*>(user_data);
415 gchar *name_space;
416
417 ENTER("cbwe=%p, user_data=%p", cbwe, user_data);
418 name_space = gnc_ui_namespace_picker_ns (w->namespace_combo);
419 DEBUG("name_space=%s", name_space);
420 gnc_ui_update_commodity_picker(w->commodity_combo, name_space, nullptr);
421 g_free(name_space);
422 LEAVE(" ");
423}
424
425
426/********************************************************************
427 * gnc_ui_update_commodity_picker
428 ********************************************************************/
429static int
430collate(gconstpointer a, gconstpointer b)
431{
432 if (!a)
433 return -1;
434 if (!b)
435 return 1;
436 return g_utf8_collate (static_cast<const char*>(a), static_cast<const char*>(b));
437}
438
439
440void
442 const gchar * name_space,
443 const gchar * init_string)
444{
445 GList * commodities;
446 GList * iterator = nullptr;
447 GList * commodity_items = nullptr;
448 GtkComboBox *combo_box;
449 GtkEntry *entry;
450 GtkTreeModel *model;
451 GtkTreeIter iter;
452 gnc_commodity_table *table;
453 gint current = 0, match = 0;
454 gchar *name;
455
456 g_return_if_fail(GTK_IS_COMBO_BOX(cbwe));
457 g_return_if_fail(name_space);
458
459 /* Erase the old entries */
460 combo_box = GTK_COMBO_BOX(cbwe);
461 model = gtk_combo_box_get_model(combo_box);
462 gtk_list_store_clear(GTK_LIST_STORE(model));
463
464 /* Erase the entry text */
465 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo_box)));
466 gtk_editable_delete_text(GTK_EDITABLE(entry), 0, -1);
467
468 gtk_combo_box_set_active(combo_box, -1);
469
470 table = gnc_commodity_table_get_table (gnc_get_current_book ());
471 commodities = gnc_commodity_table_get_commodities(table, name_space);
472 for (iterator = commodities; iterator; iterator = iterator->next)
473 {
474 commodity_items =
475 g_list_prepend (commodity_items,
476 (gpointer) gnc_commodity_get_printname(GNC_COMMODITY(iterator->data)));
477 }
478 g_list_free(commodities);
479
480 commodity_items = g_list_sort(commodity_items, collate);
481 for (iterator = commodity_items; iterator; iterator = iterator->next)
482 {
483 name = (char *)iterator->data;
484 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
485 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, name, -1);
486
487 if (init_string && g_utf8_collate(name, init_string) == 0)
488 match = current;
489 current++;
490 }
491
492 gtk_combo_box_set_active(combo_box, match);
493 g_list_free(commodity_items);
494}
495
496
497/********************************************************************
498 *
499 * Commodity Selector dialog routines are above this line.
500 *
501 * Commodity New/Edit dialog routines are below this line.
502 *
503 ********************************************************************/
504static void
505gnc_set_commodity_section_sensitivity (GtkWidget *widget, gpointer user_data)
506{
507 auto cw = static_cast<CommodityWindow*>(user_data);
508 guint offset = 0;
509
510 gtk_container_child_get(GTK_CONTAINER(cw->table), widget,
511 "top-attach", &offset,
512 nullptr);
513
514 if ((offset < cw->comm_section_top) || (offset >= cw->comm_section_bottom))
515 return;
516 if (cw->is_currency)
517 gtk_widget_set_sensitive(widget, offset == cw->comm_symbol_line);
518}
519
520static void
521gnc_ui_update_commodity_info (CommodityWindow *cw)
522{
523 gtk_container_foreach(GTK_CONTAINER(cw->table),
524 gnc_set_commodity_section_sensitivity, cw);
525}
526
527
528static void
529gnc_set_fq_sensitivity (GtkWidget *widget, gpointer user_data)
530{
531 auto cw = static_cast<CommodityWindow*>(user_data);
532 guint offset = 0;
533
534 gtk_container_child_get(GTK_CONTAINER(cw->table), widget,
535 "top-attach", &offset,
536 nullptr);
537
538 if ((offset < cw->fq_section_top) || (offset >= cw->fq_section_bottom))
539 return;
540 g_object_set(widget, "sensitive", FALSE, nullptr);
541}
542
543
544static void
545gnc_ui_update_fq_info (CommodityWindow *cw)
546{
547 gtk_container_foreach(GTK_CONTAINER(cw->table),
548 gnc_set_fq_sensitivity, cw);
549}
550
551
552/********************************************************************
553 * gnc_ui_update_namespace_picker
554 ********************************************************************/
555void
556gnc_ui_update_namespace_picker (GtkWidget *cbwe,
557 const char * init_string,
559{
560 GtkComboBox *combo_box;
561 GtkTreeModel *model;
562 GtkTreeIter iter, match;
563 GList *namespaces, *node;
564 gboolean matched = FALSE;
565
566 g_return_if_fail(GTK_IS_COMBO_BOX (cbwe));
567
568 /* Erase the old entries */
569 combo_box = GTK_COMBO_BOX(cbwe);
570 model = gtk_combo_box_get_model(combo_box);
571 gtk_list_store_clear(GTK_LIST_STORE(model));
572
573 /* fetch a list of the namespaces */
574 switch (mode)
575 {
576 case DIAG_COMM_ALL:
577 namespaces =
578 gnc_commodity_table_get_namespaces (gnc_get_current_commodities());
579 break;
580
583 namespaces =
584 gnc_commodity_table_get_namespaces (gnc_get_current_commodities());
585 node = g_list_find_custom (namespaces, GNC_COMMODITY_NS_CURRENCY, collate);
586 if (node)
587 {
588 namespaces = g_list_remove_link (namespaces, node);
589 g_list_free_1 (node);
590 }
591
592 if (gnc_commodity_namespace_is_iso (init_string))
593 init_string = nullptr;
594 break;
595
597 default:
598 namespaces = g_list_prepend (nullptr, (gpointer)GNC_COMMODITY_NS_CURRENCY);
599 break;
600 }
601
602 /* First insert "Currencies" entry if requested */
603 if (mode == DIAG_COMM_CURRENCY || mode == DIAG_COMM_ALL)
604 {
605 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
606 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0,
607 _(GNC_COMMODITY_NS_ISO_GUI), -1);
608
609 if (init_string &&
610 (g_utf8_collate(GNC_COMMODITY_NS_ISO_GUI, init_string) == 0))
611 {
612 matched = TRUE;
613 match = iter;
614 }
615 }
616
617 /* Next insert "All non-currency" entry if requested */
618 if (mode == DIAG_COMM_NON_CURRENCY_SELECT || mode == DIAG_COMM_ALL)
619 {
620 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
621 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0,
622 GNC_COMMODITY_NS_NONISO_GUI, -1);
623 }
624
625 /* add all others to the combobox */
626 namespaces = g_list_sort(namespaces, collate);
627 for (node = namespaces; node; node = node->next)
628 {
629 auto ns = static_cast<const char*>(node->data);
630 /* Skip template, legacy and currency namespaces.
631 The latter was added as first entry earlier */
632 if ((g_utf8_collate(ns, GNC_COMMODITY_NS_LEGACY) == 0) ||
633 (g_utf8_collate(ns, GNC_COMMODITY_NS_TEMPLATE ) == 0) ||
634 (g_utf8_collate(ns, GNC_COMMODITY_NS_CURRENCY ) == 0))
635 continue;
636
637 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
638 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, ns, -1);
639
640 if (init_string &&
641 (g_utf8_collate(ns, init_string) == 0))
642 {
643 matched = TRUE;
644 match = iter;
645 }
646 }
647
648 if (!matched)
649 matched = gtk_tree_model_get_iter_first (model, &match);
650
651 if (matched)
652 gtk_combo_box_set_active_iter (combo_box, &match);
653 g_list_free(namespaces);
654}
655
656
657gchar *
659{
660 const gchar *name_space;
661
662 g_return_val_if_fail(GTK_IS_COMBO_BOX (cbwe), nullptr);
663
664 name_space = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( GTK_COMBO_BOX(cbwe)))));
665
666 /* Map several currency related names to one common namespace */
667 if ((g_strcmp0 (name_space, GNC_COMMODITY_NS_ISO) == 0) ||
668 (g_strcmp0 (name_space, GNC_COMMODITY_NS_ISO_GUI) == 0) ||
669 (g_strcmp0 (name_space, _(GNC_COMMODITY_NS_ISO_GUI)) == 0))
670 return g_strdup(GNC_COMMODITY_NS_CURRENCY);
671 else
672 return g_strdup(name_space);
673}
674
675
676/********************************************************************
677 * gnc_ui_commodity_quote_info_cb *
678 *******************************************************************/
679void
680gnc_ui_commodity_quote_info_cb (GtkWidget *w, gpointer data)
681{
682 auto cw = static_cast<CommodityWindow*>(data);
683 gboolean get_quote, allow_src, active;
684 const gchar *text;
685 gint i;
686
687 ENTER(" ");
688 get_quote = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
689
690 text = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( GTK_COMBO_BOX(cw->namespace_combo)))));
691
692 allow_src = !gnc_commodity_namespace_is_iso(text);
693
694 gtk_widget_set_sensitive(cw->source_label, get_quote && allow_src);
695
696 for (i = SOURCE_SINGLE; i < SOURCE_MAX; i++)
697 {
698 if (!cw->source_button[i])
699 continue;
700 active =
701 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw->source_button[i]));
702 gtk_widget_set_sensitive(cw->source_button[i], get_quote && allow_src);
703 gtk_widget_set_sensitive(cw->source_menu[i], get_quote && allow_src && active);
704 }
705 gtk_widget_set_sensitive(cw->quote_tz_label, get_quote);
706 gtk_widget_set_sensitive(cw->quote_tz_menu, get_quote);
707 LEAVE(" ");
708}
709
710
711void
712gnc_ui_commodity_changed_cb(GtkWidget * dummy, gpointer user_data)
713{
714 auto w = static_cast<CommodityWindow*>(user_data);
715 gchar *name_space;
716 const char * fullname;
717 const char * mnemonic;
718 gboolean ok;
719
720 ENTER("widget=%p, user_data=%p", dummy, user_data);
721 if (!w->is_currency)
722 {
723 name_space = gnc_ui_namespace_picker_ns (w->namespace_combo);
724 fullname = gtk_entry_get_text(GTK_ENTRY(w->fullname_entry));
725 mnemonic = gtk_entry_get_text(GTK_ENTRY(w->mnemonic_entry));
726 DEBUG("namespace=%s, name=%s, mnemonic=%s", name_space, fullname, mnemonic);
727 ok = (fullname && name_space && mnemonic &&
728 fullname[0] && name_space[0] && mnemonic[0]);
729 g_free(name_space);
730 }
731 else
732 {
733 ok = TRUE;
734 }
735 gtk_widget_set_sensitive(w->ok_button, ok);
736 gtk_dialog_set_default_response(GTK_DIALOG(w->dialog), ok ? 0 : 1);
737 LEAVE("sensitive=%d, default = %d", ok, ok ? 0 : 1);
738}
739
740
741/********************************************************************\
742 * gnc_ui_source_menu_create *
743 * create the menu of stock quote sources *
744 * *
745 * Args: account - account to use to set default choice *
746 * Returns: the menu *
747 \*******************************************************************/
748static GtkWidget *
749gnc_ui_source_menu_create(QuoteSourceType type)
750{
751 gint i, max;
752 const gchar *name;
753 gboolean supported;
754 GtkListStore *store;
755 GtkTreeIter iter;
756 GtkWidget *combo;
757 GtkCellRenderer *renderer;
758 gnc_quote_source *source;
759
760 store = gtk_list_store_new(NUM_SOURCE_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN);
761 if (type == SOURCE_CURRENCY)
762 {
763 gtk_list_store_append(store, &iter);
764 gtk_list_store_set(store, &iter,
765 SOURCE_COL_NAME, _("Currency"),
766 SOURCE_COL_FQ_SUPPORTED, TRUE,
767 -1);
768 }
769 else
770 {
772 for (i = 0; i < max; i++)
773 {
774 source = gnc_quote_source_lookup_by_ti(type, i);
775 if (source == nullptr)
776 break;
777 name = gnc_quote_source_get_user_name(source);
778 supported = gnc_quote_source_get_supported(source);
779 gtk_list_store_append(store, &iter);
780 gtk_list_store_set(store, &iter,
781 SOURCE_COL_NAME, g_dpgettext2(NULL, "FQ Source", name),
782 SOURCE_COL_FQ_SUPPORTED, supported,
783 -1);
784 }
785 }
786
787 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
788 g_object_unref(store);
789 renderer = gtk_cell_renderer_text_new();
790 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
791 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
792 "text", SOURCE_COL_NAME);
793 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
794 "sensitive", SOURCE_COL_FQ_SUPPORTED);
795 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
796 gtk_widget_show(combo);
797 return combo;
798}
799
800
801/********************************************************************
802 * price quote timezone handling *
803 *******************************************************************/
804static const gchar *
805known_timezones[] =
806{
807 "Asia/Tokyo",
808 "Australia/Sydney",
809 "America/New_York",
810 "America/Chicago",
811 "Europe/London",
812 "Europe/Paris",
813 nullptr
814};
815
816
817static guint
818gnc_find_timezone_menu_position(const gchar *timezone)
819{
820 /* returns 0 on failure, position otherwise. */
821 gboolean found = FALSE;
822 guint i = 0;
823 while (!found && known_timezones[i])
824 {
825 if (g_strcmp0(timezone, known_timezones[i]) != 0)
826 {
827 i++;
828 }
829 else
830 {
831 found = TRUE;
832 }
833 }
834 if (found) return i + 1;
835 return 0;
836}
837
838
839static const gchar *
840gnc_timezone_menu_position_to_string(guint pos)
841{
842 if (pos == 0) return nullptr;
843 return known_timezones[pos - 1];
844}
845
846
847static GtkWidget *
848gnc_ui_quote_tz_menu_create(void)
849{
850 GtkWidget *combo;
851 const gchar **itemstr;
852
853 /* add items here as needed, but bear in mind that right now these
854 must be timezones that GNU libc understands. Also, I'd prefer if
855 we only add things here we *know* we need. That's because in
856 order to be portable to non GNU OSes, we may have to support
857 whatever we add here manually on those systems. */
858
859 combo = gtk_combo_box_text_new();
860 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Use local time"));
861 for (itemstr = &known_timezones[0]; *itemstr; itemstr++)
862 {
863 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), *itemstr);
864 }
865
866 gtk_widget_show(combo);
867 return combo;
868}
869
870
871/*******************************************************
872 * Build the new/edit commodity dialog box *
873 *******************************************************/
874static CommodityWindow *
875gnc_ui_build_commodity_dialog(const char * selected_namespace,
876 GtkWidget *parent,
877 const char * fullname,
878 const char * mnemonic,
879 const char * user_symbol,
880 const char * cusip,
881 int fraction,
882 gboolean edit)
883{
884 CommodityWindow * retval = g_new0(CommodityWindow, 1);
885 GtkWidget *box;
886 GtkWidget *menu;
887 GtkWidget *widget, *sec_label;
888 GtkBuilder *builder;
889 gboolean include_iso;
890 const gchar *title;
891 gchar *text;
892
893 ENTER("widget=%p, selected namespace=%s, fullname=%s, mnemonic=%s",
894 parent, selected_namespace, fullname, mnemonic);
895
896 builder = gtk_builder_new();
897 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "liststore2");
898 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "adjustment1");
899 gnc_builder_add_from_file (builder, "dialog-commodity.glade", "security_dialog");
900
901 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, retval);
902
903 retval->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "security_dialog"));
904
905 // Set the name for this dialog so it can be easily manipulated with css
906 gtk_widget_set_name (GTK_WIDGET(retval->dialog), "gnc-id-security");
907 gnc_widget_style_context_add_class (GTK_WIDGET(retval->dialog), "gnc-class-securities");
908
909 if (parent != nullptr)
910 gtk_window_set_transient_for (GTK_WINDOW (retval->dialog), GTK_WINDOW (parent));
911
912 retval->edit_commodity = nullptr;
913
914 /* Get widget pointers */
915 retval->fullname_entry = GTK_WIDGET(gtk_builder_get_object (builder, "fullname_entry"));
916 retval->mnemonic_entry = GTK_WIDGET(gtk_builder_get_object (builder, "mnemonic_entry"));
917 retval->user_symbol_entry = GTK_WIDGET(gtk_builder_get_object (builder, "user_symbol_entry"));
918 retval->namespace_combo = GTK_WIDGET(gtk_builder_get_object (builder, "namespace_cbwe"));
919 retval->code_entry = GTK_WIDGET(gtk_builder_get_object (builder, "code_entry"));
920 retval->fraction_spinbutton = GTK_WIDGET(gtk_builder_get_object (builder, "fraction_spinbutton"));
921 retval->ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "ok_button"));
922 retval->get_quote_check = GTK_WIDGET(gtk_builder_get_object (builder, "get_quote_check"));
923 retval->source_label = GTK_WIDGET(gtk_builder_get_object (builder, "source_label"));
924 retval->source_button[SOURCE_SINGLE] = GTK_WIDGET(gtk_builder_get_object (builder, "single_source_button"));
925 retval->source_button[SOURCE_MULTI] = GTK_WIDGET(gtk_builder_get_object (builder, "multi_source_button"));
926 retval->quote_tz_label = GTK_WIDGET(gtk_builder_get_object (builder, "quote_tz_label"));
927
928 /* Determine the commodity section of the dialog */
929 retval->table = GTK_WIDGET(gtk_builder_get_object (builder, "edit_table"));
930 sec_label = GTK_WIDGET(gtk_builder_get_object (builder, "security_label"));
931 gtk_container_child_get(GTK_CONTAINER(retval->table), sec_label,
932 "top-attach", &retval->comm_section_top, nullptr);
933
934 widget = GTK_WIDGET(gtk_builder_get_object (builder, "quote_label"));
935 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
936 "top-attach", &retval->comm_section_bottom, nullptr);
937
938 gtk_container_child_get(GTK_CONTAINER(retval->table),
939 retval->user_symbol_entry, "top-attach",
940 &retval->comm_symbol_line, nullptr);
941
942 /* Build custom widgets */
943 box = GTK_WIDGET(gtk_builder_get_object (builder, "single_source_box"));
944 if (gnc_commodity_namespace_is_iso(selected_namespace))
945 {
946 menu = gnc_ui_source_menu_create(SOURCE_CURRENCY);
947 }
948 else
949 {
950 menu = gnc_ui_source_menu_create(SOURCE_SINGLE);
951 }
952 retval->source_menu[SOURCE_SINGLE] = menu;
953 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
954
955 box = GTK_WIDGET(gtk_builder_get_object (builder, "multi_source_box"));
956 menu = gnc_ui_source_menu_create(SOURCE_MULTI);
957 retval->source_menu[SOURCE_MULTI] = menu;
958 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
959
961 {
962 retval->source_button[SOURCE_UNKNOWN] =
963 GTK_WIDGET(gtk_builder_get_object (builder, "unknown_source_button"));
964 box = GTK_WIDGET(gtk_builder_get_object (builder, "unknown_source_box"));
965 menu = gnc_ui_source_menu_create(SOURCE_UNKNOWN);
966 retval->source_menu[SOURCE_UNKNOWN] = menu;
967 gtk_box_pack_start(GTK_BOX(box), menu, TRUE, TRUE, 0);
968 }
969 else
970 {
971 gtk_grid_set_row_spacing(GTK_GRID(retval->table), 0);
972
973 widget = GTK_WIDGET(gtk_builder_get_object (builder, "unknown_source_alignment"));
974 gtk_widget_destroy(widget);
975
976 widget = GTK_WIDGET(gtk_builder_get_object (builder, "unknown_source_box"));
977 gtk_widget_destroy(widget);
978 }
979
980 box = GTK_WIDGET(gtk_builder_get_object (builder, "quote_tz_box"));
981 retval->quote_tz_menu = gnc_ui_quote_tz_menu_create();
982 gtk_box_pack_start(GTK_BOX(box), retval->quote_tz_menu, TRUE, TRUE, 0);
983
984 /* Commodity editing is next to nil */
985 if (gnc_commodity_namespace_is_iso(selected_namespace))
986 {
987 retval->is_currency = TRUE;
988 gnc_ui_update_commodity_info (retval);
989 include_iso = TRUE;
990 title = _("Edit currency");
991 text = g_strdup_printf("<b>%s</b>", _("Currency Information"));
992 }
993 else
994 {
995 include_iso = FALSE;
996 title = edit ? _("Edit security") : _("New security");
997 text = g_strdup_printf("<b>%s</b>", _("Security Information"));
998 }
999 gtk_window_set_title(GTK_WINDOW(retval->dialog), title);
1000 gtk_label_set_markup(GTK_LABEL(sec_label), text);
1001 g_free(text);
1002
1003 /* Are price quotes supported */
1005 {
1006 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "finance_quote_warning")));
1007 }
1008 else
1009 {
1010 /* Determine the price quote of the dialog */
1011 widget = GTK_WIDGET(gtk_builder_get_object (builder, "fq_warning_alignment"));
1012 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
1013 "top-attach", &retval->fq_section_top, nullptr);
1014
1015 widget = GTK_WIDGET(gtk_builder_get_object (builder, "bottom_alignment"));
1016 gtk_container_child_get(GTK_CONTAINER(retval->table), widget,
1017 "top-attach", &retval->fq_section_bottom, nullptr);
1018
1019 gnc_ui_update_fq_info (retval);
1020 }
1021
1022#ifdef DRH
1023 g_signal_connect (G_OBJECT (retval->dialog), "close",
1024 G_CALLBACK (commodity_close), retval);
1025#endif
1026 /* Fill in any data, top to bottom */
1027 gtk_entry_set_text (GTK_ENTRY (retval->fullname_entry), fullname ? fullname : "");
1028 gtk_entry_set_text (GTK_ENTRY (retval->mnemonic_entry), mnemonic ? mnemonic : "");
1029 gtk_entry_set_text (GTK_ENTRY (retval->user_symbol_entry), user_symbol ? user_symbol : "");
1030 gnc_cbwe_add_completion(GTK_COMBO_BOX(retval->namespace_combo));
1031 gnc_ui_update_namespace_picker(retval->namespace_combo,
1032 selected_namespace,
1033 include_iso ? DIAG_COMM_ALL : DIAG_COMM_NON_CURRENCY);
1034 gtk_entry_set_text (GTK_ENTRY (retval->code_entry), cusip ? cusip : "");
1035
1036 if (fraction > 0)
1037 gtk_spin_button_set_value (GTK_SPIN_BUTTON (retval->fraction_spinbutton),
1038 fraction);
1039
1040 g_object_unref(G_OBJECT(builder));
1041
1042 LEAVE(" ");
1043 return retval;
1044}
1045
1046
1047static void
1048gnc_ui_commodity_update_quote_info(CommodityWindow *win,
1049 gnc_commodity *commodity)
1050{
1051 gnc_quote_source *source;
1052 QuoteSourceType type;
1053 gboolean has_quote_src;
1054 const char *quote_tz;
1055 int pos = 0;
1056
1057 ENTER(" ");
1058 has_quote_src = gnc_commodity_get_quote_flag (commodity);
1059 source = gnc_commodity_get_quote_source (commodity);
1060 if (source == nullptr)
1061 source = gnc_commodity_get_default_quote_source (commodity);
1062 quote_tz = gnc_commodity_get_quote_tz (commodity);
1063
1064 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (win->get_quote_check),
1065 has_quote_src);
1066 if (!gnc_commodity_is_iso(commodity))
1067 {
1068 type = gnc_quote_source_get_type(source);
1069 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->source_button[type]), TRUE);
1070 gtk_combo_box_set_active(GTK_COMBO_BOX(win->source_menu[type]),
1072 }
1073
1074 if (quote_tz)
1075 {
1076 pos = gnc_find_timezone_menu_position(quote_tz);
1077// if(pos == 0) {
1078// PWARN("Unknown price quote timezone (%s), resetting to default.",
1079// quote_tz ? quote_tz : "(null)");
1080// }
1081 }
1082 gtk_combo_box_set_active(GTK_COMBO_BOX(win->quote_tz_menu), pos);
1083 LEAVE(" ");
1084}
1085
1086
1087static gnc_commodity *
1088gnc_ui_common_commodity_modal(gnc_commodity *commodity,
1089 GtkWidget * parent,
1090 const char * name_space,
1091 const char * cusip,
1092 const char * fullname,
1093 const char * mnemonic,
1094 const char * user_symbol,
1095 int fraction)
1096{
1097 CommodityWindow * win;
1098 gnc_commodity *retval = nullptr;
1099 gboolean done;
1100 gint value;
1101
1102 ENTER(" ");
1103
1104 /* If a commodity was provided, copy out the existing info */
1105 if (commodity)
1106 {
1107 name_space = gnc_commodity_get_namespace (commodity);
1108 fullname = gnc_commodity_get_fullname (commodity);
1109 mnemonic = gnc_commodity_get_mnemonic (commodity);
1110 user_symbol = gnc_commodity_get_nice_symbol (commodity);
1111 cusip = gnc_commodity_get_cusip (commodity);
1112 fraction = gnc_commodity_get_fraction (commodity);
1113 }
1114 else
1115 {
1116 /* Not allowed to create new currencies */
1117 if (gnc_commodity_namespace_is_iso(name_space))
1118 {
1119 name_space = nullptr;
1120 }
1121 }
1122
1123 win = gnc_ui_build_commodity_dialog(name_space, parent, fullname,
1124 mnemonic, user_symbol, cusip,
1125 fraction, (commodity != nullptr));
1126
1127 /* Update stock quote info based on existing commodity */
1128 gnc_ui_commodity_update_quote_info(win, commodity);
1129 win->edit_commodity = commodity;
1130
1131 /* Update stock quote sensitivities based on check box */
1132 gnc_ui_commodity_quote_info_cb(win->get_quote_check, win);
1133
1134 /* Run the dialog, handling the terminal conditions. */
1135 done = FALSE;
1136 while (!done)
1137 {
1138 value = gtk_dialog_run(GTK_DIALOG(win->dialog));
1139 switch (value)
1140 {
1141 case GTK_RESPONSE_OK:
1142 DEBUG("case OK");
1143 done = gnc_ui_commodity_dialog_to_object(win);
1144 retval = win->edit_commodity;
1145 break;
1146 case GTK_RESPONSE_HELP:
1147 DEBUG("case HELP");
1148 gnc_gnome_help (GTK_WINDOW(win->dialog), DF_MANUAL, DL_COMMODITY);
1149 break;
1150 default: /* Cancel, Escape, Close, etc. */
1151 DEBUG("default: %d", value);
1152 retval = nullptr;
1153 done = TRUE;
1154 break;
1155 }
1156 }
1157 gtk_widget_destroy (GTK_WIDGET (win->dialog)); /* Close and destroy */
1158 g_free(win);
1159
1160 LEAVE(" ");
1161 return retval;
1162}
1163
1164
1165/********************************************************
1166 * Create and run the new/edit commodity dialog. *
1167 ********************************************************/
1168gnc_commodity *
1169gnc_ui_new_commodity_modal_full(const char * name_space,
1170 GtkWidget * parent,
1171 const char * cusip,
1172 const char * fullname,
1173 const char * mnemonic,
1174 const char * user_symbol,
1175 int fraction)
1176{
1177 gnc_commodity *result;
1178
1179 ENTER(" ");
1180 result = gnc_ui_common_commodity_modal(nullptr, parent, name_space, cusip,
1181 fullname, mnemonic, user_symbol,
1182 10000);
1183 LEAVE(" ");
1184 return result;
1185}
1186
1187
1188/********************************************************************
1189 * External routine for popping up the new commodity dialog box. *
1190 ********************************************************************/
1191gnc_commodity *
1192gnc_ui_new_commodity_modal(const char * default_namespace,
1193 GtkWidget * parent)
1194{
1195 gnc_commodity *result;
1196
1197 ENTER(" ");
1198 result = gnc_ui_common_commodity_modal(nullptr, parent, default_namespace, nullptr,
1199 nullptr, nullptr, nullptr, 0);
1200 LEAVE(" ");
1201 return result;
1202}
1203
1204
1205/********************************************************************
1206 * gnc_ui_edit_commodity_modal()
1207 ********************************************************************/
1213gboolean
1214gnc_ui_edit_commodity_modal(gnc_commodity *commodity,
1215 GtkWidget * parent)
1216{
1217 gnc_commodity *result;
1218
1219 ENTER(" ");
1220 result = gnc_ui_common_commodity_modal(commodity, parent, nullptr, nullptr,
1221 nullptr, nullptr, nullptr, 0);
1222 LEAVE(" ");
1223 return result != nullptr;
1224}
1225
1226
1227/********************************************************************
1228 * gnc_ui_commodity_dialog_to_object()
1229 ********************************************************************/
1230gboolean
1231gnc_ui_commodity_dialog_to_object(CommodityWindow * w)
1232{
1233 gnc_quote_source *source;
1234 QuoteSourceType type;
1235 const char * fullname = gtk_entry_get_text(GTK_ENTRY(w->fullname_entry));
1236 gchar *name_space = gnc_ui_namespace_picker_ns (w->namespace_combo);
1237 const char * mnemonic = gtk_entry_get_text(GTK_ENTRY(w->mnemonic_entry));
1238 const char * user_symbol = gtk_entry_get_text(GTK_ENTRY(w->user_symbol_entry));
1239 const char * code = gtk_entry_get_text(GTK_ENTRY(w->code_entry));
1240 QofBook * book = gnc_get_current_book ();
1241 int fraction = gtk_spin_button_get_value_as_int
1242 (GTK_SPIN_BUTTON(w->fraction_spinbutton));
1243 const char *string;
1244 gnc_commodity * c;
1245 gint selection;
1246
1247 ENTER(" ");
1248 /* Special case currencies */
1249 if (gnc_commodity_namespace_is_iso (name_space))
1250 {
1251 if (w->edit_commodity)
1252 {
1253 gboolean quote_set;
1254 quote_set = gtk_toggle_button_get_active
1255 (GTK_TOGGLE_BUTTON (w->get_quote_check));
1256 c = w->edit_commodity;
1257 gnc_commodity_begin_edit(c);
1258 gnc_commodity_user_set_quote_flag (c, quote_set);
1259 if (quote_set)
1260 {
1261 selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->quote_tz_menu));
1262 string = gnc_timezone_menu_position_to_string(selection);
1263 gnc_commodity_set_quote_tz(c, string);
1264 }
1265 else
1266 gnc_commodity_set_quote_tz(c, nullptr);
1267
1268 gnc_commodity_set_user_symbol(c, user_symbol);
1269
1270 gnc_commodity_commit_edit(c);
1271 g_free (name_space);
1272 return TRUE;
1273 }
1274 gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s",
1275 _("You may not create a new national currency."));
1276 g_free (name_space);
1277 return FALSE;
1278 }
1279
1280 /* Don't allow user to create commodities in namespace
1281 * "template". That's reserved for scheduled transaction use.
1282 */
1283 if (g_utf8_collate(name_space, GNC_COMMODITY_NS_TEMPLATE) == 0)
1284 {
1285 gnc_warning_dialog (GTK_WINDOW (w->dialog),
1286 _("%s is a reserved commodity type."
1287 " Please use something else."), GNC_COMMODITY_NS_TEMPLATE);
1288 g_free (name_space);
1289 return FALSE;
1290 }
1291
1292 if (fullname && fullname[0] &&
1293 name_space && name_space[0] &&
1294 mnemonic && mnemonic[0])
1295 {
1296 c = gnc_commodity_table_lookup (gnc_get_current_commodities(),
1297 name_space, mnemonic);
1298
1299 if ((!w->edit_commodity && c) ||
1300 (w->edit_commodity && c && (c != w->edit_commodity)))
1301 {
1302 gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s", _("That commodity already exists."));
1303 g_free(name_space);
1304 return FALSE;
1305 }
1306
1307 if (!w->edit_commodity)
1308 {
1309 c = gnc_commodity_new(book, fullname, name_space, mnemonic, code, fraction);
1310 w->edit_commodity = c;
1311 gnc_commodity_begin_edit(c);
1312
1313 gnc_commodity_set_user_symbol(c, user_symbol);
1314 }
1315 else
1316 {
1317 c = w->edit_commodity;
1318 gnc_commodity_begin_edit(c);
1319
1320 gnc_commodity_table_remove (gnc_get_current_commodities(), c);
1321
1322 gnc_commodity_set_fullname (c, fullname);
1323 gnc_commodity_set_mnemonic (c, mnemonic);
1324 gnc_commodity_set_namespace (c, name_space);
1325 gnc_commodity_set_cusip (c, code);
1326 gnc_commodity_set_fraction (c, fraction);
1327 gnc_commodity_set_user_symbol(c, user_symbol);
1328 }
1329
1330 gnc_commodity_user_set_quote_flag (c, gtk_toggle_button_get_active
1331 (GTK_TOGGLE_BUTTON (w->get_quote_check)));
1332
1333 for (type = SOURCE_SINGLE; type < SOURCE_MAX; type = static_cast<QuoteSourceType>(type+1))
1334 {
1335 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->source_button[type])))
1336 break;
1337 }
1338 selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->source_menu[type]));
1339 source = gnc_quote_source_lookup_by_ti (type, selection);
1341
1342 selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->quote_tz_menu));
1343 string = gnc_timezone_menu_position_to_string(selection);
1344 gnc_commodity_set_quote_tz(c, string);
1345 gnc_commodity_commit_edit(c);
1346
1347 /* remember the commodity */
1348 gnc_commodity_table_insert(gnc_get_current_commodities(), c);
1349 }
1350 else
1351 {
1352 gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s",
1353 _("You must enter a non-empty \"Full name\", "
1354 "\"Symbol/abbreviation\", "
1355 "and \"Type\" for the commodity."));
1356 g_free(name_space);
1357 return FALSE;
1358 }
1359 g_free(name_space);
1360 LEAVE(" ");
1361 return TRUE;
1362}
1363
"select" and "new" commodity windows
All type declarations for the whole Gnucash engine.
gtk helper routines.
utility functions for the GnuCash UI
const char * gnc_quote_source_get_user_name(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the user friendly name of this quote source.
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
Set the 'exchange code' for the specified commodity.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
gboolean gnc_quote_source_get_supported(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the flag that indicates whether this particular quote...
void gnc_commodity_table_remove(gnc_commodity_table *table, gnc_commodity *comm)
Remove a commodity from the commodity table.
gboolean gnc_quote_source_fq_installed(void)
This function indicates whether or not the Finance::Quote module is installed on a user's computer.
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
Set the namespace for the specified commodity.
gint gnc_quote_source_get_index(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the index of this particular quote source within its ...
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
Create a new commodity.
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
Set the full name for the specified commodity.
gboolean gnc_commodity_namespace_is_iso(const char *name_space)
Checks to see if the specified commodity namespace is the namespace for ISO 4217 currencies.
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
Retrieve the automatic price quote timezone for the specified commodity.
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
Retrieve a symbol for the specified commodity, suitable for display to the user.
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
Set the automatic price quote source for the specified commodity.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
Set the fraction for the specified commodity.
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
Retrieve the automatic price quote source for the specified commodity.
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
Retrieve the 'exchange code' for the specified commodity.
gnc_quote_source * gnc_quote_source_lookup_by_ti(QuoteSourceType type, gint index)
Given the type/index of a quote source, find the data structure identified by this pair.
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
Add a new commodity to the commodity table.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
QuoteSourceType
The quote source type enum account types are used to determine how the transaction data in the accoun...
void gnc_commodity_set_user_symbol(gnc_commodity *cm, const char *user_symbol)
Set a user-defined symbol for the specified commodity.
void gnc_commodity_user_set_quote_flag(gnc_commodity *cm, const gboolean flag)
Set the automatic price quote flag for the specified commodity, based on user input.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
#define GNC_COMMODITY_NS_LEGACY
The commodity namespace definitions are used to tag a commodity by its type, or a stocks by the excha...
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
Retrieve the automatic price quote flag for the specified commodity.
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
Set the mnemonic for the specified commodity.
void gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
Set the automatic price quote timezone for the specified commodity.
QuoteSourceType gnc_quote_source_get_type(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the type of this particular quote source.
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
Return a list of all commodities in the commodity table that are in the given namespace.
gint gnc_quote_source_num_entries(QuoteSourceType type)
Return the number of entries for a given type of quote source.
@ SOURCE_MULTI
This quote source may pull from multiple web sites.
@ SOURCE_SINGLE
This quote source pulls from a single specific web site.
@ SOURCE_CURRENCY
The special currency quote source.
@ SOURCE_UNKNOWN
This is a locally installed quote source that gnucash knows nothing about.
void gnc_ui_select_commodity_changed_cb(GtkComboBox *cbwe, gpointer user_data)
This function is called whenever the commodity combo box is changed.
dialog_commodity_mode
The dialog commodity types are used to determine what commodity namespaces the currency dialog will p...
void gnc_ui_update_commodity_picker(GtkWidget *cbwe, const gchar *name_space, const gchar *init_string)
Given a combo box, fill in all the known commodities for the specified namespace, and then select one...
gnc_commodity * gnc_ui_select_commodity_modal(gnc_commodity *orig_sel, GtkWidget *parent, dialog_commodity_mode mode)
Ask the user to select a commodity from the existing set of commodities.
gnc_commodity * gnc_ui_new_commodity_modal_full(const char *name_space, GtkWidget *parent, const char *cusip, const char *fullname, const char *mnemonic, const char *user_symbol, int fraction)
Ask the user to provide the information necessary to create a new commodity.
gchar * gnc_ui_namespace_picker_ns(GtkWidget *cbwe)
Given a combo box, return the currently selected namespaces.
gboolean gnc_ui_edit_commodity_modal(gnc_commodity *commodity, GtkWidget *parent)
Given an existing commodity, uses the gnc_ui_build_commodity_dialog() routine to build a basic edit d...
void gnc_ui_select_commodity_new_cb(GtkButton *button, gpointer user_data)
This function is called whenever the user clicks on the "New" button in the commodity picker.
gnc_commodity * gnc_ui_new_commodity_modal(const char *default_namespace, GtkWidget *parent)
Ask the user to provide the information necessary to create a new commodity.
void gnc_ui_select_commodity_namespace_changed_cb(GtkComboBox *cbwe, gpointer user_data)
This function is called whenever the commodity namespace combo box is changed.
gnc_commodity * gnc_ui_select_commodity_modal_full(gnc_commodity *orig_sel, GtkWidget *parent, dialog_commodity_mode mode, const char *user_message, const char *cusip, const char *fullname, const char *mnemonic)
Ask the user to select a commodity from the existing set of commodities.
@ DIAG_COMM_NON_CURRENCY
Dialog box should allow selection of anything but a currency.
@ DIAG_COMM_CURRENCY
Dialog box should only allow selection of a currency.
@ DIAG_COMM_ALL
Dialog box should allow selection of anything.
@ DIAG_COMM_NON_CURRENCY_SELECT
Dialog box should allow selection of anything but a currency and should include the "ALL" namespace t...
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
QofBook reference.
Definition qofbook-p.hpp:47