summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d5de116)
raw | patch | inline | side by side (parent: d5de116)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Tue, 9 Oct 2007 18:05:31 +0000 (18:05 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Tue, 9 Oct 2007 18:05:31 +0000 (18:05 +0000) |
diff --git a/src/marker.cpp b/src/marker.cpp
index 1fb7584623320724c76b0c964349b8347e55d10d..5cc63d9d7f0c7303f2c86c7e3cedb44c258124c0 100644 (file)
--- a/src/marker.cpp
+++ b/src/marker.cpp
#include "attributes.h"
#include "marker.h"
#include "document.h"
+#include "document-private.h"
struct SPMarkerView {
SPMarkerView *next;
@@ -713,3 +714,37 @@ sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destro
}
g_free (view);
}
+
+const gchar *
+generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix transform, NR::Matrix move)
+{
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
+ Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document));
+
+ Inkscape::XML::Node *repr = xml_doc->createElement("svg:marker");
+ repr->setAttribute("markerUnits", "userSpaceOnUse");
+ sp_repr_set_svg_double(repr, "markerWidth", bounds.extent(NR::X));
+ sp_repr_set_svg_double(repr, "markerHeight", bounds.extent(NR::Y));
+
+ repr->setAttribute("orient", "auto");
+
+
+ defsrepr->appendChild(repr);
+ const gchar *mark_id = repr->attribute("id");
+ SPObject *mark_object = document->getObjectById(mark_id);
+
+ for (GSList *i = reprs; i != NULL; i = i->next) {
+ Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data);
+ SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node));
+
+ NR::Matrix dup_transform;
+ if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
+ dup_transform = NR::identity();
+ dup_transform *= move;
+
+ sp_item_write_transform(copy, SP_OBJECT_REPR(copy), dup_transform);
+ }
+
+ Inkscape::GC::release(repr);
+ return mark_id;
+}
diff --git a/src/marker.h b/src/marker.h
index 1fba52d36b820eafb163a959f914f646880cf302..ef8fcd583c9a0f7b9c9eed2f2b09af563394579d 100644 (file)
--- a/src/marker.h
+++ b/src/marker.h
unsigned int key, unsigned int pos,
NR::Matrix const &base, float linewidth);
void sp_marker_hide (SPMarker *marker, unsigned int key);
+const gchar *generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix transform, NR::Matrix move);
+
#endif
diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h
index 97b9a34ad76e1bdaeac56250a25b625655be3204..71c07e1f946f024ee18e07106384f4a3fcaebd17 100644 (file)
--- a/src/menus-skeleton.h
+++ b/src/menus-skeleton.h
" <verb verb-id=\"ObjectsToPattern\" />\n"
" <verb verb-id=\"ObjectsFromPattern\" />\n"
" </submenu>\n"
+" <verb verb-id=\"ObjectsToMarker\" />\n"
" <separator/>\n"
" <verb verb-id=\"SelectionRaise\" />\n"
" <verb verb-id=\"SelectionLower\" />\n"
index 0d7654bb1efd8fdcd32b9097162aec3dca176459..ec4f096dd4164290f04695316f792e412ee5c0c6 100644 (file)
}
}
+
+void sp_selection_to_marker(bool apply)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop == NULL)
+ return;
+
+ SPDocument *doc = sp_desktop_document(desktop);
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
+
+ // check if something is selected
+ if (selection->isEmpty()) {
+ desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to marker."));
+ return;
+ }
+
+ sp_document_ensure_up_to_date(doc);
+ NR::Maybe<NR::Rect> r = selection->bounds();
+ if ( !r || r->isEmpty() ) {
+ return;
+ }
+
+ // calculate the transform to be applied to objects to move them to 0,0
+ NR::Point move_p = NR::Point(0, sp_document_height(doc)) - (r->min() + NR::Point ((r->extent(NR::X))/2, (r->extent(NR::Y))/2));
+ move_p[NR::Y] = -move_p[NR::Y];
+ NR::Matrix move = NR::Matrix (NR::translate (move_p));
+
+ GSList *items = g_slist_copy((GSList *) selection->itemList());
+
+ items = g_slist_sort (items, (GCompareFunc) sp_object_compare_position);
+
+ // bottommost object, after sorting
+ SPObject *parent = SP_OBJECT_PARENT (items->data);
+
+ NR::Matrix parent_transform = sp_item_i2root_affine(SP_ITEM(parent));
+
+ // remember the position of the first item
+ gint pos = SP_OBJECT_REPR (items->data)->position();
+
+ // create a list of duplicates
+ GSList *repr_copies = NULL;
+ for (GSList *i = items; i != NULL; i = i->next) {
+ Inkscape::XML::Node *dup = (SP_OBJECT_REPR (i->data))->duplicate(xml_doc);
+ repr_copies = g_slist_prepend (repr_copies, dup);
+ }
+
+ NR::Rect bounds(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
+
+ if (apply) {
+ // delete objects so that their clones don't get alerted; this object will be restored shortly
+ for (GSList *i = items; i != NULL; i = i->next) {
+ SPObject *item = SP_OBJECT (i->data);
+ item->deleteObject (false);
+ }
+ }
+
+ // Hack: Temporarily set clone compensation to unmoved, so that we can move clone-originals
+ // without disturbing clones.
+ // See ActorAlign::on_button_click() in src/ui/dialog/align-and-distribute.cpp
+ int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+ prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+
+ const gchar *mark_id = generate_marker (repr_copies, bounds, doc,
+ NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r->min()[NR::X], r->max()[NR::Y])))) * parent_transform.inverse(), parent_transform * move);
+
+ // restore compensation setting
+ prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+
+
+ g_slist_free (items);
+
+ sp_document_done (doc, SP_VERB_EDIT_SELECTION_2_MARKER,
+ _("Objects to marker"));
+}
+
void
sp_selection_tile(bool apply)
{
index a132161ef7ff0e7e463eefafac4ed3ddc66a738c..9313711cf7245868bd84a26fa1b0e08d6beeda6f 100644 (file)
void sp_selection_unlink();
void sp_select_clone_original ();
+void sp_selection_to_marker(bool apply = true);
+
void sp_selection_tile(bool apply = true);
void sp_selection_untile();
#endif
+
diff --git a/src/verbs.cpp b/src/verbs.cpp
index e49263ede6a7dc73be3d59ca0aa4847ef4517c5f..a84500c4406f63a62a31d2a4ac6bd3f0c03dcd74 100644 (file)
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
case SP_VERB_EDIT_CLONE_ORIGINAL:
sp_select_clone_original();
break;
+ case SP_VERB_EDIT_SELECTION_2_MARKER:
+ sp_selection_to_marker();
+ break;
case SP_VERB_EDIT_TILE:
sp_selection_tile();
break;
N_("Cut the selected clone's link to its original, turning it into a standalone object"), "edit_unlink_clone"),
new EditVerb(SP_VERB_EDIT_CLONE_ORIGINAL, "EditCloneOriginal", N_("Select _Original"),
N_("Select the object to which the selected clone is linked"), "edit_select_original"),
+ // TRANSLATORS: Convert selection to a line marker
+ new EditVerb(SP_VERB_EDIT_SELECTION_2_MARKER, "ObjectsToMarker", N_("Objects to _Marker"),
+ N_("Convert selection to a line marker"), NULL),
// TRANSLATORS: Convert selection to a rectangle with tiled pattern fill
new EditVerb(SP_VERB_EDIT_TILE, "ObjectsToPattern", N_("Objects to Patter_n"),
N_("Convert selection to a rectangle with tiled pattern fill"), NULL),
diff --git a/src/verbs.h b/src/verbs.h
index 48bf8982553e64ecf4a93d6166b45184be266e00..34a633b2f082a520cadedef4bbf05482b7dc0210 100644 (file)
--- a/src/verbs.h
+++ b/src/verbs.h
SP_VERB_EDIT_CLONE,
SP_VERB_EDIT_UNLINK_CLONE,
SP_VERB_EDIT_CLONE_ORIGINAL,
+ SP_VERB_EDIT_SELECTION_2_MARKER,
SP_VERB_EDIT_TILE,
SP_VERB_EDIT_UNTILE,
SP_VERB_EDIT_CLEAR_ALL,