r16730 - gnucash/trunk/src - Allow the user to permanently disable currency quotes (#499496)

Derek Atkins warlord at cvs.gnucash.org
Wed Dec 26 00:17:38 EST 2007


Author: warlord
Date: 2007-12-26 00:17:37 -0500 (Wed, 26 Dec 2007)
New Revision: 16730
Trac: http://svn.gnucash.org/trac/changeset/16730

Modified:
   gnucash/trunk/src/engine/Account.c
   gnucash/trunk/src/engine/Period.c
   gnucash/trunk/src/engine/gnc-commodity.c
   gnucash/trunk/src/engine/gnc-commodity.h
   gnucash/trunk/src/gnome-utils/dialog-commodity.c
Log:
Allow the user to permanently disable currency quotes (#499496)
Patch by Daniel Harding

Modified: gnucash/trunk/src/engine/Account.c
===================================================================
--- gnucash/trunk/src/engine/Account.c	2007-12-26 03:28:09 UTC (rev 16729)
+++ gnucash/trunk/src/engine/Account.c	2007-12-26 05:17:37 UTC (rev 16730)
@@ -871,6 +871,7 @@
     /* The new book should contain a commodity that matches
      * the one in the old book. Find it, use it. */
     priv->commodity = gnc_commodity_obtain_twin(from_priv->commodity, book);
+    gnc_commodity_increment_usage_count(priv->commodity);
 
     priv->commodity_scu = from_priv->commodity_scu;
     priv->non_standard_scu = from_priv->non_standard_scu;
@@ -1004,6 +1005,7 @@
   priv->reconciled_balance = gnc_numeric_zero();
 
   priv->type = ACCT_TYPE_NONE;
+  gnc_commodity_decrement_usage_count(priv->commodity);
   priv->commodity = NULL;
 
   priv->balance_dirty = FALSE;
@@ -2066,7 +2068,9 @@
       return;
 
   xaccAccountBeginEdit(acc);
+  gnc_commodity_decrement_usage_count(priv->commodity);
   priv->commodity = com;
+  gnc_commodity_increment_usage_count(com);
   priv->commodity_scu = gnc_commodity_get_fraction(com);
   priv->non_standard_scu = FALSE;
 
@@ -2085,15 +2089,6 @@
   priv->balance_dirty = TRUE;
   mark_account (acc);
 
-  if (gnc_commodity_is_iso(com)) {
-    /* compatability hack - Gnucash 1.8 gets currency quotes when a
-       non-default currency is assigned to an account.  */
-	gnc_commodity_begin_edit(com);
-    gnc_commodity_set_quote_flag(com, TRUE);
-    gnc_commodity_set_quote_source(com, 
-        gnc_commodity_get_default_quote_source(com));
-	gnc_commodity_commit_edit(com);
-  }
   xaccAccountCommitEdit(acc);
 }
 

Modified: gnucash/trunk/src/engine/Period.c
===================================================================
--- gnucash/trunk/src/engine/Period.c	2007-12-26 03:28:09 UTC (rev 16729)
+++ gnucash/trunk/src/engine/Period.c	2007-12-26 05:17:37 UTC (rev 16730)
@@ -538,7 +538,7 @@
    /* Next, copy the commodity tables */
    src_tbl = gnc_commodity_table_get_table (src_book);
    dst_tbl = gnc_commodity_table_get_table (dest_book);
-   gnc_commodity_table_copy (dst_tbl, src_tbl);
+   gnc_commodity_table_copy (dst_tbl, src_tbl, dest_book);
 
    /* Next, copy all of the accounts */
    /* hack alert -- FIXME -- this should really be a merge, not a

Modified: gnucash/trunk/src/engine/gnc-commodity.c
===================================================================
--- gnucash/trunk/src/engine/gnc-commodity.c	2007-12-26 03:28:09 UTC (rev 16729)
+++ gnucash/trunk/src/engine/gnc-commodity.c	2007-12-26 05:17:37 UTC (rev 16730)
@@ -61,6 +61,10 @@
   gboolean  quote_flag;	    /* user wants price quotes */
   gnc_quote_source * quote_source;   /* current/old source of quotes */
   char    * quote_tz;
+
+  /* the number of accounts using this commodity - this field is not
+   * persisted */
+  int       usage_count;
 };
 
 struct _GncCommodityClass
@@ -624,6 +628,17 @@
 
   cm->mark = 0;
 
+#if !ACCOUNTS_CLEANED_UP
+  /* Account objects are not actually cleaned up when a book is closed (in fact
+   * a memory leak), but commodities are, so in currently this warning gets hit
+   * quite frequently.  Disable the check until cleaning up of accounts objects
+   * on close is implemented.  */
+  if(cm->usage_count != 0) {
+      PWARN("Destroying commodity (%p) with non-zero usage_count (%d).", cm,
+              cm->usage_count);
+  }
+#endif
+
   /* qof_instance_release (&cm->inst); */
   g_object_unref(cm);
 }
@@ -638,13 +653,15 @@
   gnc_commodity_set_quote_flag (dest, src->quote_flag);
   gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src));
   gnc_commodity_set_quote_tz (dest, src->quote_tz);
+  kvp_frame_delete (dest->inst.kvp_data);
+  dest->inst.kvp_data = kvp_frame_copy (src->inst.kvp_data);
 }
 
 gnc_commodity *
-gnc_commodity_clone(gnc_commodity *src)
+gnc_commodity_clone(gnc_commodity *src, QofBook *dest_book)
 {
   gnc_commodity * dest = g_object_new(GNC_TYPE_COMMODITY, NULL);
-  /* qof_instance_init_data (&dest->inst, GNC_ID_COMMODITY, src->inst.book); */
+  qof_instance_init_data (&dest->inst, GNC_ID_COMMODITY, dest_book);
 
   dest->fullname = CACHE_INSERT(src->fullname);
   dest->mnemonic = CACHE_INSERT(src->mnemonic);
@@ -659,6 +676,9 @@
 
   gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src));
 
+  kvp_frame_delete (dest->inst.kvp_data);
+  dest->inst.kvp_data = kvp_frame_copy (src->inst.kvp_data);
+
   reset_printname(dest);
   reset_unique_name(dest);
 
@@ -775,6 +795,21 @@
 }
 
 /********************************************************************
+ * gnc_commodity_get_auto_quote_control_flag
+ ********************************************************************/
+
+static gboolean
+gnc_commodity_get_auto_quote_control_flag(const gnc_commodity *cm)
+{
+  const char *str;
+
+  if(!cm) return FALSE;
+
+  str = kvp_frame_get_string(cm->inst.kvp_data, "auto_quote_control");
+  return !str || (strcmp(str, "false") != 0);
+}
+
+/********************************************************************
  * gnc_commodity_get_quote_flag
  ********************************************************************/
 
@@ -929,6 +964,60 @@
 }
 
 /********************************************************************
+ * gnc_commodity_set_auto_quote_control_flag
+ ********************************************************************/
+
+static void
+gnc_commodity_set_auto_quote_control_flag(gnc_commodity *cm,
+                                          const gboolean flag)
+{
+  ENTER ("(cm=%p, flag=%d)", cm, flag);
+
+  if(!cm) {
+    LEAVE("");
+    return;
+  }
+
+  gnc_commodity_begin_edit(cm);
+  kvp_frame_set_string(cm->inst.kvp_data,
+                       "auto_quote_control", flag ? NULL : "false");
+  mark_commodity_dirty(cm);
+  gnc_commodity_commit_edit(cm);
+  LEAVE("");
+}
+
+/********************************************************************
+ * gnc_commodity_user_set_quote_flag
+ ********************************************************************/
+
+void
+gnc_commodity_user_set_quote_flag(gnc_commodity *cm, const gboolean flag)
+{
+  ENTER ("(cm=%p, flag=%d)", cm, flag);
+
+  if(!cm) {
+    LEAVE("");
+    return;
+  }
+
+  gnc_commodity_begin_edit(cm);
+  gnc_commodity_set_quote_flag(cm, flag);
+  if(gnc_commodity_is_iso(cm)) {
+    /* For currencies, disable auto quote control if the quote flag is being
+     * changed from its default value and enable it if the quote flag is being
+     * reset to its default value.  The defaults for the quote flag are
+     * disabled if no accounts are using the currency, and true otherwise.
+     * Thus enable auto quote control if flag is FALSE and there are not any
+     * accounts using this currency OR flag is TRUE and there are accounts
+     * using this currency; otherwise disable auto quote control */
+    gnc_commodity_set_auto_quote_control_flag(cm,
+        (!flag && (cm->usage_count == 0)) || (flag && (cm->usage_count != 0)));
+  }
+  gnc_commodity_commit_edit(cm);
+  LEAVE("");
+}
+
+/********************************************************************
  * gnc_commodity_set_quote_flag
  ********************************************************************/
 
@@ -981,6 +1070,70 @@
   LEAVE(" ");
 }
 
+/********************************************************************
+ * gnc_commodity_increment_usage_count
+ ********************************************************************/
+
+void
+gnc_commodity_increment_usage_count(gnc_commodity *cm)
+{
+  const char *str;
+
+  ENTER("(cm=%p)", cm);
+
+  if(!cm) {
+    LEAVE("");
+    return;
+  }
+
+  if((cm->usage_count == 0) && !cm->quote_flag
+      && gnc_commodity_get_auto_quote_control_flag(cm)
+      && gnc_commodity_is_iso(cm)) {
+    /* compatability hack - Gnucash 1.8 gets currency quotes when a
+       non-default currency is assigned to an account.  */
+    gnc_commodity_begin_edit(cm);
+    gnc_commodity_set_quote_flag(cm, TRUE);
+    gnc_commodity_set_quote_source(cm,
+        gnc_commodity_get_default_quote_source(cm));
+    gnc_commodity_commit_edit(cm);
+  }
+  cm->usage_count++;
+  LEAVE("(usage_count=%d)", cm->usage_count);
+}
+
+/********************************************************************
+ * gnc_commodity_decrement_usage_count
+ ********************************************************************/
+
+void
+gnc_commodity_decrement_usage_count(gnc_commodity *cm)
+{
+  const char *str;
+
+  ENTER("(cm=%p)", cm);
+
+  if(!cm) {
+    LEAVE("");
+    return;
+  }
+
+  if(cm->usage_count == 0) {
+    PWARN("usage_count already zero");
+    LEAVE("");
+    return;
+  }
+
+  cm->usage_count--;
+  if((cm->usage_count == 0) && cm->quote_flag
+      && gnc_commodity_get_auto_quote_control_flag(cm)
+      && gnc_commodity_is_iso(cm)) {
+    /* if this is a currency with auto quote control enabled and no more
+     * accounts reference this currency, disable quote retrieval */
+    gnc_commodity_set_quote_flag(cm, FALSE);
+  }
+  LEAVE("(usage_count=%d)", cm->usage_count);
+}
+
 /********************************************************************\
 \********************************************************************/
 
@@ -1122,7 +1275,7 @@
   twin = gnc_commodity_table_lookup_unique (comtbl, ucom);
   if (!twin)
   {
-    twin = gnc_commodity_clone (from);
+    twin = gnc_commodity_clone (from, book);
     twin = gnc_commodity_table_insert (comtbl, twin);
   }
   return twin;
@@ -1779,19 +1932,27 @@
 
 /* =========================================================== */
 
+typedef struct {
+  gnc_commodity_table *dest;
+  QofBook *dest_book;
+} table_copy_helper_data;
+
 static gboolean 
 table_copy_helper (gnc_commodity *src_cm, gpointer user_data)
 {
-  gnc_commodity_table *dest = user_data;
-  gnc_commodity_table_insert (dest, gnc_commodity_clone (src_cm));
+  table_copy_helper_data *data = user_data;
+  gnc_commodity_table_insert (data->dest,
+      gnc_commodity_clone (src_cm, data->dest_book));
   return TRUE;
 }
 
 void
 gnc_commodity_table_copy(gnc_commodity_table *dest,
-                          gnc_commodity_table *src)
+                          gnc_commodity_table *src,
+                          QofBook *dest_book)
 {
-  gnc_commodity_table_foreach_commodity (src, table_copy_helper, dest);
+  table_copy_helper_data data = {dest, dest_book};
+  gnc_commodity_table_foreach_commodity (src, table_copy_helper, &data);
 }
 
 /********************************************************************

Modified: gnucash/trunk/src/engine/gnc-commodity.h
===================================================================
--- gnucash/trunk/src/engine/gnc-commodity.h	2007-12-26 03:28:09 UTC (rev 16729)
+++ gnucash/trunk/src/engine/gnc-commodity.h	2007-12-26 05:17:37 UTC (rev 16730)
@@ -312,7 +312,7 @@
 void  gnc_commodity_copy(gnc_commodity * dest, gnc_commodity *src);
 
 /** allocate and copy */
-gnc_commodity * gnc_commodity_clone(gnc_commodity *src);
+gnc_commodity * gnc_commodity_clone(gnc_commodity *src, QofBook *dest_book);
 /** @} */
 
 
@@ -547,6 +547,23 @@
  */
 void  gnc_commodity_set_fraction(gnc_commodity * cm, int smallest_fraction);
 
+/** Set the automatic price quote flag for the specified commodity,
+ *  based on user input. This flag indicates whether stock quotes
+ *  should be retrieved for the specified stock.
+ *
+ *  It is necessary to have a separate function to distinguish when
+ *  this setting is being modified by a user so that the
+ *  auto-enabling/auto-disabling of currencies can be handled
+ *  properly.
+ *
+ *  @param cm A pointer to a commodity data structure.
+ *
+ *  @param flag TRUE if quotes should be pulled for this commodity, FALSE
+ *  otherwise.
+ */
+void  gnc_commodity_user_set_quote_flag(gnc_commodity *cm,
+                                        const gboolean flag);
+
 /** Set the automatic price quote flag for the specified commodity.
  *  This flag indicates whether stock quotes should be retrieved for
  *  the specified stock.
@@ -584,7 +601,30 @@
 /** @} */
 
 
+/** @name Commodity Usage Count Adjustment Routines
+@{
+*/
 
+/** Increment a commodity's internal counter that tracks how many
+ *  accounts are using that commodity.  For currencies, this may have
+ *  the side effect of enabling the commodity's quote flag.
+ *
+ *  @param cm A pointer to a commodity data structure.
+ */
+void
+gnc_commodity_increment_usage_count(gnc_commodity *cm);
+
+/** Decrement a commodity's internal counter that tracks how many
+ *  accounts are using that commodity.  For currencies, this may have
+ *  the side effect of disabling the commodity's quote flag.
+ *
+ *  @param cm A pointer to a commodity data structure.
+ */
+void
+gnc_commodity_decrement_usage_count(gnc_commodity *cm);
+/** @} */
+
+
 /** @name Commodity Comparison 
  @{
 */
@@ -653,7 +693,8 @@
 
 /** copy all commodities from src table to dest table */
 void gnc_commodity_table_copy(gnc_commodity_table *dest,
-                              gnc_commodity_table *src);
+                              gnc_commodity_table *src,
+                              QofBook *dest_book);
 /** @} */
 /* ---------------------------------------------------------- */
 /** @name Commodity Table Lookup functions

Modified: gnucash/trunk/src/gnome-utils/dialog-commodity.c
===================================================================
--- gnucash/trunk/src/gnome-utils/dialog-commodity.c	2007-12-26 03:28:09 UTC (rev 16729)
+++ gnucash/trunk/src/gnome-utils/dialog-commodity.c	2007-12-26 05:17:37 UTC (rev 16730)
@@ -1194,7 +1194,7 @@
     if (w->edit_commodity) {
       c = w->edit_commodity;
       gnc_commodity_begin_edit(c);
-      gnc_commodity_set_quote_flag (c, gtk_toggle_button_get_active
+      gnc_commodity_user_set_quote_flag (c, gtk_toggle_button_get_active
 				    (GTK_TOGGLE_BUTTON (w->get_quote_check)));
       selection = gtk_combo_box_get_active(GTK_COMBO_BOX(w->quote_tz_menu));
       string = gnc_timezone_menu_position_to_string(selection);
@@ -1237,7 +1237,7 @@
       gnc_commodity_set_fraction (c, fraction);
     }
 
-    gnc_commodity_set_quote_flag (c, gtk_toggle_button_get_active
+    gnc_commodity_user_set_quote_flag (c, gtk_toggle_button_get_active
 				  (GTK_TOGGLE_BUTTON (w->get_quote_check)));
 
     for (type = SOURCE_SINGLE; type < SOURCE_MAX; type++) {



More information about the gnucash-changes mailing list