Code

Make curvature work again by fixing a minor omission
[inkscape.git] / src / selection-chemistry.cpp
index 62fbdf172815c5a352bbe07f8e5e7c82b0833254..e55bba2a5926079ef2e3a2fd99f300d7b8e791c2 100644 (file)
@@ -27,6 +27,7 @@
 #include "svg/svg.h"
 #include "desktop.h"
 #include "desktop-style.h"
+#include "dir-util.h"
 #include "selection.h"
 #include "tools-switch.h"
 #include "desktop-handles.h"
@@ -52,6 +53,7 @@
 #include <libnr/nr-matrix-ops.h>
 #include <2geom/transforms.h>
 #include "xml/repr.h"
+#include "xml/rebase-hrefs.h"
 #include "style.h"
 #include "document-private.h"
 #include "sp-gradient.h"
@@ -728,7 +730,9 @@ sp_selection_raise(SPDesktop *desktop)
     }
 
     sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_RAISE,
-                     //TRANSLATORS: Only put the word "Raise" in the translation. Means "to raise an object" in the undo history
+                     //TRANSLATORS: only translate "string" in "context|string".
+                     // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
+                     // "Raise" means "to raise an object" in the undo history
                      Q_("undo_action|Raise"));
 }
 
@@ -1174,7 +1178,7 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live
 that case, items are already in the new position, but the repr is in the old, and this function
 then simply updates the repr from item->transform.
  */
-void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix const &affine, bool set_i2d)
+void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix const &affine, bool set_i2d, bool compensate)
 {
     if (selection->isEmpty())
         return;
@@ -1238,7 +1242,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons
                     continue;
                 for (SPObject *use = region->firstChild() ; use ; use = SP_OBJECT_NEXT(use)) {
                     if (!SP_IS_USE(use)) continue;
-                    sp_item_write_transform(SP_USE(use), SP_OBJECT_REPR(use), item->transform.inverse(), NULL);
+                    sp_item_write_transform(SP_USE(use), SP_OBJECT_REPR(use), item->transform.inverse(), NULL, compensate);
                 }
             }
         } else if (transform_clone_with_original) {
@@ -1264,30 +1268,30 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons
 
                 if (prefs_parallel) {
                     Geom::Matrix move = result * clone_move * t_inv;
-                    sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move);
+                    sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move, compensate);
 
                 } else if (prefs_unmoved) {
                     //if (SP_IS_USE(sp_use_get_original(SP_USE(item))))
                     //    clone_move = Geom::identity();
                     Geom::Matrix move = result * clone_move;
-                    sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t);
+                    sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t, compensate);
                 }
 
             } else {
                 // just apply the result
-                sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t);
+                sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t, compensate);
             }
 
         } else {
             if (set_i2d) {
                 sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * (Geom::Matrix)affine);
             }
-            sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, NULL);
+            sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, NULL, compensate);
         }
 
         // if we're moving the actual object, not just updating the repr, we can transform the
         // center by the same matrix (only necessary for non-translations)
-        if (set_i2d && item->isCenterSet() && !affine.isTranslation()) {
+        if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) {
             item->setCenter(old_center * affine);
             SP_OBJECT(item)->updateRepr();
         }
@@ -1382,9 +1386,9 @@ sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &al
     sp_selection_apply_affine(selection, final);
 }
 
-void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move)
+void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move, bool compensate)
 {
-    sp_selection_apply_affine(selection, Geom::Matrix(Geom::Translate(move)));
+    sp_selection_apply_affine(selection, Geom::Matrix(Geom::Translate(move)), true, compensate);
 }
 
 void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy)
@@ -2515,11 +2519,14 @@ sp_selection_create_bitmap_copy(SPDesktop *desktop)
     g_get_current_time(&cu);
     guint current = (int) (cu.tv_sec * 1000000 + cu.tv_usec) % 1024;
 
-    // Create the filename
-    gchar *filename = g_strdup_printf("%s-%s-%u.png", document->name, SP_OBJECT_REPR(items->data)->attribute("id"), current);
+    // Create the filename.
+    gchar *const basename = g_strdup_printf("%s-%s-%u.png",
+                                            document->name,
+                                            SP_OBJECT_REPR(items->data)->attribute("id"),
+                                            current);
     // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters,
     // digits, and a few other chars, with "_"
-    g_strcanon(filename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_');
+    g_strcanon(basename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_');
 
     // Build the complete path by adding document base dir, if set, otherwise home dir
     gchar * directory = NULL;
@@ -2529,7 +2536,7 @@ sp_selection_create_bitmap_copy(SPDesktop *desktop)
     if (directory == NULL) {
         directory = homedir_path(NULL);
     }
-    gchar *filepath = g_build_filename(directory, filename, NULL);
+    gchar *filepath = g_build_filename(directory, basename, NULL);
 
     //g_print("%s\n", filepath);
 
@@ -2631,8 +2638,12 @@ sp_selection_create_bitmap_copy(SPDesktop *desktop)
     if (pb) {
         // Create the repr for the image
         Inkscape::XML::Node * repr = xml_doc->createElement("svg:image");
-        repr->setAttribute("xlink:href", filename);
-        repr->setAttribute("sodipodi:absref", filepath);
+        {
+            repr->setAttribute("sodipodi:absref", filepath);
+            gchar *abs_base = Inkscape::XML::calc_abs_doc_base(document->base);
+            repr->setAttribute("xlink:href", sp_relative_path_from_path(filepath, abs_base));
+            g_free(abs_base);
+        }
         if (res == PX_PER_IN) { // for default 90 dpi, snap it to pixel grid
             sp_repr_set_svg_double(repr, "width", width);
             sp_repr_set_svg_double(repr, "height", height);
@@ -2667,7 +2678,7 @@ sp_selection_create_bitmap_copy(SPDesktop *desktop)
 
     desktop->clearWaitingCursor();
 
-    g_free(filename);
+    g_free(basename);
     g_free(filepath);
 }