GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-currency-edit.c
Go to the documentation of this file.
1 /*
2  * gnc-currency-edit.c -- Currency editor widget
3  *
4  * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
5  * All rights reserved.
6  *
7  * Gnucash is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public License
9  * as published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * Gnucash is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, contact:
19  *
20  * Free Software Foundation Voice: +1-617-542-5942
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
22  * Boston, MA 02110-1301, USA [email protected]
23  *
24  */
25 
58 #include "config.h"
59 
60 #include <gtk/gtk.h>
61 #include <string.h>
62 #include <ctype.h>
63 #include <stdio.h>
64 
65 #include "gnc-currency-edit.h"
66 #include "gnc-commodity.h"
67 #include "gnc-gtk-utils.h"
68 #include "gnc-ui-util.h"
69 #include "gnc-engine.h"
70 
72 static QofLogModule log_module = GNC_MOD_GUI;
73 
74 static void gnc_currency_edit_init (GNCCurrencyEdit *gce);
75 static void gnc_currency_edit_class_init (GNCCurrencyEditClass *klass);
76 static void gnc_currency_edit_finalize (GObject *object);
77 static void gnc_currency_edit_mnemonic_changed (GObject *gobject,
78  GParamSpec *pspec,
79  gpointer user_data);
80 static void gnc_currency_edit_active_changed (GtkComboBox *gobject,
81  gpointer user_data);
82 
83 static GtkComboBoxClass *parent_class;
84 
87 {
88  gchar *mnemonic;
90 
91 #define GET_PRIVATE(o) \
92  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_CURRENCY_EDIT, GNCCurrencyEditPrivate))
93 
97 /* Return the GType for the GNCCurrencyEdit currency selection widget.
98  */
99 GType
101 {
102  static GType currency_edit_type = 0;
103 
104  if (currency_edit_type == 0)
105  {
106  static const GTypeInfo currency_edit_info =
107  {
108  sizeof (GNCCurrencyEditClass),
109  NULL,
110  NULL,
111  (GClassInitFunc) gnc_currency_edit_class_init,
112  NULL,
113  NULL,
114  sizeof (GNCCurrencyEdit),
115  0, /* n_preallocs */
116  (GInstanceInitFunc) gnc_currency_edit_init,
117  NULL
118  };
119 
120  currency_edit_type = g_type_register_static (GTK_TYPE_COMBO_BOX,
121  "GNCCurrencyEdit",
122  &currency_edit_info, 0);
123  }
124 
125  return currency_edit_type;
126 }
127 
128 enum
129 {
130  PROP_0,
131 
132  PROP_GCE_MNEMONIC,
133 
134  N_PROPERTIES
135 };
136 
137 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
138 
139 static void
140 gnc_currency_edit_set_property (GObject *object,
141  guint property_id,
142  const GValue *value,
143  GParamSpec *pspec)
144 {
145  GNCCurrencyEdit *self = GNC_CURRENCY_EDIT (object);
146  GNCCurrencyEditPrivate *priv = GET_PRIVATE (self);
147 
148  switch (property_id)
149  {
150  case PROP_GCE_MNEMONIC:
151  g_free (priv->mnemonic);
152  priv->mnemonic = g_value_dup_string (value);
153  DEBUG ("mnemonic: %s\n", priv->mnemonic);
154  break;
155 
156  default:
157  /* We don't have any other property... */
158  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
159  break;
160  }
161 }
162 
163 static void
164 gnc_currency_edit_get_property (GObject *object,
165  guint property_id,
166  GValue *value,
167  GParamSpec *pspec)
168 {
169  GNCCurrencyEdit *self = GNC_CURRENCY_EDIT (object);
170  GNCCurrencyEditPrivate *priv = GET_PRIVATE (self);
171 
172  switch (property_id)
173  {
174  case PROP_GCE_MNEMONIC:
175  g_value_set_string (value, priv->mnemonic);
176  break;
177 
178  default:
179  /* We don't have any other property... */
180  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
181  break;
182  }
183 }
184 
185 
186 
187 
194 static void
195 gnc_currency_edit_class_init (GNCCurrencyEditClass *klass)
196 {
197  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
198  parent_class = g_type_class_peek_parent (klass);
199 
200  g_type_class_add_private(klass, sizeof(GNCCurrencyEditPrivate));
201 
202  gobject_class->set_property = gnc_currency_edit_set_property;
203  gobject_class->get_property = gnc_currency_edit_get_property;
204  gobject_class->finalize = gnc_currency_edit_finalize;
205 
206  obj_properties[PROP_GCE_MNEMONIC] =
207  g_param_spec_string ("mnemonic",
208  "Active currency's mnemonic",
209  "Active currency's mnemonic",
210  "USD" /* default value */,
211  G_PARAM_READWRITE);
212 
213  g_object_class_install_properties (gobject_class,
214  N_PROPERTIES,
215  obj_properties);
216 }
217 
218 
225 static void
226 gnc_currency_edit_init (GNCCurrencyEdit *gce)
227 {
228  g_signal_connect (gce, "notify::mnemonic",
229  G_CALLBACK (gnc_currency_edit_mnemonic_changed), gce);
230  g_signal_connect (gce, "changed",
231  G_CALLBACK (gnc_currency_edit_active_changed), gce);
232 }
233 
234 
245 static void
246 gnc_currency_edit_finalize (GObject *object)
247 {
249  GNCCurrencyEdit *period;
250 
251  g_return_if_fail (object != NULL);
252  g_return_if_fail (GNC_IS_CURRENCY_EDIT (object));
253 
254  period = GNC_CURRENCY_EDIT(object);
255  priv = GET_PRIVATE(period);
256 
257  g_free (priv->mnemonic);
258 
259  /* Do not free the private data structure itself. It is part of
260  * a larger memory block allocated by the type system. */
261 
262  if (G_OBJECT_CLASS(parent_class)->finalize)
263  (* G_OBJECT_CLASS(parent_class)->finalize) (object);
264 }
265 
266 
267 static void
268 gnc_currency_edit_mnemonic_changed (GObject *gobject,
269  GParamSpec *pspec,
270  gpointer user_data)
271 {
272 
273  GNCCurrencyEdit *self = GNC_CURRENCY_EDIT (gobject);
274  GNCCurrencyEditPrivate *priv = GET_PRIVATE (self);
275 
276  gnc_commodity *currency = gnc_commodity_table_lookup (gnc_get_current_commodities (),
277  GNC_COMMODITY_NS_CURRENCY,
278  priv->mnemonic);
279 
280  /* If there isn't any such commodity, get the default */
281  if (!currency)
282  {
283  currency = gnc_locale_default_currency();
284  DEBUG("gce %p, default currency mnemonic %s",
285  self, gnc_commodity_get_mnemonic(currency));
286  }
287 
288  g_signal_handlers_block_by_func(G_OBJECT(self),
289  G_CALLBACK(gnc_currency_edit_mnemonic_changed), user_data);
290  gnc_currency_edit_set_currency(self, currency);
291  g_signal_handlers_unblock_by_func(G_OBJECT(self),
292  G_CALLBACK(gnc_currency_edit_mnemonic_changed), user_data);
293 }
294 
295 
296 static void gnc_currency_edit_active_changed (GtkComboBox *gobject,
297  gpointer user_data)
298 {
299  GNCCurrencyEdit *self = GNC_CURRENCY_EDIT (gobject);
300  GNCCurrencyEditPrivate *priv = GET_PRIVATE (self);
301 
303  const gchar *mnemonic = gnc_commodity_get_mnemonic (currency);
304 
305  g_signal_handlers_block_by_func(G_OBJECT(self),
306  G_CALLBACK(gnc_currency_edit_active_changed), user_data);
307  g_object_set (G_OBJECT (self), "mnemonic", mnemonic, NULL);
308  g_signal_handlers_unblock_by_func(G_OBJECT(self),
309  G_CALLBACK(gnc_currency_edit_active_changed), user_data);
310 }
311 
322 static void
323 add_item(gnc_commodity *commodity, GNCCurrencyEdit *gce)
324 {
325  GtkTreeModel *model;
326  GtkTreeIter iter;
327  const char *string;
328 
329  model = gtk_combo_box_get_model(GTK_COMBO_BOX(gce));
330 
331  string = gnc_commodity_get_printname(commodity);
332 
333  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
334  gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, string, -1);
335 
336 }
337 
338 
347 static void
348 fill_currencies(GNCCurrencyEdit *gce)
349 {
350  GList *currencies;
351 
353  (gnc_get_current_commodities (), GNC_COMMODITY_NS_CURRENCY);
354  g_list_foreach(currencies, (GFunc)add_item, gce);
355  g_list_free(currencies);
356 }
357 
358 
359 /* Create a new GNCCurrencyEdit widget which can be used to provide
360  * an easy way to enter ISO currency codes.
361  *
362  * @return A GNCCurrencyEdit widget.
363  */
364 GtkWidget *
366 {
367  GNCCurrencyEdit *gce;
368  GtkListStore *store;
369 
370  store = gtk_list_store_new (1, G_TYPE_STRING);
371  gce = g_object_new (GNC_TYPE_CURRENCY_EDIT,
372  "model", store,
373  "has-entry", TRUE,
374  NULL);
375  g_object_unref (store);
376 
377  /* Set the column for the text */
378  gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(gce), 0);
379 
380  /* Now the signals to make sure the user can't leave the
381  widget without a valid currency. */
382  gnc_cbwe_require_list_item(GTK_COMBO_BOX(gce));
383 
384  /* Fill in all the data. */
385  fill_currencies (gce);
386  gtk_tree_sortable_set_sort_column_id
387  (GTK_TREE_SORTABLE(store), 0, GTK_SORT_ASCENDING);
388 
389  return GTK_WIDGET (gce);
390 }
391 
397 /* Set the widget to display a certain currency name.
398  *
399  * @param gce The currency editor widget to set.
400  *
401  * @param currency The currency to set as the displayed/selected
402  * value of the widget.
403  */
404 void
406  const gnc_commodity *currency)
407 {
408  const gchar *printname;
409 
410  g_return_if_fail(gce != NULL);
411  g_return_if_fail(GNC_IS_CURRENCY_EDIT(gce));
412  g_return_if_fail(currency != NULL);
413 
414  printname = gnc_commodity_get_printname(currency);
415  gnc_cbwe_set_by_string(GTK_COMBO_BOX(gce), printname);
416 }
417 
418 
419 /* Retrieve the displayed currency of the widget.
420  *
421  * @param gce The currency editor widget whose values should be retrieved.
422  *
423  * @return A pointer to the selected currency (a gnc_commodity
424  * structure).
425  */
428 {
429  gnc_commodity *commodity;
430  const char *fullname;
431  char *mnemonic, *name;
432  GtkTreeModel *model;
433  GtkTreeIter iter;
434  GValue value = { 0 };
435 
436  g_return_val_if_fail(gce != NULL, NULL);
437  g_return_val_if_fail(GNC_IS_CURRENCY_EDIT(gce), NULL);
438 
439  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(gce), &iter))
440  {
441  model = gtk_combo_box_get_model(GTK_COMBO_BOX(gce));
442  gtk_tree_model_get_value(model, &iter, 0, &value);
443  fullname = g_value_get_string(&value);
444  mnemonic = g_strdup(fullname);
445  g_value_unset(&value);
446 
447  name = strchr(mnemonic, ' ');
448  if (name != NULL)
449  *name = '\0';
450  commodity = gnc_commodity_table_lookup (gnc_get_current_commodities (),
451  GNC_COMMODITY_NS_CURRENCY,
452  mnemonic);
453  g_free(mnemonic);
454  }
455  else
456  {
457  g_warning("Combo box returned 'inactive'. Using locale default currency.");
458  commodity = gnc_locale_default_currency();
459  }
460 
461 
462  return commodity;
463 }
464 
void gnc_cbwe_set_by_string(GtkComboBox *cbwe, const gchar *text)
Definition: gnc-gtk-utils.c:41
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
utility functions for the GnuCash UI
GType gnc_currency_edit_get_type(void)
gtk helper routines.
#define DEBUG(format, args...)
Definition: qoflog.h:255
Currency selection widget.
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
All type declarations for the whole Gnucash engine.
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
GtkWidget * gnc_currency_edit_new(void)
Commodity handling public routines.
const gchar * QofLogModule
Definition: qofid.h:89
struct _GNCCurrencyEditPrivate GNCCurrencyEditPrivate