Commit c2d88106 authored by Peter Moulder's avatar Peter Moulder Committed by pjrm

Move Inkscape::IO::fixupHrefs to Inkscape::XML::rebase_hrefs in new file...

Move Inkscape::IO::fixupHrefs to Inkscape::XML::rebase_hrefs in new file xml/rebase-hrefs.*.  Give it the old and new base directory, so that it can change hrefs without relying on sodipodi:absref.
Also create a new function sp_repr_save_rebased_file that changes all xlink:href attributes as it writes them, so that we don't need to modify the owning document.  (Especially useful for "Save a copy" or exporting.)
extension/system.cpp: (Inkscape::Extension::save): Don't call sp_document_set_uri even temporarily other than at the same time as calling rebase_hrefs.  (Otherwise, existing relative hrefs will point nowhere.)
When exporting plain SVG, change the relative hrefs according to the destination filename.

(bzr r7643)
parent 6ccd8075
......@@ -184,16 +184,14 @@ XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename)
void
XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const *filename)
{
/* TODO: Should we assume filename to be in utf8 or to be a raw filename?
* See JavaFXOutput::save for discussion. */
g_return_if_fail(doc != NULL);
g_return_if_fail(filename != NULL);
Inkscape::XML::Node *repr = NULL;
repr = sp_document_repr_root (doc);
gchar *save_path = g_path_get_dirname (filename);
Inkscape::IO::fixupHrefs( doc, save_path, true );
g_free(save_path);
std::string tempfilename_out;
int tempfd_out = 0;
try {
......@@ -203,8 +201,8 @@ XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const
return;
}
gboolean const s = sp_repr_save_file (repr->document(), tempfilename_out.c_str(), SP_SVG_NS_URI);
if (s == FALSE) {
if (!sp_repr_save_rebased_file(repr->document(), tempfilename_out.c_str(), SP_SVG_NS_URI,
doc->base, filename)) {
throw Inkscape::Extension::Output::save_failed();
}
......
......@@ -54,7 +54,7 @@ GdkpixbufInput::open(Inkscape::Extension::Input */*mod*/, char const *uri)
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
// import as <image>
repr = xml_doc->createElement("svg:image");
// both are the same, as we don't know our base dir here and cannot relativate href (importer will fixupHrefs):
// both are the same, as we don't know our base dir here and cannot relativate href (importer will rebase_hrefs):
repr->setAttribute("xlink:href", uri);
repr->setAttribute("sodipodi:absref", uri);
......
......@@ -198,7 +198,7 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena
gchar *save_path = g_path_get_dirname(filename);
gboolean const spns = (!mod->get_id()
bool const spns = ( !mod->get_id()
|| !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)
|| !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE));
......@@ -212,10 +212,8 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena
repr = sp_document_root (doc)->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD);
}
Inkscape::IO::fixupHrefs( doc, save_path, spns );
gboolean const s = sp_repr_save_file(repr->document(), filename, SP_SVG_NS_URI);
if (s == FALSE) {
if (!sp_repr_save_rebased_file(repr->document(), filename, SP_SVG_NS_URI,
doc->base, filename)) {
throw Inkscape::Extension::Output::save_failed();
}
......
......@@ -29,6 +29,7 @@
#include "print.h"
#include "implementation/script.h"
#include "implementation/xslt.h"
#include "xml/rebase-hrefs.h"
/* #include "implementation/plugin.h" */
namespace Inkscape {
......@@ -250,12 +251,20 @@ save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension,
bool saved_modified = false;
gchar *saved_output_extension = NULL;
gchar *saved_dataloss = NULL;
gchar *saved_uri = NULL;
if (!official) {
saved_modified = doc->isModifiedSinceSave();
saved_output_extension = g_strdup(repr->attribute("inkscape:output_extension"));
saved_dataloss = g_strdup(repr->attribute("inkscape:dataloss"));
saved_uri = g_strdup(doc->uri);
} else {
/* The document is changing name/uri. */
/* TODO: Don't treat URIs and filenames interchangeably.
* So call g_filename_to_uri when passing to sp_document_set_uri,
* and change rebase_hrefs to accept a base URI/LEIRI instead of dir name. */
gchar *const new_base = g_path_get_dirname(fileName);
Inkscape::XML::rebase_hrefs(doc, new_base, true);
sp_document_set_uri(doc, fileName);
g_free(new_base);
}
// Update attributes:
......@@ -263,8 +272,6 @@ save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension,
bool const saved = sp_document_get_undo_sensitive(doc);
sp_document_set_undo_sensitive(doc, false);
{
// save the filename for next use
sp_document_set_uri(doc, fileName);
// also save the extension for next use
repr->setAttribute("inkscape:output_extension", omod->get_id());
// set the "dataloss" attribute if the chosen extension is lossy
......@@ -286,14 +293,12 @@ save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension,
{
repr->setAttribute("inkscape:output_extension", saved_output_extension);
repr->setAttribute("inkscape:dataloss", saved_dataloss);
sp_document_set_uri(doc, saved_uri);
}
sp_document_set_undo_sensitive(doc, saved);
doc->setModifiedSinceSave(saved_modified);
g_free(saved_output_extension);
g_free(saved_dataloss);
g_free(saved_uri);
}
g_free(fileName);
......
......@@ -63,6 +63,7 @@
#include "ui/dialog/ocaldialogs.h"
#include "ui/view/view-widget.h"
#include "uri.h"
#include "xml/rebase-hrefs.h"
#ifdef WITH_GNOME_VFS
# include <libgnomevfs/gnome-vfs.h>
......@@ -924,7 +925,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
}
if (doc != NULL) {
Inkscape::IO::fixupHrefs(doc, in_doc->base, true);
Inkscape::XML::rebase_hrefs(doc, in_doc->base, true);
Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);
prevent_id_clashes(doc, in_doc);
......@@ -1479,102 +1480,6 @@ sp_file_print_preview(gpointer /*object*/, gpointer /*data*/)
}
void Inkscape::IO::fixupHrefs( SPDocument *doc, const gchar *base, gboolean spns )
{
//g_message("Inkscape::IO::fixupHrefs( , [%s], )", base );
if ( 0 ) {
gchar const* things[] = {
"data:foo,bar",
"http://www.google.com/image.png",
"ftp://ssd.com/doo",
"/foo/dee/bar.svg",
"foo.svg",
"file:/foo/dee/bar.svg",
"file:///foo/dee/bar.svg",
"file:foo.svg",
"/foo/bar\xe1\x84\x92.svg",
"file:///foo/bar\xe1\x84\x92.svg",
"file:///foo/bar%e1%84%92.svg",
"/foo/bar%e1%84%92.svg",
"bar\xe1\x84\x92.svg",
"bar%e1%84%92.svg",
NULL
};
g_message("+------");
for ( int i = 0; things[i]; i++ )
{
try
{
URI uri(things[i]);
gboolean isAbs = g_path_is_absolute( things[i] );
gchar *str = uri.toString();
g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs,
(int)uri.isRelative(),
uri.getScheme(),
uri.getPath(),
uri.getOpaque(),
things[i],
str );
g_free(str);
}
catch ( MalformedURIException err )
{
dump_str( things[i], "MalformedURIException" );
xmlChar *redo = xmlURIEscape((xmlChar const *)things[i]);
g_message(" gone from [%s] to [%s]", things[i], redo );
if ( redo == NULL )
{
URI again = URI::fromUtf8( things[i] );
gboolean isAbs = g_path_is_absolute( things[i] );
gchar *str = again.toString();
g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs,
(int)again.isRelative(),
again.getScheme(),
again.getPath(),
again.getOpaque(),
things[i],
str );
g_free(str);
g_message(" ----");
}
}
}
g_message("+------");
}
GSList const *images = sp_document_get_resource_list(doc, "image");
for (GSList const *l = images; l != NULL; l = l->next) {
Inkscape::XML::Node *ir = SP_OBJECT_REPR(l->data);
const gchar *href = ir->attribute("xlink:href");
// First try to figure out an absolute path to the asset
//g_message("image href [%s]", href );
if (spns && !g_path_is_absolute(href)) {
const gchar *absref = ir->attribute("sodipodi:absref");
const gchar *base_href = g_build_filename(base, href, NULL);
//g_message(" absr [%s]", absref );
if ( absref && Inkscape::IO::file_test(absref, G_FILE_TEST_EXISTS) && !Inkscape::IO::file_test(base_href, G_FILE_TEST_EXISTS))
{
// only switch over if the absref is valid while href is not
href = absref;
//g_message(" copied absref to href");
}
}
// Once we have an absolute path, convert it relative to the new location
if (href && g_path_is_absolute(href)) {
const gchar *relname = sp_relative_path_from_path(href, base);
//g_message(" setting to [%s]", relname );
ir->setAttribute("xlink:href", relname);
}
// TODO next refinement is to make the first choice keeping the relative path as-is if
// based on the new location it gives us a valid file.
}
}
/*
Local Variables:
......
......@@ -196,13 +196,16 @@ void sp_file_print_preview (gpointer object, gpointer data);
void sp_file_vacuum ();
namespace Inkscape {
namespace IO {
void fixupHrefs( SPDocument *doc, const gchar *uri, gboolean spns );
}
}
#endif
#endif
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vi: set autoindent shiftwidth=4 tabstop=8 filetype=cpp expandtab softtabstop=4 encoding=utf-8 textwidth=99 :
......@@ -983,7 +983,8 @@ void sp_process_file_list(GSList *fl)
rdoc = sp_repr_document_new("svg:svg");
repr = rdoc->root();
repr = sp_document_root(doc)->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD);
sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
sp_repr_save_rebased_file(repr->document(), sp_export_svg, SP_SVG_NS_URI,
doc->base, sp_export_svg);
}
if (sp_export_ps) {
do_export_ps_pdf(doc, sp_export_ps, "image/x-postscript");
......
......@@ -16,6 +16,8 @@ ink_common_sources += \
xml/node-fns.cpp \
xml/node-fns.h \
xml/pi-node.h \
xml/rebase-hrefs.cpp \
xml/rebase-hrefs.h \
xml/repr-io.cpp \
xml/repr-sorting.cpp \
xml/repr-sorting.h \
......
This diff is collapsed.
#ifndef REBASE_HREFS_H_SEEN
#define REBASE_HREFS_H_SEEN
#include <glib/gtypes.h>
#include "util/list.h"
#include "xml/attribute-record.h"
struct SPDocument;
namespace Inkscape {
namespace XML {
gchar *calc_abs_doc_base(gchar const *doc_base);
void rebase_hrefs(SPDocument *doc, gchar const *new_base, bool spns);
Inkscape::Util::List<AttributeRecord const> rebase_href_attrs(
gchar const *old_abs_base,
gchar const *new_abs_base,
Inkscape::Util::List<AttributeRecord const> attributes);
}
}
#endif /* !REBASE_HREFS_H_SEEN */
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vi: set autoindent shiftwidth=4 tabstop=8 filetype=cpp expandtab softtabstop=4 encoding=utf-8 textwidth=99 :
This diff is collapsed.
......@@ -71,13 +71,21 @@ inline Inkscape::XML::Node *sp_repr_next(Inkscape::XML::Node *repr) {
Inkscape::XML::Document *sp_repr_read_file(gchar const *filename, gchar const *default_ns);
Inkscape::XML::Document *sp_repr_read_mem(gchar const *buffer, int length, gchar const *default_ns);
void sp_repr_write_stream (Inkscape::XML::Node *repr, Inkscape::IO::Writer &out,
gint indent_level, bool add_whitespace, Glib::QueryQuark elide_prefix,
int inlineattrs, int indent);
void sp_repr_write_stream(Inkscape::XML::Node *repr, Inkscape::IO::Writer &out,
gint indent_level, bool add_whitespace, Glib::QueryQuark elide_prefix,
int inlineattrs, int indent,
gchar const *old_href_base = NULL,
gchar const *new_href_base = NULL);
Inkscape::XML::Document *sp_repr_read_buf (const Glib::ustring &buf, const gchar *default_ns);
Glib::ustring sp_repr_save_buf(Inkscape::XML::Document *doc);
void sp_repr_save_stream(Inkscape::XML::Document *doc, FILE *to_file, gchar const *default_ns=NULL, bool compress = false);
void sp_repr_save_stream(Inkscape::XML::Document *doc, FILE *to_file,
gchar const *default_ns = NULL, bool compress = false,
gchar const *old_href_base = NULL,
gchar const *new_href_base = NULL);
bool sp_repr_save_file(Inkscape::XML::Document *doc, gchar const *filename, gchar const *default_ns=NULL);
bool sp_repr_save_rebased_file(Inkscape::XML::Document *doc, gchar const *filename_utf8,
gchar const *default_ns,
gchar const *old_base, gchar const *new_base_filename);
/* CSS stuff */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment