X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fselection-chemistry.cpp;h=62f5c57e2e80c1be0677597912b01ec41609a871;hb=b752616506705efd28f22c4d852d198ff40c7026;hp=e5e2cdc0177d7e41dbe20d9ce917758037055e15;hpb=542acb67493132a953fa9bb79b5b462b343fc3f5;p=inkscape.git diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index e5e2cdc01..62f5c57e2 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -20,6 +20,8 @@ # include "config.h" #endif +#include "selection-chemistry.h" + #include #include "svg/svg.h" @@ -70,18 +72,29 @@ #include "layer-fns.h" #include "context-fns.h" #include +#include +#include #include "helper/units.h" #include "sp-item.h" +#include "box3d.h" #include "unit-constants.h" #include "xml/simple-document.h" #include "sp-filter-reference.h" #include "gradient-drag.h" +#include "uri-references.h" +#include "live_effects/lpeobject.h" +#include "live_effects/parameter/path.h" +#include "libnr/nr-convert2geom.h" + +// For clippath editing +#include "tools-switch.h" +#include "shape-editor.h" +#include "node-context.h" +#include "nodepath.h" using NR::X; using NR::Y; -#include "selection-chemistry.h" - /* fixme: find a better place */ Inkscape::XML::Document *clipboard_document = NULL; GSList *clipboard = NULL; @@ -941,6 +954,11 @@ void sp_copy_stuff_used_by_item (GSList **defs_clip, SPItem *item, GSList const } } + // For 3D boxes copy perspectives + if (SP_IS_BOX3D(item)) { + sp_copy_single (defs_clip, SP_OBJECT(box3d_get_perspective(SP_BOX3D(item))), xml_doc); + } + if (SP_IS_TEXT_TEXTPATH (item)) { sp_copy_textpath_path (defs_clip, SP_TEXTPATH(sp_object_first_child(SP_OBJECT(item))), items, xml_doc); } @@ -1120,6 +1138,100 @@ void sp_selection_copy() g_slist_free ((GSList *) items); } + +void sp_selection_copy_lpe_pathparam(Inkscape::LivePathEffect::PathParam * pathparam) +{ + if (pathparam == NULL) + return; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + if (!clipboard_document) { + clipboard_document = new Inkscape::XML::SimpleDocument(); + } + + // clear old defs clipboard + while (defs_clipboard) { + Inkscape::GC::release((Inkscape::XML::Node *) defs_clipboard->data); + defs_clipboard = g_slist_remove (defs_clipboard, defs_clipboard->data); + } + + // clear style clipboard + if (style_clipboard) { + sp_repr_css_attr_unref (style_clipboard); + style_clipboard = NULL; + } + + //clear main clipboard + while (clipboard) { + Inkscape::GC::release((Inkscape::XML::Node *) clipboard->data); + clipboard = g_slist_remove(clipboard, clipboard->data); + } + + // make new path node and put svgd as 'd' attribute + Inkscape::XML::Node *newnode = clipboard_document->createElement("svg:path"); + gchar * svgd = pathparam->param_writeSVGValue(); + newnode->setAttribute("d", svgd); + g_free(svgd); + + clipboard = g_slist_prepend(clipboard, newnode); + + Geom::Rect bnds = Geom::bounds_exact(*pathparam); + size_clipboard = from_2geom(bnds); +} + + +//____________________________________________________________________________ + +/** Paste the bitmap in the clipboard if one is in there. + The bitmap is saved to a PNG file then imported into the document + + @return true if a bitmap was detected and pasted; false if no bitmap +*/ +static bool pastedPicFromClipboard() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if ( desktop == NULL || doc == NULL) + return false; + + Glib::RefPtr refClipboard = Gtk::Clipboard::get(); + Glib::RefPtr pic = refClipboard->wait_for_image(); + + // Stop if the system clipboard doesn't have a bitmap. + if ( pic == 0 ) + { + return false; + } //if + else + { + // Write into a file, then import the file into the document. + // Make a file name based on current time; use the current working dir. + time_t rawtime; + char filename[50]; + const char* path; + + time ( &rawtime ); + strftime (filename,50,"pastedpic_%m%d%Y_%H%M%S.png",localtime( &rawtime )); + path = (char *)prefs_get_string_attribute("dialogs.save_as", "path"); + Glib::ustring finalPath = path; + finalPath.append(G_DIR_SEPARATOR_S).append(filename); + pic->save( finalPath, "png" ); + file_import(doc, finalPath, NULL); + + // Clear the clipboard so that the bitmap in there won't always over + // ride the normal inkscape clipboard.This isn't the ideal solution. + refClipboard->set_text(""); + return true; + } //else + + return false; +} //pastedPicFromClipboard + +//____________________________________________________________________________ + void sp_selection_paste(bool in_place) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -1142,8 +1254,14 @@ void sp_selection_paste(bool in_place) } // check if something is in the clipboard + + // Stop if successfully pasted a clipboard bitmap. + if ( pastedPicFromClipboard() ) + return; + + if (clipboard == NULL) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard.")); + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing in the clipboard.")); return; } @@ -1213,11 +1331,12 @@ void sp_selection_paste_livepatheffect() return; } - paste_defs (&defs_clipboard, sp_desktop_document(desktop)); + SPDocument *doc = sp_desktop_document(desktop); + paste_defs (&defs_clipboard, doc); Inkscape::XML::Node *repr = (Inkscape::XML::Node *) clipboard->data; - char const *effectstr = repr->attribute("inkscape:path-effect"); - if (!effectstr) { + char const *effecturi = repr->attribute("inkscape:path-effect"); + if (!effecturi) { SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Clipboard does not contain a live path effect.")); return; } @@ -1225,8 +1344,13 @@ void sp_selection_paste_livepatheffect() for ( GSList const *itemlist = selection->itemList(); itemlist != NULL; itemlist = g_slist_next(itemlist) ) { SPItem *item = reinterpret_cast(itemlist->data); if ( item && SP_IS_SHAPE(item) ) { - Inkscape::XML::Node *selrepr = (Inkscape::XML::Node *) SP_OBJECT_REPR(item); - selrepr->setAttribute("inkscape:path-effect", effectstr); + SPShape * shape = SP_SHAPE(item); + + // create a private LPE object! + SPObject * obj = sp_uri_reference_resolve(doc, effecturi); + LivePathEffectObject * lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(0); + + sp_shape_set_path_effect(shape, lpeobj); // set inkscape:original-d for paths. the other shapes don't need this. if ( SP_IS_PATH(item) ) { @@ -2017,6 +2141,50 @@ void sp_selection_next_patheffect_param(SPDesktop * dt) } } +void sp_selection_edit_clip_or_mask(SPDesktop * dt, bool clip) +{ + if (!dt) return; + + Inkscape::Selection *selection = sp_desktop_selection(dt); + if ( selection && !selection->isEmpty() ) { + SPItem *item = selection->singleItem(); + if ( item ) { + SPObject *obj = NULL; + if (clip) + obj = item->clip_ref ? SP_OBJECT(item->clip_ref->getObject()) : NULL; + else + obj = item->mask_ref ? SP_OBJECT(item->mask_ref->getObject()) : NULL; + + if (obj) { + // obj is a group object, the children are the actual clippers + for ( SPObject *child = obj->children ; child ; child = child->next ) { + if ( SP_IS_ITEM(child) ) { + // If not already in nodecontext, goto it! + if (!tools_isactive(dt, TOOLS_NODES)) { + tools_switch_current(TOOLS_NODES); + } + + ShapeEditor * shape_editor = SP_NODE_CONTEXT( dt->event_context )->shape_editor; + shape_editor->set_item(SP_ITEM(child)); + Inkscape::NodePath::Path *np = shape_editor->get_nodepath(); + if (np) { + np->helperpath_rgba = clip ? 0x0000ffff : 0x800080ff; + np->helperpath_width = 1.0; + sp_nodepath_show_helperpath(np, true); + } + break; // break out of for loop after 1st encountered item + } + } + } else if (clip) { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("The selection has no applied clip path.")); + } else { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("The selection has no applied mask.")); + } + } + } +} + + namespace { template @@ -2315,12 +2483,13 @@ void sp_selection_to_marker(bool apply) sp_document_ensure_up_to_date(doc); NR::Maybe r = selection->bounds(); - if ( !r || r->isEmpty() ) { + NR::Maybe c = selection->center(); + if ( !r || !c || 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)); + NR::Point move_p = NR::Point(0, sp_document_height(doc)) - *c; move_p[NR::Y] = -move_p[NR::Y]; NR::Matrix move = NR::Matrix (NR::translate (move_p)); @@ -2377,6 +2546,45 @@ void sp_selection_to_marker(bool apply) _("Objects to marker")); } +static void sp_selection_to_guides_recursive(SPItem *item, bool deleteitem) { + if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item)) { + for (GSList *i = sp_item_group_item_list (SP_GROUP(item)); i != NULL; i = i->next) { + sp_selection_to_guides_recursive(SP_ITEM(i->data), deleteitem); + } + } else { + sp_item_convert_item_to_guides(item); + + if (deleteitem) { + SP_OBJECT(item)->deleteObject(true); + } + } +} + +void sp_selection_to_guides() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); + // we need to copy the list because it gets reset when objects are deleted + GSList *items = g_slist_copy((GSList *) selection->itemList()); + + if (!items) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to guides.")); + return; + } + + bool deleteitem = (prefs_get_int_attribute("tools", "cvg_keep_objects", 0) == 0); + + for (GSList const *i = items; i != NULL; i = i->next) { + sp_selection_to_guides_recursive(SP_ITEM(i->data), deleteitem); + } + + sp_document_done (doc, SP_VERB_EDIT_SELECTION_2_GUIDES, _("Objects to guides")); +} + void sp_selection_tile(bool apply) {