[edit] Where preferences are stored
Preferences are stored in an XML file called
~/.inkscape/preferences.xml
on Linux or
Documents and Settings/USER/Application Data/Inkscape/preferences.xml
on Windows. Note that the Windows path is supposed to be relative to Inkscape program directory.
This file stores the hierarchy of values. Each value is in an attribute belonging to one of the elements, and elements with attributes are usually grouped together by top-level elements. Note that all elements have unique id attributes.
[edit] Find a place for your value
When creating a new preference value, start by examining this file and finding a logical place for the new value. For example, if I want to add a value for some option related to the selector.
This is what I did when I decided to store a value of the nudge distance (the distance of one arrow-key jump). This value is not local to any single tool; it is used in selector and node editor and will likely be used in other tools as well. So I created a new top-level element for all such global options and put my value there like so:
<group id="options"> <group id="nudgedistance" value="2.8346457"/> </group>
Here, 2.8346457 is the distance in points that is equal to 1 mm. Note:
- Element names actually do not matter. What matters for finding the value is the id attribute values. So you can use group elements or any others, whatever seems more logical.
- Values are stored in attributes. No text within elements is allowed (except whitespace).
[edit] Add the value to the skeleton
When no preferences file exists, a new one is created based on src/preferences-skeleton.h. Moreover, if the preferences file lacks some values, the defaults are taken from the same file. So, I edit this file adding
" <group id=\"options\">" " <group id=\"nudgedistance\" value=\"2.8346457\"/>" " </group>").
[edit] Access the value in the program
Now for the interesting part. If you want to access your value in the program, start by adding
#include "prefs-utils.h"
to the header. Now, create a variable:
double nudge;
and right before it is going to be used, update it from the preferences like so:
nudge = prefs_get_double_attribute ("options.nudgedistance", "value", 2.8346457);
What this call does is reads the value from the memory representation of preferences.xml. This representation was created on program start, may be used or modified by changing any values in it, and will be written back into preferences.xml when the program exits. (FIXME: do we need a menu command for saving preferences?)
To pinpoint the value we need, you pass to this function a text string in a syntax that is vaguely reminiscent of XPath, except that it uses id attribute values instead of element names and a dot instead of / as a separator. That is, options.nudgedistance means, find top-level element with id="options" and within it, an element with id="nudgedistance". The second argument to the prefs_get_double_attribute is the name of the attribute that we are interested in. The third argument is the default value which will be returned if no such value is stored in the preferences.
It is important that this prefs_get_double_attribute call is done before each use of the value, and not just once upon program launch, because the preferences may be edited by the user via a dialog (see below for more on that) and we want the interface to respond to these changes immediately.
Similarly, to write a new value back into the preferences' memory representation, use
prefs_set_double_attribute ("options.nudgedistance", "value", new_nudge);
Instead of double values, you can store and retrieve ints (more precisely, gints) by
gint prefs_get_int_attribute (gchar *path, gchar *attr, default); void prefs_set_int_attribute (gchar *path, gchar *attr, new_value);
or strings by
gchar const *prefs_get_string_attribute (gchar const *path, gchar const *attr); void prefs_set_string_attribute (gchar const *path, gchar const *attr, gchar const *value);
[edit] Guard against screw-ups
Sometimes there may be very weird values stored in the preferences file, which may cause trouble to the program. It is wise to guard against them by providing min and max bounds for your value. Here's how:
gint prefs_get_int_attribute_limited (gchar *path, gchar *attr, gint def, gint min, gint max); double prefs_get_double_attribute_limited (gchar *path, gchar *attr, double def, double min, double max);
These functions will return def if the value stored in the preferences is less than min or greater than max. Be generous in setting limits, but be sure to test that with the value set to any of the limits program does not crash.
[edit] Add a ( "options.nudgedistance", "value",