diff --git a/src/file.cpp b/src/file.cpp
index cdd76941fc8a615ba9de41f84eb5efa8b96cd58d..5c729eeeb65b1032a8c61cb0ca255d6bdbcad34a 100644 (file)
--- a/src/file.cpp
+++ b/src/file.cpp
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-/**
- * Note: This file needs to be cleaned up extensively.
+/** @file
+ * @note This file needs to be cleaned up extensively.
* What it probably needs is to have one .h file for
* the API, and two or more .cpp files for the implementations.
*/
# include "config.h"
#endif
+#include <gtk/gtk.h>
#include <glib/gmem.h>
#include <libnr/nr-pixops.h>
#include "message-stack.h"
#include "ui/dialog/filedialog.h"
#include "ui/dialog/ocaldialogs.h"
-#include "prefs-utils.h"
+#include "preferences.h"
#include "path-prefix.h"
#include "sp-namedview.h"
#include "application/editor.h"
#include "inkscape.h"
#include "uri.h"
-#include "extract-uri.h"
+#include "id-clash.h"
+#include "dialogs/rdf.h"
#ifdef WITH_GNOME_VFS
# include <libgnomevfs/gnome-vfs.h>
void dump_str(gchar const *str, gchar const *prefix);
void dump_ustr(Glib::ustring const &ustr);
+// what gets passed here is not actually an URI... it is an UTF-8 encoded filename (!)
+static void sp_file_add_recent(gchar const *uri)
+{
+ GtkRecentManager *recent = gtk_recent_manager_get_default();
+ gchar *fn = g_filename_from_utf8(uri, -1, NULL, NULL, NULL);
+ if (fn) {
+ gchar *uri_to_add = g_filename_to_uri(fn, NULL, NULL);
+ if (uri_to_add) {
+ gtk_recent_manager_add_item(recent, uri_to_add);
+ g_free(uri_to_add);
+ }
+ g_free(fn);
+ }
+}
+
/*######################
## N E W
Inkscape::Extension::Extension *key,
bool add_to_recent, bool replace_empty)
{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop)
+ desktop->setWaitingCursor();
+
SPDocument *doc = NULL;
try {
doc = Inkscape::Extension::open(key, uri.c_str());
doc = NULL;
}
+ if (desktop)
+ desktop->clearWaitingCursor();
+
if (doc) {
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
SPDocument *existing = desktop ? sp_desktop_document(desktop) : NULL;
if (existing && existing->virgin && replace_empty) {
sp_namedview_update_layers_from_document(desktop);
if (add_to_recent) {
- prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+ sp_file_add_recent(SP_DOCUMENT_URI(doc));
}
return TRUE;
// remember current zoom and view
double zoom = desktop->current_zoom();
- NR::Point c = desktop->get_display_area().midpoint();
+ Geom::Point c = desktop->get_display_area().midpoint();
reverted = sp_file_open(uri,NULL);
if (reverted) {
// restore zoom and view
- desktop->zoom_absolute(c[NR::X], c[NR::Y], zoom);
+ desktop->zoom_absolute(c[Geom::X], c[Geom::Y], zoom);
}
} else {
reverted = false;
@@ -381,12 +404,12 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
{
//# Get the current directory for finding files
static Glib::ustring open_path;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if(open_path.empty())
{
- gchar const *attr = prefs_get_string_attribute("dialogs.open", "path");
- if (attr)
- open_path = attr;
+ Glib::ustring attr = prefs->getString("/dialogs/open/path");
+ if (!attr.empty()) open_path = attr;
}
//# Test if the open_path directory exists
@@ -497,7 +520,7 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
open_path = Glib::path_get_dirname (fileName);
open_path.append(G_DIR_SEPARATOR_S);
- prefs_set_string_attribute("dialogs.open", "path", open_path.c_str());
+ prefs->setString("/dialogs/open/path", open_path);
sp_file_open(fileName, selection);
}
g_free(text);
g_free(safeUri);
return FALSE;
+ } catch (Inkscape::Extension::Output::save_cancelled &e) {
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
+ return FALSE;
} catch (Inkscape::Extension::Output::no_overwrite &e) {
return sp_file_save_dialog(parentWindow, doc);
}
{
Inkscape::XML::Node *repr = sp_document_repr_root(doc);
-
Inkscape::Extension::Output *extension = 0;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
//# Get the default extension name
Glib::ustring default_extension;
char *attr = (char *)repr->attribute("inkscape:output_extension");
- if (!attr)
- attr = (char *)prefs_get_string_attribute("dialogs.save_as", "default");
- if (attr)
+ if (!attr) {
+ Glib::ustring attr2 = prefs->getString("/dialogs/save_as/default");
+ if(!attr2.empty()) default_extension = attr2;
+ } else {
default_extension = attr;
+ }
//g_message("%s: extension name: '%s'", __FUNCTION__, default_extension);
Glib::ustring save_path;
if (extension)
filename_extension = extension->get_extension();
- attr = (char *)prefs_get_string_attribute("dialogs.save_as", "path");
- if (attr)
- save_path = attr;
+ Glib::ustring attr3 = prefs->getString("/dialogs/save_as/path");
+ if (!attr3.empty())
+ save_path = attr3;
if (!Inkscape::IO::file_test(save_path.c_str(),
(GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
} else {
dialog_title = (char const *) _("Select file to save to");
}
+ gchar* doc_title = doc->root->title();
Inkscape::UI::Dialog::FileSaveDialog *saveDialog =
Inkscape::UI::Dialog::FileSaveDialog::create(
parentWindow,
save_loc,
Inkscape::UI::Dialog::SVG_TYPES,
dialog_title,
- default_extension
+ default_extension,
+ doc_title ? doc_title : ""
);
saveDialog->setSelectionType(extension);
return success;
}
+ // set new title here (call RDF to ensure metadata and title element are updated)
+ rdf_set_work_entity(doc, rdf_find_entity("title"), saveDialog->getDocTitle().c_str());
+ // free up old string
+ if(doc_title) g_free(doc_title);
+
Glib::ustring fileName = saveDialog->getFilename();
Inkscape::Extension::Extension *selectionType = saveDialog->getSelectionType();
success = file_save(parentWindow, doc, fileName, selectionType, TRUE, !is_copy);
- if (success)
- prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+ if (success) {
+ sp_file_add_recent(SP_DOCUMENT_URI(doc));
+ }
save_path = Glib::path_get_dirname(fileName);
- prefs_set_string_attribute("dialogs.save_as", "path", save_path.c_str());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setString("/dialogs/save_as/path", save_path);
return success;
}
@@ -873,206 +910,6 @@ sp_file_save_a_copy(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
## I M P O R T
######################*/
-typedef enum { REF_HREF, REF_STYLE, REF_URL } ID_REF_TYPE;
-
-struct IdReference {
- ID_REF_TYPE type;
- SPObject *elem;
- const char *attr; // property or href-like attribute
-};
-
-typedef std::map<std::string, std::list<IdReference> > refmap_type;
-
-typedef std::pair<SPObject*, std::string> id_changeitem_type;
-typedef std::list<id_changeitem_type> id_changelist_type;
-
-const char *href_like_attributes[] = {
- "inkscape:href",
- "inkscape:path-effect",
- "inkscape:perspectiveID",
- "inkscape:tiled-clone-of",
- "xlink:href",
-};
-#define NUM_HREF_LIKE_ATTRIBUTES (sizeof(href_like_attributes) / sizeof(*href_like_attributes))
-
-const SPIPaint SPStyle::* SPIPaint_members[] = {
- &SPStyle::color,
- &SPStyle::fill,
- &SPStyle::stroke,
-};
-const char* SPIPaint_properties[] = {
- "color",
- "fill",
- "stroke",
-};
-#define NUM_SPIPAINT_PROPERTIES (sizeof(SPIPaint_properties) / sizeof(*SPIPaint_properties))
-
-const char* other_url_properties[] = {
- "clip-path",
- "color-profile",
- "cursor",
- "marker-end",
- "marker-mid",
- "marker-start",
- "mask",
-};
-#define NUM_OTHER_URL_PROPERTIES (sizeof(other_url_properties) / sizeof(*other_url_properties))
-
-/**
- * Build a table of places where ids are referenced, for a given element.
- * FIXME: There are some types of references not yet dealt with here
- * (e.g., ID selectors in CSS stylesheets).
- */
-static void
-find_references(SPObject *elem, refmap_type *refmap)
-{
- Inkscape::XML::Node *repr_elem = SP_OBJECT_REPR(elem);
- SPStyle *style = SP_OBJECT_STYLE(elem);
-
- /* check for xlink:href="#..." and similar */
- for (unsigned i = 0; i < NUM_HREF_LIKE_ATTRIBUTES; ++i) {
- const char *attr = href_like_attributes[i];
- const gchar *val = repr_elem->attribute(attr);
- if (val && val[0] == '#') {
- std::string id(val+1);
- IdReference idref = { REF_HREF, elem, attr };
- (*refmap)[id].push_back(idref);
- }
- }
-
- /* check for url(#...) references in 'fill' or 'stroke' */
- for (unsigned i = 0; i < NUM_SPIPAINT_PROPERTIES; ++i) {
- const SPIPaint SPStyle::*prop = SPIPaint_members[i];
- const SPIPaint *paint = &(style->*prop);
- if (paint->isPaintserver()) {
- const gchar *id = SP_OBJECT_ID(paint->value.href->getObject());
- IdReference idref = { REF_STYLE, elem, SPIPaint_properties[i] };
- (*refmap)[id].push_back(idref);
- }
- }
-
- /* check for url(#...) references in 'filter' */
- const SPIFilter *filter = &(style->filter);
- if (filter->href) {
- const gchar *id = SP_OBJECT_ID(filter->href->getObject());
- IdReference idref = { REF_STYLE, elem, "filter" };
- (*refmap)[id].push_back(idref);
- }
-
- /* check for other url(#...) references */
- for (unsigned i = 0; i < NUM_OTHER_URL_PROPERTIES; ++i) {
- const char *attr = other_url_properties[i];
- const gchar *value = repr_elem->attribute(attr);
- if (value) {
- const gchar *uri = extract_uri(value);
- if (uri && uri[0] == '#') {
- IdReference idref = { REF_URL, elem, attr };
- (*refmap)[uri+1].push_back(idref);
- }
- }
- }
-
- /* recurse */
- for (SPObject *child = sp_object_first_child(elem);
- child; child = SP_OBJECT_NEXT(child) )
- {
- find_references(child, refmap);
- }
-}
-
-/**
- * Change any ids that clash with ids in the current document, and make
- * a list of those changes that will require fixing up references.
- */
-static void
-change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc,
- SPObject *elem, const refmap_type *refmap,
- id_changelist_type *id_changes)
-{
- const gchar *id = SP_OBJECT_ID(elem);
-
- if (id && current_doc->getObjectById(id)) {
- // Choose a new id.
- // To try to preserve any meaningfulness that the original id
- // may have had, the new id is the old id followed by a hyphen
- // and one or more digits.
- std::string old_id(id);
- std::string new_id(old_id + '-');
- for (;;) {
- new_id += "0123456789"[std::rand() % 10];
- const char *str = new_id.c_str();
- if (current_doc->getObjectById(str) == NULL &&
- imported_doc->getObjectById(str) == NULL) break;
- }
- // Change to the new id
- SP_OBJECT_REPR(elem)->setAttribute("id", new_id.c_str());
- // Make a note of this change, if we need to fix up refs to it
- if (refmap->find(old_id) != refmap->end())
- id_changes->push_back(id_changeitem_type(elem, old_id));
- }
-
- /* recurse */
- for (SPObject *child = sp_object_first_child(elem);
- child; child = SP_OBJECT_NEXT(child) )
- {
- change_clashing_ids(imported_doc, current_doc, child, refmap, id_changes);
- }
-}
-
-/**
- * Fix up references to changed ids.
- */
-static void
-fix_up_refs(const refmap_type *refmap, const id_changelist_type &id_changes)
-{
- id_changelist_type::const_iterator pp;
- const id_changelist_type::const_iterator pp_end = id_changes.end();
- for (pp = id_changes.begin(); pp != pp_end; ++pp) {
- SPObject *obj = pp->first;
- refmap_type::const_iterator pos = refmap->find(pp->second);
- std::list<IdReference>::const_iterator it;
- const std::list<IdReference>::const_iterator it_end = pos->second.end();
- for (it = pos->second.begin(); it != it_end; ++it) {
- if (it->type == REF_HREF) {
- gchar *new_uri = g_strdup_printf("#%s", SP_OBJECT_ID(obj));
- SP_OBJECT_REPR(it->elem)->setAttribute(it->attr, new_uri);
- g_free(new_uri);
- }
- else if (it->type == REF_STYLE) {
- sp_style_set_property_url(it->elem, it->attr, obj, false);
- }
- else if (it->type == REF_URL) {
- gchar *url = g_strdup_printf("url(#%s)", SP_OBJECT_ID(obj));
- SP_OBJECT_REPR(it->elem)->setAttribute(it->attr, url);
- g_free(url);
- }
- else g_assert(0); // shouldn't happen
- }
- }
-}
-
-/**
- * This function resolves ID clashes between the document being imported
- * and the current open document: IDs in the imported document that would
- * clash with IDs in the existing document are changed, and references to
- * those IDs are updated accordingly.
- */
-void
-prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc)
-{
- refmap_type *refmap = new refmap_type;
- id_changelist_type id_changes;
- SPObject *imported_root = SP_DOCUMENT_ROOT(imported_doc);
-
- find_references(imported_root, refmap);
- change_clashing_ids(imported_doc, current_doc, imported_root, refmap,
- &id_changes);
- fix_up_refs(refmap, id_changes);
-
- delete refmap;
-}
-
-
/**
* Import a resource. Called by sp_file_import()
*/
Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);
prevent_id_clashes(doc, in_doc);
-
+
SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();
-
+
SPCSSAttr *style = sp_css_attr_from_object(SP_DOCUMENT_ROOT(doc));
// Count the number of top-level items in the imported document.
if (newgroup) newgroup->appendChild(newitem);
else new_obj = place_to_insert->appendChildRepr(newitem);
}
-
+
// don't lose top-level defs or style elements
else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
const gchar *tag = SP_OBJECT_REPR(child)->name();
// To move the imported object, we must temporarily set the "transform pattern with
// object" option.
{
- int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1);
- prefs_set_int_attribute("options.transform", "pattern", 1);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool const saved_pref = prefs->getBool("/options/transform/pattern", true);
+ prefs->setBool("/options/transform/pattern", true);
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
- NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->bounds();
if (sel_bbox) {
- NR::Point m( desktop->point() - sel_bbox->midpoint() );
+ Geom::Point m( desktop->point() - sel_bbox->midpoint() );
sp_selection_move_relative(selection, m);
}
- prefs_set_int_attribute("options.transform", "pattern", saved_pref);
+ prefs->setBool("/options/transform/pattern", saved_pref);
}
}
Glib::ustring export_loc;
Inkscape::XML::Node *repr = sp_document_repr_root(doc);
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
Inkscape::Extension::Output *extension;
//# Get the default extension name
Glib::ustring default_extension;
char *attr = (char *)repr->attribute("inkscape:output_extension");
- if (!attr)
- attr = (char *)prefs_get_string_attribute("dialogs.save_as", "default");
- if (attr)
+ if (!attr) {
+ Glib::ustring attr2 = prefs->getString("/dialogs/save_as/default");
+ if(!attr2.empty()) default_extension = attr2;
+ } else {
default_extension = attr;
+ }
//g_message("%s: extension name: '%s'", __FUNCTION__, default_extension);
if (doc->uri == NULL)
if (extension)
filename_extension = extension->get_extension();
- attr = (char *)prefs_get_string_attribute("dialogs.save_as", "path");
- if (attr)
- export_path = attr;
+ Glib::ustring attr3 = prefs->getString("/dialogs/save_as/path");
+ if (!attr3.empty())
+ export_path = attr3;
if (!Inkscape::IO::file_test(export_path.c_str(),
(GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
success = file_save(doc, fileName, selectionType, TRUE, FALSE);
- if (success)
- prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+ if (success) {
+ Glib::RefPtr<Gtk::RecentManager> recent = Gtk::RecentManager::get_default();
+ recent->add_item(SP_DOCUMENT_URI(doc));
+ }
export_path = fileName;
- prefs_set_string_attribute("dialogs.save_as", "path", export_path.c_str());
+ prefs->setString("/dialogs/save_as/path", export_path);
return success;
}
// Start now the submition
// Create the uri
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
Glib::ustring uri = "dav://";
- char *username = (char *)prefs_get_string_attribute("options.ocalusername", "str");
- char *password = (char *)prefs_get_string_attribute("options.ocalpassword", "str");
- if ((username == NULL) || (!strcmp(username, "")) || (password == NULL) || (!strcmp(password, "")))
+ Glib::ustring username = prefs->getString("/options/ocalusername/str");
+ Glib::ustring password = prefs->getString("/options/ocalpassword/str");
+ if (username.empty() || password.empty())
{
if(!gotSuccess)
{
if (!success)
return success;
}
- username = (char *)exportPasswordDialogInstance->getUsername().c_str();
- password = (char *)exportPasswordDialogInstance->getPassword().c_str();
+ username = exportPasswordDialogInstance->getUsername();
+ password = exportPasswordDialogInstance->getPassword();
}
uri.append(username);
uri.append(":");
uri.append(password);
uri.append("@");
- uri.append(prefs_get_string_attribute("options.ocalurl", "str"));
+ uri.append(prefs->getString("/options/ocalurl/str"));
uri.append("/dav.php/");
uri.append(Glib::path_get_basename(fileName));