Code

merge inline patch from Jimmy
[inkscape.git] / src / prefs-utils.cpp
1 /*
2  * Utility functions for reading and setting preferences
3  *
4  * Authors:
5  *   bulia byak <bulia@dr.com>
6  *
7  * Copyright (C) 2003 authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
17 #include "inkscape.h"
18 #include "xml/repr.h"
20 /**
21 \brief Checks if the path exists in the preference file
22 */
23 bool pref_path_exists(gchar const *path){
24     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
25     return (repr != NULL);
26 }
28 /**
29 \brief returns the number of sub-prefs
30 */
31 unsigned int pref_path_number_of_children(gchar const *path){
32     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
33     Inkscape::XML::Node *child_repr = sp_repr_children(repr);
34     int nb_child = 0;
35     while (child_repr) {
36         nb_child ++;
37         child_repr = sp_repr_next(child_repr);
38     }
39     return nb_child;
40 }
42 /**
43 \brief creates a new preference and returns its key on success.
44 */
45 gchar * create_pref(gchar const *father_path, gchar const *child){
46     Inkscape::XML::Node *father = inkscape_get_repr(INKSCAPE, father_path);
47     if (! father ) return NULL;
48     Inkscape::XML::Node *repr = father->document()->createElement("group");
49     repr->setAttribute("id", child, false);
50     father->appendChild(repr);
51     return g_strdup_printf("%s.%s", father_path,child);
52 }
53 /**
54 \brief gets the list of children from a pref. Please free all that stuff after use.
55 */
56 bool get_pref_children(gchar const *father_path, GSList ** children){
57     Inkscape::XML::Node *father = inkscape_get_repr(INKSCAPE, father_path);
58     if (! father ) return false;
59     Inkscape::XML::Node *child_repr = sp_repr_children(father);  
60     while (child_repr) {
61         *children = g_slist_prepend(*children, g_strdup_printf("%s.%s",father_path,child_repr->attribute("id")));
62         child_repr = sp_repr_next(child_repr);
63     }
65 }
66 /**
67 \brief gets the nth children of a pref, starting from one (first child <=> n=1). returns NULL if out of bounds or father does not exist. Please free all that stuff after use.
68 */
69 gchar  *get_pref_nth_child(gchar const *father_path, unsigned int n){
70     if (n <= 0) return NULL;
71     Inkscape::XML::Node *father = inkscape_get_repr(INKSCAPE, father_path);
72     if (! father ) return NULL;
73     Inkscape::XML::Node *child_repr = sp_repr_children(father);  
74     unsigned int index = 0;
75     while (child_repr && (++index < n)) {
76         child_repr = sp_repr_next(child_repr);
77     }
78     if (child_repr) return g_strdup_printf("%s.%s",father_path,child_repr->attribute("id"));
79     return NULL;
80 }
82 void
83 prefs_set_int_attribute(gchar const *path, gchar const *attr, long long int value)
84 {
85     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
86     if (repr) {
87         sp_repr_set_int(repr, attr, value);
88     }
89 }
91 long long int
92 prefs_get_int_attribute(gchar const *path, gchar const *attr, long long int def)
93 {
94     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
95     if (repr) {
96         return sp_repr_get_int_attribute(repr, attr, def);
97     } else {
98         return def;
99     }
102 /**
103 \brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned
104 */
105 long long int
106 prefs_get_int_attribute_limited(gchar const *path, gchar const *attr, long long int def, long long int min, long long int max)
108     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
109     if (repr) {
110         long long int const v = sp_repr_get_int_attribute(repr, attr, def);
111         if (v >= min && v <= max) {
112             return v;
113         } else {
114             return def;
115         }
116     } else {
117         return def;
118     }
121 void
122 prefs_set_double_attribute(gchar const *path, gchar const *attr, double value)
124     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
125     if (repr) {
126         sp_repr_set_svg_double(repr, attr, value);
127     }
130 double
131 prefs_get_double_attribute(gchar const *path, gchar const *attr, double def)
133     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
134     if (repr) {
135         return sp_repr_get_double_attribute(repr, attr, def);
136     } else {
137         return def;
138     }
141 /**
142 \brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned
143 */
144 double
145 prefs_get_double_attribute_limited(gchar const *path, gchar const *attr, double def, double min, double max)
147     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
148     if (repr) {
149         double const v = sp_repr_get_double_attribute(repr, attr, def);
150         if (v >= min && v <= max) {
151             return v;
152         } else {
153             return def;
154         }
155     } else {
156         return def;
157     }
160 gchar const *
161 prefs_get_string_attribute(gchar const *path, gchar const *attr)
163     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
164     if (repr) {
165         return (char *) repr->attribute(attr);
166     }
167     return NULL;
170 void
171 prefs_set_string_attribute(gchar const *path, gchar const *attr, gchar const *value)
173     Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
174     if (repr) {
175         repr->setAttribute(attr, value);
176     }
179 void
180 prefs_set_recent_file(gchar const *uri, gchar const *name)
182     unsigned const max_documents = prefs_get_int_attribute("options.maxrecentdocuments", "value", 20);
184     if (uri != NULL) {
185         Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent");
186         if (recent) {
187             // remove excess recent files
188             if (recent->childCount() >= max_documents) {
189                 Inkscape::XML::Node *child = recent->firstChild();
190                 // count to the last
191                 for (unsigned i = 0; child && i + 1 < max_documents; ++i) {
192                     child = child->next();
193                 }
194                 // remove all after the last
195                 while (child) {
196                     Inkscape::XML::Node *next = child->next();
197                     sp_repr_unparent(child);
198                     child = next;
199                 }
200             }
202             if (max_documents > 0) {
203                 Inkscape::XML::Node *child = sp_repr_lookup_child(recent, "uri", uri);
204                 if (child) {
205                     recent->changeOrder(child, NULL);
206                 } else {
207                     child = recent->document()->createElement("document");
208                     child->setAttribute("uri", uri);
209                     recent->addChild(child, NULL);
210                 }
211                 child->setAttribute("name", name);
212             }
213         }
214     }
217 gchar const **
218 prefs_get_recent_files()
220     Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent");
221     if (recent) {
222         unsigned const docs = recent->childCount();
223         gchar const **datalst = (gchar const **) g_malloc(sizeof(gchar *) * ((docs * 2) + 1));
225         gint i;
226         Inkscape::XML::Node *child;
227         for (i = 0, child = recent->firstChild();
228              child != NULL;
229              child = child->next(), i += 2)
230         {
231             gchar const *uri = child->attribute("uri");
232             gchar const *name = child->attribute("name");
233             datalst[i]     = uri;
234             datalst[i + 1] = name;
235         }
237         datalst[i] = NULL;
238         return datalst;
239     }
241     return NULL;
244 /*
245   Local Variables:
246   mode:c++
247   c-file-style:"stroustrup"
248   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
249   indent-tabs-mode:nil
250   fill-column:99
251   End:
252 */
253 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :