summaryrefslogtreecommitdiffstats
path: root/src/file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/file.cpp')
-rw-r--r--src/file.cpp620
1 files changed, 573 insertions, 47 deletions
diff --git a/src/file.cpp b/src/file.cpp
index 650ce5d0f..e8248bb8e 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -11,9 +11,10 @@
* Jon A. Cruz <jon@joncruz.org>
* Abhishek Sharma
* David Xiong
+ * Tavmjong Bah
*
* Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
- * Copyright (C) 1999-2012 Authors
+ * Copyright (C) 1999-2016 Authors
* Copyright (C) 2004 David Turner
* Copyright (C) 2001-2002 Ximian, Inc.
*
@@ -30,17 +31,18 @@
# include "config.h"
#endif
+#include <gtkmm.h>
+
#include "ui/dialog/ocaldialogs.h"
#include "desktop.h"
-#include "dir-util.h"
+#include "extension/effect.h"
#include "document-private.h"
#include "document-undo.h"
#include "ui/tools/tool-base.h"
#include "extension/db.h"
#include "extension/input.h"
#include "extension/output.h"
-#include "extension/system.h"
#include "file.h"
#include "helper/png-write.h"
#include "id-clash.h"
@@ -48,33 +50,28 @@
#include "inkscape-version.h"
#include "ui/interface.h"
#include "io/sys.h"
-#include "message.h"
#include "message-stack.h"
#include "path-prefix.h"
-#include "preferences.h"
#include "print.h"
#include "resource-manager.h"
#include "rdf.h"
#include "selection-chemistry.h"
-#include "selection.h"
#include "sp-namedview.h"
#include "style.h"
#include "ui/view/view-widget.h"
-#include "uri.h"
#include "xml/rebase-hrefs.h"
#include "xml/sp-css-attr.h"
#include "verbs.h"
#include "event-log.h"
#include "ui/dialog/font-substitution.h"
-#include <gtk/gtk.h>
-#include <gtkmm/main.h>
-
-#include <glibmm/convert.h>
-#include <glibmm/i18n.h>
-#include <glibmm/miscutils.h>
-
-#include <string>
+// For updating old Inkscape SVG files
+#include "display/canvas-grid.h"
+#include "sp-guide.h"
+#include "selection-chemistry.h"
+#include "persp3d.h"
+#include "proj_pt.h"
+#include "ui/shape-editor.h"
using Inkscape::DocumentUndo;
@@ -141,15 +138,6 @@ SPDesktop *sp_file_new(const std::string &templ)
DocumentUndo::setUndoSensitive(doc, true);
}
- // Set viewBox if it doesn't exist
- if (!doc->getRoot()->viewBox_set
- && (doc->getRoot()->width.unit != SVGLength::PERCENT)
- && (doc->getRoot()->height.unit != SVGLength::PERCENT)) {
- DocumentUndo::setUndoSensitive(doc, false);
- doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit())));
- DocumentUndo::setUndoSensitive(doc, true);
- }
-
SPDesktop *olddesktop = SP_ACTIVE_DESKTOP;
if (olddesktop)
olddesktop->setWaitingCursor();
@@ -252,6 +240,43 @@ sp_file_exit()
}
+// Quick and dirty internal backup function
+bool sp_file_save_backup( Glib::ustring uri ) {
+
+ Glib::ustring out = uri;
+ out.insert(out.find(".svg"),"_backup");
+
+ FILE *filein = Inkscape::IO::fopen_utf8name(uri.c_str(), "rb");
+ if (!filein) {
+ std::cerr << "sp_file_save_backup: failed to open: " << uri << std::endl;
+ return false;
+ }
+
+ FILE *fileout = Inkscape::IO::fopen_utf8name(out.c_str(), "wb");
+ if (!fileout) {
+ std::cerr << "sp_file_save_backup: failed to open: " << out << std::endl;
+ fclose( filein );
+ return false;
+ }
+
+ int ch;
+ while ((ch = fgetc(filein)) != EOF) {
+ fputc(ch, fileout);
+ }
+ fflush(fileout);
+
+ bool return_value = true;
+ if (ferror(fileout)) {
+ std::cerr << "sp_file_save_backup: error when writing to: " << out << std::endl;
+ return_value = false;
+ }
+
+ fclose(filein);
+ fclose(fileout);
+
+ return return_value;
+}
+
/*######################
## O P E N
######################*/
@@ -290,14 +315,6 @@ bool sp_file_open(const Glib::ustring &uri,
}
if (doc) {
- // Set viewBox if it doesn't exist
- if (!doc->getRoot()->viewBox_set
- && (doc->getRoot()->width.unit != SVGLength::PERCENT)
- && (doc->getRoot()->height.unit != SVGLength::PERCENT)) {
- DocumentUndo::setUndoSensitive(doc, false);
- doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit())));
- DocumentUndo::setUndoSensitive(doc, true);
- }
SPDocument *existing = desktop ? desktop->getDocument() : NULL;
@@ -324,6 +341,498 @@ bool sp_file_open(const Glib::ustring &uri,
root->original.inkscape = root->version.inkscape;
root->original.svg = root->version.svg;
+ if (INKSCAPE.use_gui()) {
+
+ // See if we need to offer the user a fix for the 90->96 px per inch change.
+ // std::cout << "SPFileOpen:" << std::endl;
+ // std::cout << " Version: " << sp_version_to_string(root->version.inkscape) << std::endl;
+
+ if ( sp_version_inside_range( root->version.inkscape, 0, 1, 0, 92 ) ) {
+
+ // std::cout << " SVG file from old Inkscape version detected: "
+ // << sp_version_to_string(root->version.inkscape) << std::endl;
+ static const double ratio = 90.0/96.0;
+
+ bool need_fix_viewbox = false;
+ bool need_fix_units = false;
+ bool need_fix_guides = false;
+ bool need_fix_grid_mm = false;
+ bool need_fix_box3d = false;
+ bool did_scaling = false;
+
+ // Check if potentially need viewbox or unit fix
+ switch (root->width.unit) {
+ case SP_CSS_UNIT_PC:
+ case SP_CSS_UNIT_PT:
+ case SP_CSS_UNIT_MM:
+ case SP_CSS_UNIT_CM:
+ case SP_CSS_UNIT_IN:
+ need_fix_viewbox = true;
+ break;
+ case SP_CSS_UNIT_NONE:
+ case SP_CSS_UNIT_PX:
+ need_fix_units = true;
+ break;
+ case SP_CSS_UNIT_EM:
+ case SP_CSS_UNIT_EX:
+ case SP_CSS_UNIT_PERCENT:
+ // OK
+ break;
+ default:
+ std::cerr << "sp_file_open: Unhandled width unit!" << std::endl;
+ }
+
+ switch (root->height.unit) {
+ case SP_CSS_UNIT_PC:
+ case SP_CSS_UNIT_PT:
+ case SP_CSS_UNIT_MM:
+ case SP_CSS_UNIT_CM:
+ case SP_CSS_UNIT_IN:
+ need_fix_viewbox = true;
+ break;
+ case SP_CSS_UNIT_NONE:
+ case SP_CSS_UNIT_PX:
+ need_fix_units = true;
+ break;
+ case SP_CSS_UNIT_EM:
+ case SP_CSS_UNIT_EX:
+ case SP_CSS_UNIT_PERCENT:
+ // OK
+ break;
+ default:
+ std::cerr << "sp_file_open: Unhandled height unit!" << std::endl;
+ }
+
+ // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl;
+ // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl;
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ if (!root->viewBox_set && need_fix_viewbox) {
+
+ Glib::ustring msg = _(
+ "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n"
+ "Drawing elements may be too small. This can be corrected by\n"
+ "either setting the SVG 'viewBox' to compensate or by scaling\n"
+ "all the elements in the drawing.");
+ Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false);
+
+ Gtk::Label info;
+ info.set_markup(msg.c_str());
+ info.show();
+ scaleDialog.get_content_area()->pack_start(info, false, false, 20);
+
+ Gtk::CheckButton backupButton( _("Create backup file (in same directory).") );
+ bool backup = prefs->getBool("/options/dpifixbackup", true);
+ backupButton.set_active( backup );
+ backupButton.show();
+ scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20);
+
+ scaleDialog.add_button(_("Set 'viewBox'"), 1);
+ scaleDialog.add_button(_("Scale elements"), 2);
+ scaleDialog.add_button(_("Ignore"), 3);
+ scaleDialog.add_button("Scale test - group", 4);
+ scaleDialog.add_button("Scale test - children", 5);
+ scaleDialog.add_button("Scale test - all", 6);
+
+ gint response = scaleDialog.run();
+ backup = backupButton.get_active();
+ prefs->setBool("/options/dpifixbackup", backup);
+
+ if ( backup && response != 3) {
+ sp_file_save_backup( uri );
+ }
+
+ if (response == 1) {
+
+ doc->setViewBox(Geom::Rect::from_xywh(
+ 0, 0,
+ doc->getWidth().value("px") * ratio,
+ doc->getHeight().value("px") * ratio));
+
+ } else if (response == 2 ) {
+
+ std::list<Inkscape::Extension::Effect *> effects;
+ Inkscape::Extension::db.get_effect_list(effects);
+ std::list<Inkscape::Extension::Effect *>::iterator it = effects.begin();
+ bool did = false;
+ while (it != effects.end()) {
+ if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) {
+ Inkscape::UI::View::View *view = desktop;
+ (*it)->effect(view);
+ did = true;
+ break;
+ }
+ ++it;
+ }
+ if (!did) {
+ std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl;
+ }
+ did_scaling = true;
+
+ } else if (response == 4) {
+
+ // Save preferences
+ bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true);
+ bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
+
+ prefs->setBool("/options/kbselection/onlysensitive", false);
+ prefs->setBool("/options/kbselection/onlyvisible", false);
+
+ Inkscape::Selection *selection = desktop->getSelection();
+ Inkscape::SelectionHelper::selectAllInAll( desktop );
+ selection->group();
+ SPItem * group = selection->singleItem();
+ if (group) {
+ group->setAttribute("transform","scale(1.06666667,1.06666667)");
+ } else {
+ std::cerr << "sp_file_open: Failed to get group!" << std::endl;
+ }
+ selection->clear();
+ selection->add( group );
+ selection->ungroup();
+ selection->clear();
+
+ prefs->setBool("/options/kbselection/onlysensitive", onlysensitive);
+ prefs->setBool("/options/kbselection/onlyvisible", onlyvisible );
+
+ did_scaling = true;
+
+ } else if (response == 5) {
+
+ // Save preferences
+ bool transform_stroke = prefs->getBool("/options/transform/stroke", true);
+ bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true);
+ bool transform_pattern = prefs->getBool("/options/transform/pattern", true);
+ bool transform_gradient = prefs->getBool("/options/transform/gradient", true);
+
+ prefs->setBool("/options/transform/stroke", true);
+ prefs->setBool("/options/transform/rectcorners", true);
+ prefs->setBool("/options/transform/pattern", true);
+ prefs->setBool("/options/transform/gradient", true);
+
+ Inkscape::UI::ShapeEditor::blockSetItem(true);
+ doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false);
+ Inkscape::UI::ShapeEditor::blockSetItem(false);
+
+ // Restore preferences
+ prefs->setBool("/options/transform/stroke", transform_stroke);
+ prefs->setBool("/options/transform/rectcorners", transform_rectcorners);
+ prefs->setBool("/options/transform/pattern", transform_pattern);
+ prefs->setBool("/options/transform/gradient", transform_gradient);
+
+ } else if (response == 6) {
+
+ // Save preferences
+ bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true);
+ bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
+
+ prefs->setBool("/options/kbselection/onlysensitive", false);
+ prefs->setBool("/options/kbselection/onlyvisible", false);
+
+ Inkscape::Selection *selection = desktop->getSelection();
+ Inkscape::SelectionHelper::selectAllInAll( desktop );
+
+ double height = root->height.computed;
+ selection->setScaleRelative( Geom::Point(0,height), Geom::Scale(96.0/90.0,96.0/90.0) );
+ selection->clear();
+
+ prefs->setBool("/options/kbselection/onlysensitive", onlysensitive);
+ prefs->setBool("/options/kbselection/onlyvisible", onlyvisible );
+
+ did_scaling = true;
+
+ }
+
+ need_fix_box3d = false; // setScaleRelative() handles box3d
+ need_fix_guides = true; // Always fix guides
+ }
+
+ else if (need_fix_units) {
+ Glib::ustring msg = _(
+ "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n"
+ "Drawings meant to match a physical size (e.g. Letter or A4)\n"
+ "will be too small. Scaling the drawing can correct for this.\n"
+ "Internal scaling can be handled either by setting the SVG 'viewBox'\n"
+ "attribute to compensate or by scaling all objects in the drawing.");
+ Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false);
+
+ Gtk::Label info;
+ info.set_markup(msg.c_str());
+ info.show();
+ scaleDialog.get_content_area()->pack_start(info, false, false, 20);
+
+ Gtk::CheckButton backupButton( _("Create backup file (in same directory).") );
+ bool backup = prefs->getBool("/options/dpifixbackup", true);
+ backupButton.set_active( backup );
+ backupButton.show();
+ scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20);
+
+ scaleDialog.add_button(_("Set 'viewBox'"), 1);
+ scaleDialog.add_button(_("Scale elements"), 2);
+ scaleDialog.add_button(_("Ignore"), 3);
+ scaleDialog.add_button("Scale test - group", 4);
+ scaleDialog.add_button("Scale test - children", 5);
+ scaleDialog.add_button("Scale test - all", 6);
+
+ gint response = scaleDialog.run();
+ backup = backupButton.get_active();
+ prefs->setBool("/options/dpifixbackup", backup);
+
+ if ( backup && response != 3) {
+ sp_file_save_backup( uri );
+ }
+
+ if (response == 1) {
+
+ if (!root->viewBox_set) {
+ doc->setViewBox(Geom::Rect::from_xywh(
+ 0, 0,
+ doc->getWidth().value("px"),
+ doc->getHeight().value("px")));
+ }
+ Inkscape::Util::Quantity width =
+ Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" );
+ Inkscape::Util::Quantity height =
+ Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" );
+ doc->setWidthAndHeight( width, height, false );
+
+ need_fix_guides = true; // Only fix guides if drawing scaled
+ need_fix_box3d = true;
+
+ } else if (response == 2) {
+
+ std::list<Inkscape::Extension::Effect *> effects;
+ Inkscape::Extension::db.get_effect_list(effects);
+ std::list<Inkscape::Extension::Effect *>::iterator it = effects.begin();
+ bool did = false;
+ while (it != effects.end()){
+ if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) {
+ Inkscape::UI::View::View *view = desktop;
+ (*it)->effect(view);
+ did = true;
+ break;
+ }
+ ++it;
+ }
+ if (!did) {
+ std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl;
+ }
+ need_fix_guides = true; // Only fix guides if drawing scaled
+ did_scaling = true;
+
+ } else if (response == 4) {
+
+ Inkscape::Util::Quantity width =
+ Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" );
+ Inkscape::Util::Quantity height =
+ Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" );
+ doc->setWidthAndHeight( width, height, false );
+
+ if (!root->viewBox_set) {
+
+ // Save preferences
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true);
+ bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
+
+ prefs->setBool("/options/kbselection/onlysensitive", false);
+ prefs->setBool("/options/kbselection/onlyvisible", false);
+
+ Inkscape::Selection *selection = desktop->getSelection();
+ Inkscape::SelectionHelper::selectAllInAll( desktop );
+ selection->group();
+ SPItem * group = selection->singleItem();
+ if (group) {
+ group->setAttribute("transform","scale(1.06666667,1.06666667)");
+ } else {
+ std::cerr << "sp_file_open: Failed to get group!" << std::endl;
+ }
+ selection->clear();
+ selection->add( group );
+ selection->ungroup();
+ selection->clear();
+
+ prefs->setBool("/options/kbselection/onlysensitive", onlysensitive);
+ prefs->setBool("/options/kbselection/onlyvisible", onlyvisible );
+
+ did_scaling = true;
+ }
+
+ need_fix_box3d = true;
+ need_fix_guides = true; // Only fix guides if drawing scaled
+
+ } else if (response == 5) {
+
+ Inkscape::Util::Quantity width =
+ Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" );
+ Inkscape::Util::Quantity height =
+ Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" );
+ doc->setWidthAndHeight( width, height, false );
+
+ if (!root->viewBox_set) {
+
+ // Save preferences
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool transform_stroke = prefs->getBool("/options/transform/stroke", true);
+ bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true);
+ bool transform_pattern = prefs->getBool("/options/transform/pattern", true);
+ bool transform_gradient = prefs->getBool("/options/transform/gradient", true);
+
+ prefs->setBool("/options/transform/stroke", true);
+ prefs->setBool("/options/transform/rectcorners", true);
+ prefs->setBool("/options/transform/pattern", true);
+ prefs->setBool("/options/transform/gradient", true);
+
+ Inkscape::UI::ShapeEditor::blockSetItem(true);
+ doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false);
+ Inkscape::UI::ShapeEditor::blockSetItem(false);
+
+ // Restore preferences
+ prefs->setBool("/options/transform/stroke", transform_stroke);
+ prefs->setBool("/options/transform/rectcorners", transform_rectcorners);
+ prefs->setBool("/options/transform/pattern", transform_pattern);
+ prefs->setBool("/options/transform/gradient", transform_gradient);
+
+ did_scaling = true;
+
+ }
+
+ } else if (response == 6) {
+
+ double old_height = root->height.computed;
+ Inkscape::Util::Quantity width =
+ Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" );
+ Inkscape::Util::Quantity height =
+ Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" );
+ doc->setWidthAndHeight( width, height, false );
+
+ if (!root->viewBox_set) {
+
+ // Save preferences
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true);
+ bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
+
+ prefs->setBool("/options/kbselection/onlysensitive", false);
+ prefs->setBool("/options/kbselection/onlyvisible", false);
+
+ Inkscape::Selection *selection = desktop->getSelection();
+ Inkscape::SelectionHelper::selectAllInAll( desktop );
+ double height = root->height.computed;
+
+ // So far we have just enlarged the drawing but due to the
+ // inverted coordinate system we must scale around the old
+ // height position.
+ selection->setScaleRelative( Geom::Point(0,old_height), Geom::Scale(96.0/90.0,96.0/90.0) );
+ selection->clear();
+
+ prefs->setBool("/options/kbselection/onlysensitive", onlysensitive);
+ prefs->setBool("/options/kbselection/onlyvisible", onlyvisible );
+
+ did_scaling = true;
+ }
+
+ need_fix_box3d = false; // setScaleRelative() handls box3s
+ need_fix_guides = true; // Only fix guides if drawing scaled
+
+ } else {
+ // Ignore
+ need_fix_grid_mm = true;
+ }
+ }
+
+ // Fix guides and grids and perspective
+ for (SPObject *child = root->firstChild() ; child; child = child->getNext() ) {
+ SPNamedView *nv = dynamic_cast<SPNamedView *>(child);
+ if (nv) {
+ if (need_fix_guides) {
+ // std::cout << "Fixing guides" << std::endl;
+ for (SPObject *child2 = nv->firstChild() ; child2; child2 = child2->getNext() ) {
+ SPGuide *gd = dynamic_cast<SPGuide *>(child2);
+ if (gd) {
+ gd->moveto( gd->getPoint() / ratio, true );
+ }
+ }
+ }
+
+ for(std::vector<Inkscape::CanvasGrid *>::const_iterator it=nv->grids.begin();it!=nv->grids.end();++it ) {
+ Inkscape::CanvasXYGrid *xy = dynamic_cast<Inkscape::CanvasXYGrid *>(*it);
+ if (xy) {
+ // std::cout << "A grid: " << xy->getSVGName() << std::endl;
+ // std::cout << " Origin: " << xy->origin
+ // << " Spacing: " << xy->spacing << std::endl;
+ // std::cout << (xy->isLegacy()?" Legacy":" Not Legacy") << std::endl;
+ Geom::Scale scale = doc->getDocumentScale();
+ if (xy->isLegacy()) {
+ if (xy->isPixel()) {
+ if (need_fix_grid_mm) {
+ xy->Scale( Geom::Scale(1,1) ); // See note below
+ } else {
+ scale *= Geom::Scale(ratio,ratio);
+ xy->Scale( scale.inverse() ); /* *** */
+ }
+ } else {
+ if (need_fix_grid_mm) {
+ xy->Scale( Geom::Scale(ratio,ratio) );
+ } else {
+ xy->Scale( scale.inverse() ); /* *** */
+ }
+ }
+ } else {
+ if (need_fix_guides) {
+ if(did_scaling){
+ xy->Scale( Geom::Scale(ratio,ratio).inverse() );
+ } else {
+ // HACK: Scaling the document does not seem to cause
+ // grids defined in document units to be updated.
+ // This forces an update.
+ xy->Scale( Geom::Scale(1,1) );
+ }
+ }
+ }
+ }
+ }
+ } // If SPNamedView
+
+ SPDefs *defs = dynamic_cast<SPDefs *>(child);
+ if (defs && need_fix_box3d) {
+ for (SPObject *child = defs->firstChild() ; child; child = child->getNext() ) {
+ Persp3D* persp3d = dynamic_cast<Persp3D *>(child);
+ if (persp3d) {
+ std::vector<Glib::ustring> tokens;
+
+ const gchar* vp_x = persp3d->getAttribute("inkscape:vp_x");
+ const gchar* vp_y = persp3d->getAttribute("inkscape:vp_y");
+ const gchar* vp_z = persp3d->getAttribute("inkscape:vp_z");
+ const gchar* vp_o = persp3d->getAttribute("inkscape:persp3d-origin");
+ // std::cout << "Found Persp3d: "
+ // << " vp_x: " << vp_x
+ // << " vp_y: " << vp_y
+ // << " vp_z: " << vp_z << std::endl;
+ Proj::Pt2 pt_x (vp_x);
+ Proj::Pt2 pt_y (vp_y);
+ Proj::Pt2 pt_z (vp_z);
+ Proj::Pt2 pt_o (vp_o);
+ pt_x = pt_x * (1.0/ratio);
+ pt_y = pt_y * (1.0/ratio);
+ pt_z = pt_z * (1.0/ratio);
+ pt_o = pt_o * (1.0/ratio);
+ persp3d->setAttribute("inkscape:vp_x",pt_x.coord_string());
+ persp3d->setAttribute("inkscape:vp_y",pt_y.coord_string());
+ persp3d->setAttribute("inkscape:vp_z",pt_z.coord_string());
+ persp3d->setAttribute("inkscape:persp3d-origin",pt_o.coord_string());
+ }
+ }
+ }
+ } // Look for SPNamedView and SPDefs loop
+
+ // desktop->getDocument()->ensureUpToDate(); // Does not update box3d!
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Update Document"));
+
+ } // If old Inkscape version
+ } // If use_gui
+
// resize the window to match the document properties
sp_namedview_window_from_document(desktop);
sp_namedview_update_layers_from_document(desktop);
@@ -1122,21 +1631,25 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
for (Inkscape::XML::Node *obj = clipboard->firstChild() ; obj ; obj = obj->next()) {
if(target_document->getObjectById(obj->attribute("id"))) continue;
Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc());
- target_parent->appendChild(obj_copy);
+ SPObject * pasted = desktop->currentLayer()->appendChildRepr(obj_copy);
Inkscape::GC::release(obj_copy);
+ SPLPEItem * pasted_lpe_item = dynamic_cast<SPLPEItem *>(pasted);
+ if (pasted_lpe_item){
+ pasted_lpe_item->forkPathEffectsIfNecessary(1);
+ }
pasted_objects_not.push_back(obj_copy);
}
Inkscape::Selection *selection = desktop->getSelection();
selection->setReprList(pasted_objects_not);
Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
- sp_selection_delete(desktop);
+ selection->applyAffine(desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
+ selection->deleteItems();
// Change the selection to the freshly pasted objects
selection->setReprList(pasted_objects);
// Apply inverse of parent transform
- sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
+ selection->applyAffine(desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
// Update (among other things) all curves in paths, for bounds() to work
target_document->ensureUpToDate();
@@ -1166,8 +1679,9 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
m.unSetup();
}
- sp_selection_move_relative(selection, offset);
+ selection->moveRelative(offset);
}
+ target_document->emitReconstructionFinish();
}
@@ -1204,12 +1718,23 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// Count the number of top-level items in the imported document.
guint items_count = 0;
- for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext()) {
- if (SP_IS_ITEM(child)) {
+ SPObject *o = NULL;
+ for (auto& child: doc->getRoot()->children) {
+ if (SP_IS_ITEM(&child)) {
items_count++;
+ o = &child;
}
}
+ //ungroup if necessary
+ bool did_ungroup = false;
+ while(items_count==1 && o && SP_IS_GROUP(o) && o->children.size()==1){
+ std::vector<SPItem *>v;
+ sp_item_group_ungroup(SP_GROUP(o),v,false);
+ o = v.empty() ? NULL : v[0];
+ did_ungroup=true;
+ }
+
// Create a new group if necessary.
Inkscape::XML::Node *newgroup = NULL;
if ((style && style->attributeList()) || items_count > 1) {
@@ -1234,9 +1759,9 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// Construct a new object representing the imported image,
// and insert it into the current document.
SPObject *new_obj = NULL;
- for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext() ) {
- if (SP_IS_ITEM(child)) {
- Inkscape::XML::Node *newitem = child->getRepr()->duplicate(xml_in_doc);
+ for (auto& child: doc->getRoot()->children) {
+ if (SP_IS_ITEM(&child)) {
+ Inkscape::XML::Node *newitem = did_ungroup ? o->getRepr()->duplicate(xml_in_doc) : child.getRepr()->duplicate(xml_in_doc);
// convert layers to groups, and make sure they are unlocked
// FIXME: add "preserve layers" mode where each layer from
@@ -1249,13 +1774,14 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
}
// don't lose top-level defs or style elements
- else if (child->getRepr()->type() == Inkscape::XML::ELEMENT_NODE) {
- const gchar *tag = child->getRepr()->name();
+ else if (child.getRepr()->type() == Inkscape::XML::ELEMENT_NODE) {
+ const gchar *tag = child.getRepr()->name();
if (!strcmp(tag, "svg:style")) {
- in_doc->getRoot()->appendChildRepr(child->getRepr()->duplicate(xml_in_doc));
+ in_doc->getRoot()->appendChildRepr(child.getRepr()->duplicate(xml_in_doc));
}
}
}
+ in_doc->emitReconstructionFinish();
if (newgroup) new_obj = place_to_insert->appendChildRepr(newgroup);
// release some stuff
@@ -1271,7 +1797,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// c2p is identity matrix at this point unless ensureUpToDate is called
doc->ensureUpToDate();
Geom::Affine affine = doc->getRoot()->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse();
- sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false);
+ selection->applyAffine(desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false);
// move to mouse pointer
{
@@ -1279,7 +1805,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
Geom::OptRect sel_bbox = selection->visualBounds();
if (sel_bbox) {
Geom::Point m( desktop->point() - sel_bbox->midpoint() );
- sp_selection_move_relative(selection, m, false);
+ selection->moveRelative(m, false);
}
}
}