Andy Den Tandt adtlist_qsd at
Thu Apr 30 15:45:24 EDT 2009

My feeling is that there will also be cases where preferences are defined
two/three places. E.g. a global user preference could be overruled in a
specific book. Eg. A user can have his date/time/number preferences and have
one book that requires a different convention.

Phil, you've been through Bugzilla, so I leave it up to your judgment
whether this is a common case that we should think about in advance, or
whether it's more exceptional and thus better handled in an ad-hoc manner. 


-----Oorspronkelijk bericht-----
Van: gnucash-devel-bounces at
[mailto:gnucash-devel-bounces at] Namens Derek Atkins
Verzonden: woensdag 29 april 2009 22:22
Aan: Phil Longstaff
CC: GnuCash development list
Onderwerp: Re: Preferences


Quoting Phil Longstaff <plongstaff at>:

> A number of bugs in bugzilla reference the idea of splitting global 
> preferences from per-file preferences, so I thought I would take a 
> stab at this.  Here's my design idea, and I'm looking for any 
> response/feedback:
> 1) Preferences are currently stored in gconf.  Global preferences 
> will continue to be stored there, but local preferences will be 
> stored as kvp entries of the QofBook.  This is per-file, uses 
> existing mechanisms (I'll need to check that the xml/dbi backends 
> load/save book kvp entries) and fits with the gconf/preferences 
> hierarchical nature.

Note that there are really three categories for preferences/properties:

1) Global for a user (Applies for a specific user to all data files)
2) Specific to a data file (Applies to a specific data file for all users)
3) Per-user, Per-Datafile (Applies to a specific user using a specific
   data file).

Your proposal only touches #1 and #2, but I do think we need to handle
#3 as well.  For example, "current open reports" probably belongs in
this category, and I'm sure we can come up with more values that
belong here instead of #1 or #2.

Also note that we do have the File -> Properties which are like preferences
and stored in the Book KVP.

> 2) Over the past few years, I've grown to really like the interface 
> idea when two pieces of code need to interact.  It allows one module 
> to use another module's services while only having a dependence on 
> the interface, not the implementation behind it.  Therefore, I'll 
> create a GncPrefs GObject-based interface (GInterface - is that the 
> right term?) with get_string/boolean/double/int and 
> set_string/boolean/double/int methods.

Sounds like a good approach to me.

> 3) A GncPrefsFromGconf GObject will be created and will implement 
> GncPrefs.  This object will interact with gconf (will replace the 
> gnc_gconf_xxx() functions).
> 4) A GncPrefsFromQofBook GObject will be created and will implement 
> GncPrefs.  For a set operation, this will store the value into the 
> QofBook kvp frames.  For a get operation, this will look for the 
> value in the QofBook kvp frames.  If found, it will be returned.  If 
> not found, it will relay the request to the global prefs to get the 
> value from gconf and then will set the value in the QofBook kvp 
> frames.  This will handle transfering values which are currently 
> global and make them local.  If the key is not found globally, a 
> default value will be returned.

I'm wondering if it would be better to do the migration only once,
like when the data file is loaded.  If the Book Prefs KVP doesn't exist
prompt the user to upgrade and if so do the migration (or perhaps
do the migration anyways and just inform the user you've done it).

> 5) New routines GncPrefs* qof_session_get_local_prefs() and GncPrefs* 
> qof_session_get_global_prefs() will return the local and global 
> prefs, respectively.

See above about prefs object #3.

> 6) I don't think anything needs to be done for a newly created book.  
> For current installations, #4 will copy global values from gconf to 
> the book and then they will be used from the book from that time 
> forward.  For new installations with no current gconf values, the 
> defaults will be used until they are changed.
> Of course, then there is the decision about which current prefs stay 
> global and which become local.  I haven't looked into that yet, but 
> when I do, I'll make a proposal.

There's also the question of how you define the prefs..  And how you know
where something is supposed to live.  Right now the user of the pref
needs to know where it lives so you would need to do something like:

  GncPref* gnc_get_global_pref(const char *prefpage, const char *prefname);
  GncPref* gnc_get_book_pref(QofBook*, const char*, const char *);
  GncPref* gnc_get_user_book_pref(QofBook*, const char*, const char*);

Then of course we would need to define the set of prefs in each
PrefsSet, so there's the Global prefs set, Book PrefsSet, and the
User/Book PrefsSet.  So we would need a registration procedure so
that GnuCash can register preferences settings in each section.

That preference definition could contain the page, name, tooltip,
default value, etc for each preference.

If we want to abstract out the pref location (Global, Book, or UserBook)
from the caller/user of the pref then we need to assure that a pref
isn't duplicated anywhere and DEFINITELY need a "global" registry.

> Phil


       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL:    PP-ASEL-IA     N1NWH
       warlord at MIT.EDU                        PGP key available

gnucash-devel mailing list
gnucash-devel at

More information about the gnucash-devel mailing list