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 }
54 /**
55 \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.
56 */
57 gchar *get_pref_nth_child(gchar const *father_path, unsigned int n){
58 if (n <= 0) return NULL;
59 Inkscape::XML::Node *father = inkscape_get_repr(INKSCAPE, father_path);
60 if (! father ) return NULL;
61 Inkscape::XML::Node *child_repr = sp_repr_children(father);
62 unsigned int index = 0;
63 while (child_repr && (++index < n)) {
64 child_repr = sp_repr_next(child_repr);
65 }
66 if (child_repr) return g_strdup_printf("%s.%s",father_path,child_repr->attribute("id"));
67 return NULL;
68 }
70 void
71 prefs_set_int_attribute(gchar const *path, gchar const *attr, long long int value)
72 {
73 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
74 if (repr) {
75 sp_repr_set_int(repr, attr, value);
76 }
77 }
79 long long int
80 prefs_get_int_attribute(gchar const *path, gchar const *attr, long long int def)
81 {
82 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
83 if (repr) {
84 return sp_repr_get_int_attribute(repr, attr, def);
85 } else {
86 return def;
87 }
88 }
90 /**
91 \brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned
92 */
93 long long int
94 prefs_get_int_attribute_limited(gchar const *path, gchar const *attr, long long int def, long long int min, long long int max)
95 {
96 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
97 if (repr) {
98 long long int const v = sp_repr_get_int_attribute(repr, attr, def);
99 if (v >= min && v <= max) {
100 return v;
101 } else {
102 return def;
103 }
104 } else {
105 return def;
106 }
107 }
109 void
110 prefs_set_double_attribute(gchar const *path, gchar const *attr, double value)
111 {
112 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
113 if (repr) {
114 sp_repr_set_svg_double(repr, attr, value);
115 }
116 }
118 double
119 prefs_get_double_attribute(gchar const *path, gchar const *attr, double def)
120 {
121 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
122 if (repr) {
123 return sp_repr_get_double_attribute(repr, attr, def);
124 } else {
125 return def;
126 }
127 }
129 /**
130 \brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned
131 */
132 double
133 prefs_get_double_attribute_limited(gchar const *path, gchar const *attr, double def, double min, double max)
134 {
135 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
136 if (repr) {
137 double const v = sp_repr_get_double_attribute(repr, attr, def);
138 if (v >= min && v <= max) {
139 return v;
140 } else {
141 return def;
142 }
143 } else {
144 return def;
145 }
146 }
148 gchar const *
149 prefs_get_string_attribute(gchar const *path, gchar const *attr)
150 {
151 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
152 if (repr) {
153 return repr->attribute(attr);
154 }
155 return NULL;
156 }
158 void
159 prefs_set_string_attribute(gchar const *path, gchar const *attr, gchar const *value)
160 {
161 Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path);
162 if (repr) {
163 repr->setAttribute(attr, value);
164 }
165 }
167 void
168 prefs_set_recent_file(gchar const *uri, gchar const *name)
169 {
170 unsigned const max_documents = prefs_get_int_attribute("options.maxrecentdocuments", "value", 20);
172 if (uri != NULL) {
173 Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent");
174 if (recent) {
175 // remove excess recent files
176 if (recent->childCount() >= max_documents) {
177 Inkscape::XML::Node *child = recent->firstChild();
178 // count to the last
179 for (unsigned i = 0; child && i + 1 < max_documents; ++i) {
180 child = child->next();
181 }
182 // remove all after the last
183 while (child) {
184 Inkscape::XML::Node *next = child->next();
185 sp_repr_unparent(child);
186 child = next;
187 }
188 }
190 if (max_documents > 0) {
191 Inkscape::XML::Node *child = sp_repr_lookup_child(recent, "uri", uri);
192 if (child) {
193 recent->changeOrder(child, NULL);
194 } else {
195 child = recent->document()->createElement("document");
196 child->setAttribute("uri", uri);
197 recent->addChild(child, NULL);
198 }
199 child->setAttribute("name", name);
200 }
201 }
202 }
203 }
205 gchar const **
206 prefs_get_recent_files()
207 {
208 Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent");
209 if (recent) {
210 unsigned const docs = recent->childCount();
211 gchar const **datalst = (gchar const **) g_malloc(sizeof(gchar *) * ((docs * 2) + 1));
213 gint i;
214 Inkscape::XML::Node *child;
215 for (i = 0, child = recent->firstChild();
216 child != NULL;
217 child = child->next(), i += 2)
218 {
219 gchar const *uri = child->attribute("uri");
220 gchar const *name = child->attribute("name");
221 datalst[i] = uri;
222 datalst[i + 1] = name;
223 }
225 datalst[i] = NULL;
226 return datalst;
227 }
229 return NULL;
230 }
232 /*
233 Local Variables:
234 mode:c++
235 c-file-style:"stroustrup"
236 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
237 indent-tabs-mode:nil
238 fill-column:99
239 End:
240 */
241 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :