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