GnuCash  5.6-150-g038405b370+
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. */
52 static QofLogModule log_module = GNC_MOD_GUI;
53 
54 enum
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 
106 typedef struct select_commodity_window SelectCommodityWindow;
107 typedef struct commodity_window CommodityWindow;
108 
109 /* The commodity selection window */
110 static SelectCommodityWindow *
111 gnc_ui_select_commodity_create(const gnc_commodity * orig_sel,
112  dialog_commodity_mode mode);
113 void gnc_ui_select_commodity_new_cb(GtkButton * button,
114  gpointer user_data);
115 extern "C" {
116 void gnc_ui_select_commodity_changed_cb(GtkComboBox *cbwe,
117  gpointer user_data);
118 void gnc_ui_select_commodity_namespace_changed_cb(GtkComboBox *cbwe,
119  gpointer user_data);
120 
121 /* The commodity creation window */
122 void gnc_ui_commodity_changed_cb(GtkWidget * dummy, gpointer user_data);
123 void gnc_ui_commodity_quote_info_cb(GtkWidget *w, gpointer data);
124 }
125 gboolean gnc_ui_commodity_dialog_to_object(CommodityWindow * w);
126 
127 #if 0
128 static 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  ********************************************************************/
134 gnc_commodity *
135 gnc_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  ********************************************************************/
216 gnc_commodity *
217 gnc_ui_select_commodity_modal(gnc_commodity * orig_sel,
218  GtkWidget * parent,
220 {
221  return gnc_ui_select_commodity_modal_full(orig_sel,
222  parent,
223  mode,
224  nullptr,
225  nullptr,
226  nullptr,
227  nullptr);
228 }
229 
230 
231 /********************************************************************
232  * gnc_ui_select_commodity_create()
233  ********************************************************************/
234 static SelectCommodityWindow *
235 gnc_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;
285  case DIAG_COMM_CURRENCY:
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,
298  gnc_commodity_get_namespace(orig_sel),
299  mode);
300  name_space = gnc_ui_namespace_picker_ns(retval->namespace_combo);
301  gnc_ui_update_commodity_picker(retval->commodity_combo, name_space,
302  gnc_commodity_get_printname(orig_sel));
303 
304  g_object_unref(G_OBJECT(builder));
305 
306  g_free(name_space);
307  return retval;
308 }
309 
310 
325 void
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),
345  DIAG_COMM_ALL);
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 
369 void
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 
410 void
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  ********************************************************************/
429 static int
430 collate(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 
440 void
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  ********************************************************************/
504 static void
505 gnc_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 
520 static void
521 gnc_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 
528 static void
529 gnc_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 
544 static void
545 gnc_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  ********************************************************************/
555 void
556 gnc_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 
596  case DIAG_COMM_CURRENCY:
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 
657 gchar *
658 gnc_ui_namespace_picker_ns (GtkWidget *cbwe)
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  *******************************************************************/
679 void
680 gnc_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 
711 void
712 gnc_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  \*******************************************************************/
748 static GtkWidget *
749 gnc_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  {
771  max = gnc_quote_source_num_entries(type);
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, 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  *******************************************************************/
804 static const gchar *
805 known_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 
817 static guint
818 gnc_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 
839 static const gchar *
840 gnc_timezone_menu_position_to_string(guint pos)
841 {
842  if (pos == 0) return nullptr;
843  return known_timezones[pos - 1];
844 }
845 
846 
847 static GtkWidget *
848 gnc_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  *******************************************************/
874 static CommodityWindow *
875 gnc_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 
1047 static void
1048 gnc_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]),
1071  gnc_quote_source_get_index(source));
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 
1087 static gnc_commodity *
1088 gnc_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  ********************************************************/
1168 gnc_commodity *
1169 gnc_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  ********************************************************************/
1191 gnc_commodity *
1192 gnc_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  ********************************************************************/
1213 gboolean
1214 gnc_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  ********************************************************************/
1230 gboolean
1231 gnc_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  return TRUE;
1272  }
1273  gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s",
1274  _("You may not create a new national currency."));
1275  return FALSE;
1276  }
1277 
1278  /* Don't allow user to create commodities in namespace
1279  * "template". That's reserved for scheduled transaction use.
1280  */
1281  if (g_utf8_collate(name_space, GNC_COMMODITY_NS_TEMPLATE) == 0)
1282  {
1283  gnc_warning_dialog (GTK_WINDOW (w->dialog),
1284  _("%s is a reserved commodity type."
1285  " Please use something else."), GNC_COMMODITY_NS_TEMPLATE);
1286  return FALSE;
1287  }
1288 
1289  if (fullname && fullname[0] &&
1290  name_space && name_space[0] &&
1291  mnemonic && mnemonic[0])
1292  {
1293  c = gnc_commodity_table_lookup (gnc_get_current_commodities(),
1294  name_space, mnemonic);
1295 
1296  if ((!w->edit_commodity && c) ||
1297  (w->edit_commodity && c && (c != w->edit_commodity)))
1298  {
1299  gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s", _("That commodity already exists."));
1300  g_free(name_space);
1301  return FALSE;
1302  }
1303 
1304  if (!w->edit_commodity)
1305  {
1306  c = gnc_commodity_new(book, fullname, name_space, mnemonic, code, fraction);
1307  w->edit_commodity = c;
1308  gnc_commodity_begin_edit(c);
1309 
1310  gnc_commodity_set_user_symbol(c, user_symbol);
1311  }
1312  else
1313  {
1314  c = w->edit_commodity;
1315  gnc_commodity_begin_edit(c);
1316 
1317  gnc_commodity_table_remove (gnc_get_current_commodities(), c);
1318 
1319  gnc_commodity_set_fullname (c, fullname);
1320  gnc_commodity_set_mnemonic (c, mnemonic);
1321  gnc_commodity_set_namespace (c, name_space);
1322  gnc_commodity_set_cusip (c, code);
1323  gnc_commodity_set_fraction (c, fraction);
1324  gnc_commodity_set_user_symbol(c, user_symbol);
1325  }
1326 
1327  gnc_commodity_user_set_quote_flag (c, gtk_toggle_button_get_active
1328  (GTK_TOGGLE_BUTTON (w->get_quote_check)));
1329 
1330  for (type = SOURCE_SINGLE; type < SOURCE_MAX; type = static_cast<QuoteSourceType>(type+1))
1331  {
1332  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->source_button[type])))
1333  break;
1334  }
1335  selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->source_menu[type]));
1336  source = gnc_quote_source_lookup_by_ti (type, selection);
1337  gnc_commodity_set_quote_source(c, source);
1338 
1339  selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->quote_tz_menu));
1340  string = gnc_timezone_menu_position_to_string(selection);
1341  gnc_commodity_set_quote_tz(c, string);
1342  gnc_commodity_commit_edit(c);
1343 
1344  /* remember the commodity */
1345  gnc_commodity_table_insert(gnc_get_current_commodities(), c);
1346  }
1347  else
1348  {
1349  gnc_warning_dialog (GTK_WINDOW (w->dialog), "%s",
1350  _("You must enter a non-empty \"Full name\", "
1351  "\"Symbol/abbreviation\", "
1352  "and \"Type\" for the commodity."));
1353  g_free(name_space);
1354  return FALSE;
1355  }
1356  g_free(name_space);
1357  LEAVE(" ");
1358  return TRUE;
1359 }
1360 
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_cusip(const gnc_commodity *cm)
Retrieve the &#39;exchange code&#39; for the specified commodity.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
Dialog box should only allow selection of a currency.
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...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
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...
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
This quote source pulls from a single specific web site.
Dialog box should allow selection of anything but a currency.
utility functions for the GnuCash UI
gtk helper routines.
gchar * gnc_ui_namespace_picker_ns(GtkWidget *cbwe)
Given a combo box, return the currently selected namespaces.
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
Retrieve the automatic price quote flag 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.
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.
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
Retrieve the automatic price quote timezone for the specified commodity.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
Set the fraction 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...
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...
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...
The special currency quote source.
This is a locally installed quote source that gnucash knows nothing about.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
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.
QuoteSourceType
The quote source type enum account types are used to determine how the transaction data in the accoun...
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...
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
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.
void gnc_commodity_set_user_symbol(gnc_commodity *cm, const char *user_symbol)
Set a user-defined symbol for the specified commodity.
Dialog box should allow selection of anything.
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
Set the automatic price quote source for the specified commodity.
gint gnc_quote_source_num_entries(QuoteSourceType type)
Return the number of entries for a given type of quote source.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome&#39;s yelp for linux, and open to a given link within a gi...
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
Dialog box should allow selection of anything but a currency and should include the "ALL" namespace t...
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...
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
Set the &#39;exchange code&#39; for the specified commodity.
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.
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.
dialog_commodity_mode
The dialog commodity types are used to determine what commodity namespaces the currency dialog will p...
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_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
#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_nice_symbol(const gnc_commodity *cm)
Retrieve a symbol for the specified commodity, suitable for display to the user.
void gnc_ui_select_commodity_changed_cb(GtkComboBox *cbwe, gpointer user_data)
This function is called whenever the commodity combo box is changed.
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.
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.
All type declarations for the whole Gnucash engine.
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.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the &#39;print&#39; name for the specified commodity.
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
Set the full name for the specified commodity.
This quote source may pull from multiple web sites.
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
Retrieve the automatic price quote source for the specified commodity.
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
Set the mnemonic 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 ...
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
void gnc_commodity_table_remove(gnc_commodity_table *table, gnc_commodity *comm)
Remove a commodity from the commodity table.
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
Set the namespace for the specified commodity.
void gnc_ui_update_namespace_picker(GtkWidget *cbwe, const gchar *sel, dialog_commodity_mode mode)
Given a combo box, fill in the known commodity namespaces and then select one.
"select" and "new" commodity windows
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
gboolean gnc_quote_source_fq_installed(void)
This function indicates whether or not the Finance::Quote module is installed on a user&#39;s computer...