~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/preferences.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Wolfram Quester
  • Date: 2009-11-30 17:23:20 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20091130172320-wml0kbvehpf3pevw
Tags: 0.47.0-1
* Imported Upstream version 0.47
* This is upstream version  0.47, I added the .0 because 
  I forget the ~ in the -pre versions.
* add proper Vcs-fields to debian/control
* upload sponsored by Guido Guenther <agx@debian.org>

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
#include <glibmm/i18n.h>
16
16
#include <glib.h>
17
17
#include <glib/gstdio.h>
 
18
#include <gtk/gtk.h>
18
19
#include "preferences.h"
19
20
#include "preferences-skeleton.h"
20
21
#include "inkscape.h"
26
27
 
27
28
namespace Inkscape {
28
29
 
 
30
static Inkscape::XML::Document *loadImpl( std::string const& prefsFilename, Glib::ustring & errMsg );
 
31
static void migrateDetails( Inkscape::XML::Document *from, Inkscape::XML::Document *to );
 
32
 
 
33
static Inkscape::XML::Document *migrateFromDoc = 0;
 
34
 
 
35
// TODO clean up. Function copied from file.cpp:
 
36
// what gets passed here is not actually an URI... it is an UTF-8 encoded filename (!)
 
37
static void file_add_recent(gchar const *uri)
 
38
{
 
39
    if (!uri) {
 
40
        g_warning("file_add_recent: uri == NULL");
 
41
    } else {
 
42
        GtkRecentManager *recent = gtk_recent_manager_get_default();
 
43
        gchar *fn = g_filename_from_utf8(uri, -1, NULL, NULL, NULL);
 
44
        if (fn) {
 
45
            if (g_file_test(fn, G_FILE_TEST_EXISTS)) {
 
46
                gchar *uriToAdd = g_filename_to_uri(fn, NULL, NULL);
 
47
                if (uriToAdd) {
 
48
                    gtk_recent_manager_add_item(recent, uriToAdd);
 
49
                    g_free(uriToAdd);
 
50
                }
 
51
            }
 
52
            g_free(fn);
 
53
        }
 
54
    }
 
55
}
 
56
 
 
57
 
29
58
// private inner class definition
30
59
 
31
60
/**
47
76
    Glib::ustring const _filter;
48
77
};
49
78
 
50
 
 
51
79
Preferences::Preferences() :
52
80
    _prefs_basename(PREFERENCES_FILE_NAME),
53
81
    _prefs_dir(""),
62
90
    _prefs_dir = path;
63
91
    g_free(path);
64
92
 
65
 
    path = profile_path(_prefs_basename.data());
 
93
    path = profile_path(_prefs_basename.c_str());
66
94
    _prefs_filename = path;
67
95
    g_free(path);
68
96
 
104
132
    // NOTE: After we upgrade to Glib 2.16, use Glib::ustring::compose
105
133
 
106
134
    // 1. Does the file exist?
107
 
    if (!g_file_test(_prefs_filename.data(), G_FILE_TEST_EXISTS)) {
 
135
    if (!g_file_test(_prefs_filename.c_str(), G_FILE_TEST_EXISTS)) {
108
136
        // No - we need to create one.
109
137
        // Does the profile directory exist?
110
 
        if (!g_file_test(_prefs_dir.data(), G_FILE_TEST_EXISTS)) {
 
138
        if (!g_file_test(_prefs_dir.c_str(), G_FILE_TEST_EXISTS)) {
111
139
            // No - create the profile directory
112
 
            if (g_mkdir(_prefs_dir.data(), 0755)) {
 
140
            if (g_mkdir(_prefs_dir.c_str(), 0755)) {
113
141
                // the creation failed
114
142
                //_reportError(Glib::ustring::compose(_("Cannot create profile directory %1."),
115
143
                //    Glib::filename_to_utf8(_prefs_dir)), not_saved);
116
144
                gchar *msg = g_strdup_printf(_("Cannot create profile directory %s."),
117
 
                    Glib::filename_to_utf8(_prefs_dir).data());
 
145
                    Glib::filename_to_utf8(_prefs_dir).c_str());
118
146
                _reportError(msg, not_saved);
119
147
                g_free(msg);
120
148
                return;
127
155
                g_free(dir);
128
156
            }
129
157
 
130
 
        } else if (!g_file_test(_prefs_dir.data(), G_FILE_TEST_IS_DIR)) {
 
158
        } else if (!g_file_test(_prefs_dir.c_str(), G_FILE_TEST_IS_DIR)) {
131
159
            // The profile dir is not actually a directory
132
160
            //_reportError(Glib::ustring::compose(_("%1 is not a valid directory."),
133
161
            //    Glib::filename_to_utf8(_prefs_dir)), not_saved);
134
162
            gchar *msg = g_strdup_printf(_("%s is not a valid directory."),
135
 
                Glib::filename_to_utf8(_prefs_dir).data());
 
163
                Glib::filename_to_utf8(_prefs_dir).c_str());
136
164
            _reportError(msg, not_saved);
137
165
            g_free(msg);
138
166
            return;
139
167
        }
140
168
        // The profile dir exists and is valid.
141
 
        if (!g_file_set_contents(_prefs_filename.data(), preferences_skeleton, PREFERENCES_SKELETON_SIZE, NULL)) {
 
169
        if (!g_file_set_contents(_prefs_filename.c_str(), preferences_skeleton, PREFERENCES_SKELETON_SIZE, NULL)) {
142
170
            // The write failed.
143
171
            //_reportError(Glib::ustring::compose(_("Failed to create the preferences file %1."),
144
172
            //    Glib::filename_to_utf8(_prefs_filename)), not_saved);
145
173
            gchar *msg = g_strdup_printf(_("Failed to create the preferences file %s."),
146
 
                Glib::filename_to_utf8(_prefs_filename).data());
 
174
                Glib::filename_to_utf8(_prefs_filename).c_str());
147
175
            _reportError(msg, not_saved);
148
176
            g_free(msg);
149
177
            return;
150
178
        }
151
179
 
 
180
        if ( migrateFromDoc ) {
 
181
            migrateDetails( migrateFromDoc, _prefs_doc );
 
182
        }
 
183
 
152
184
        // The prefs file was just created.
153
185
        // We can return now and skip the rest of the load process.
154
186
        _writable = true;
156
188
    }
157
189
 
158
190
    // Yes, the pref file exists.
 
191
    Glib::ustring errMsg;
 
192
    Inkscape::XML::Document *prefs_read = loadImpl( _prefs_filename, errMsg );
 
193
 
 
194
    if ( prefs_read ) {
 
195
        // Merge the loaded prefs with defaults.
 
196
        _prefs_doc->root()->mergeFrom(prefs_read->root(), "id");
 
197
        Inkscape::GC::release(prefs_read);
 
198
        _writable = true;
 
199
    } else {
 
200
        _reportError(errMsg, not_saved);
 
201
    }
 
202
}
 
203
 
 
204
//_reportError(msg, not_saved);
 
205
static Inkscape::XML::Document *loadImpl( std::string const& prefsFilename, Glib::ustring & errMsg )
 
206
{
159
207
    // 2. Is it a regular file?
160
 
    if (!g_file_test(_prefs_filename.data(), G_FILE_TEST_IS_REGULAR)) {
161
 
        //_reportError(Glib::ustring::compose(_("The preferences file %1 is not a regular file."),
162
 
        //    Glib::filename_to_utf8(_prefs_filename)), not_saved);
 
208
    if (!g_file_test(prefsFilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
163
209
        gchar *msg = g_strdup_printf(_("The preferences file %s is not a regular file."),
164
 
            Glib::filename_to_utf8(_prefs_filename).data());
165
 
        _reportError(msg, not_saved);
 
210
            Glib::filename_to_utf8(prefsFilename).c_str());
 
211
        errMsg = msg;
166
212
        g_free(msg);
167
 
        return;
 
213
        return 0;
168
214
    }
169
215
 
170
216
    // 3. Is the file readable?
171
217
    gchar *prefs_xml = NULL; gsize len = 0;
172
 
    if (!g_file_get_contents(_prefs_filename.data(), &prefs_xml, &len, NULL)) {
173
 
        //_reportError(Glib::ustring::compose(_("The preferences file %1 could not be read."),
174
 
        //    Glib::filename_to_utf8(_prefs_filename)), not_saved);
 
218
    if (!g_file_get_contents(prefsFilename.c_str(), &prefs_xml, &len, NULL)) {
175
219
        gchar *msg = g_strdup_printf(_("The preferences file %s could not be read."),
176
 
            Glib::filename_to_utf8(_prefs_filename).data());
177
 
        _reportError(msg, not_saved);
 
220
            Glib::filename_to_utf8(prefsFilename).c_str());
 
221
        errMsg = msg;
178
222
        g_free(msg);
179
 
        return;
 
223
        return 0;
180
224
    }
181
225
 
182
226
    // 4. Is it valid XML?
183
227
    Inkscape::XML::Document *prefs_read = sp_repr_read_mem(prefs_xml, len, NULL);
184
228
    g_free(prefs_xml);
185
229
    if (!prefs_read) {
186
 
        //_reportError(Glib::ustring::compose(_("The preferences file %1 is not a valid XML document."),
187
 
        //    Glib::filename_to_utf8(_prefs_filename)), not_saved);
188
230
        gchar *msg = g_strdup_printf(_("The preferences file %s is not a valid XML document."),
189
 
            Glib::filename_to_utf8(_prefs_filename).data());
190
 
        _reportError(msg, not_saved);
 
231
            Glib::filename_to_utf8(prefsFilename).c_str());
 
232
        errMsg = msg;
191
233
        g_free(msg);
192
 
        return;
 
234
        return 0;
193
235
    }
194
236
 
195
237
    // 5. Basic sanity check: does the root element have a correct name?
196
238
    if (strcmp(prefs_read->root()->name(), "inkscape")) {
197
 
        //_reportError(Glib::ustring::compose(_("The file %1 is not a valid Inkscape preferences file."),
198
 
        //    Glib::filename_to_utf8(_prefs_filename)), not_saved);
199
239
        gchar *msg = g_strdup_printf(_("The file %s is not a valid Inkscape preferences file."),
200
 
            Glib::filename_to_utf8(_prefs_filename).data());
201
 
        _reportError(msg, not_saved);
 
240
            Glib::filename_to_utf8(prefsFilename).c_str());
 
241
        errMsg = msg;
202
242
        g_free(msg);
203
243
        Inkscape::GC::release(prefs_read);
204
 
        return;
 
244
        return 0;
205
245
    }
206
246
 
207
 
    // Merge the loaded prefs with defaults.
208
 
    _prefs_doc->root()->mergeFrom(prefs_read->root(), "id");
209
 
    Inkscape::GC::release(prefs_read);
210
 
    _writable = true;
 
247
    return prefs_read;
 
248
}
 
249
 
 
250
static void migrateDetails( Inkscape::XML::Document *from, Inkscape::XML::Document *to )
 
251
{
 
252
    // TODO pull in additional prefs with more granularity
 
253
    to->root()->mergeFrom(from->root(), "id");
211
254
}
212
255
 
213
256
/**
231
274
        // There are many other factors, so ask if you would like to learn them. - JAC
232
275
        Glib::ustring utf8name = Glib::filename_to_utf8(_prefs_filename);
233
276
        if (!utf8name.empty()) {
234
 
            sp_repr_save_file(_prefs_doc, utf8name.data());
 
277
            sp_repr_save_file(_prefs_doc, utf8name.c_str());
235
278
        }
236
279
    }
237
280
}
252
295
    return result;
253
296
}
254
297
 
 
298
void Preferences::migrate( std::string const& legacyDir, std::string const& prefdir )
 
299
{
 
300
    int mode = S_IRWXU;
 
301
#ifdef S_IRGRP
 
302
    mode |= S_IRGRP;
 
303
#endif
 
304
#ifdef S_IXGRP
 
305
    mode |= S_IXGRP;
 
306
#endif
 
307
#ifdef S_IXOTH
 
308
    mode |= S_IXOTH;
 
309
#endif
 
310
    if ( g_mkdir_with_parents(prefdir.c_str(), mode) == -1 ) {
 
311
    } else {
 
312
    }
 
313
 
 
314
    gchar * oldPrefFile = g_build_filename(legacyDir.c_str(), PREFERENCES_FILE_NAME, NULL);
 
315
    if (oldPrefFile) {
 
316
        if (g_file_test(oldPrefFile, G_FILE_TEST_EXISTS)) {
 
317
            Glib::ustring errMsg;
 
318
            Inkscape::XML::Document *oldPrefs = loadImpl( oldPrefFile, errMsg );
 
319
            if (oldPrefs) {
 
320
                Glib::ustring docId("documents");
 
321
                Glib::ustring recentId("recent");
 
322
                Inkscape::XML::Node *node = oldPrefs->root();
 
323
                Inkscape::XML::Node *child = 0;
 
324
                Inkscape::XML::Node *recentNode = 0;
 
325
                if (node->attribute("version")) {
 
326
                    node->setAttribute("version", "1");
 
327
                }
 
328
                for (child = node->firstChild(); child; child = child->next()) {
 
329
                    if (docId == child->attribute("id")) {
 
330
                        for (child = child->firstChild(); child; child = child->next()) {
 
331
                            if (recentId == child->attribute("id")) {
 
332
                                recentNode = child;
 
333
                                for (child = child->firstChild(); child; child = child->next()) {
 
334
                                    gchar const* uri = child->attribute("uri");
 
335
                                    if (uri) {
 
336
                                        file_add_recent(uri);
 
337
                                    }
 
338
                                }
 
339
                                break;
 
340
                            }
 
341
                        }
 
342
                        break;
 
343
                    }
 
344
                }
 
345
 
 
346
                if (recentNode) {
 
347
                    while (recentNode->firstChild()) {
 
348
                        recentNode->removeChild(recentNode->firstChild());
 
349
                    }
 
350
                }
 
351
                migrateFromDoc = oldPrefs;
 
352
                //Inkscape::GC::release(oldPrefs);
 
353
                oldPrefs = 0;
 
354
            } else {
 
355
                g_warning( "%s", errMsg.c_str() );
 
356
            }
 
357
        }
 
358
        g_free(oldPrefFile);
 
359
        oldPrefFile = 0;
 
360
    }
 
361
}
 
362
 
255
363
// Now for the meat.
256
364
 
257
365
/**
345
453
 */
346
454
void Preferences::setString(Glib::ustring const &pref_path, Glib::ustring const &value)
347
455
{
348
 
    _setRawValue(pref_path, value.data());
 
456
    _setRawValue(pref_path, value.c_str());
349
457
}
350
458
 
351
459
void Preferences::setStyle(Glib::ustring const &pref_path, SPCSSAttr *style)
515
623
 
516
624
    Inkscape::XML::Node *node = _prefs_doc->root();
517
625
    Inkscape::XML::Node *child = NULL;
518
 
    gchar **splits = g_strsplit(pref_key.data(), "/", 0);
 
626
    gchar **splits = g_strsplit(pref_key.c_str(), "/", 0);
519
627
 
520
628
    if ( splits ) {
521
629
        for (int part_i = 0; splits[part_i]; ++part_i) {
568
676
    if ( node == NULL ) {
569
677
        result = NULL;
570
678
    } else {
571
 
        gchar const *attr = node->attribute(attr_key.data());
 
679
        gchar const *attr = node->attribute(attr_key.c_str());
572
680
        if ( attr == NULL ) {
573
681
            result = NULL;
574
682
        } else {
585
693
 
586
694
    // set the attribute
587
695
    Inkscape::XML::Node *node = _getNode(node_key, true);
588
 
    node->setAttribute(attr_key.data(), value);
 
696
    node->setAttribute(attr_key.c_str(), value);
589
697
}
590
698
 
591
699
// The _extract* methods are where the actual wrok is done - they define how preferences are stored
640
748
    _keySplit(v._pref_path, node_key, attr_key);
641
749
 
642
750
    Inkscape::XML::Node *node = _getNode(node_key, false);
643
 
    return sp_repr_css_attr_inherited(node, attr_key.data());
 
751
    return sp_repr_css_attr_inherited(node, attr_key.c_str());
644
752
}
645
753
 
646
754
// XML backend helper: Split the path into a node key and an attribute key.