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 }
100 }
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)
107 {
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 }
119 }
121 void
122 prefs_set_double_attribute(gchar const *path, gchar const *attr, double value)
123 {
124 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
125 if (repr) {
126 sp_repr_set_svg_double(repr, attr, value);
127 }
128 }
130 double
131 prefs_get_double_attribute(gchar const *path, gchar const *attr, double def)
132 {
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 }
139 }
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)
146 {
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 }
158 }
160 gchar const *
161 prefs_get_string_attribute(gchar const *path, gchar const *attr)
162 {
163 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
164 if (repr) {
165 return (char *) repr->attribute(attr);
166 }
167 return NULL;
168 }
170 void
171 prefs_set_string_attribute(gchar const *path, gchar const *attr, gchar const *value)
172 {
173 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
174 if (repr) {
175 repr->setAttribute(attr, value);
176 }
177 }
179 void
180 prefs_set_recent_file(gchar const *uri, gchar const *name)
181 {
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 }
215 }
217 gchar const **
218 prefs_get_recent_files()
219 {
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;
242 }
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 :