diff options
| author | Johan B. C. Engelen <jbc.engelen@swissonline.ch> | 2008-03-27 23:02:23 +0000 |
|---|---|---|
| committer | johanengelen <johanengelen@users.sourceforge.net> | 2008-03-27 23:02:23 +0000 |
| commit | 1d5965fea00bedb49232c419c22382dbf6581309 (patch) | |
| tree | aff38e478e9a621178ab80bd87ba630e8e11dac1 /src | |
| parent | comment #define BYPASS_GLIB_SPAWN 1 to fix build on windows (diff) | |
| download | inkscape-1d5965fea00bedb49232c419c22382dbf6581309.tar.gz inkscape-1d5965fea00bedb49232c419c22382dbf6581309.zip | |
add linking to other paths to lpe-PathParam
(bzr r5209)
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/parameter/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/live_effects/parameter/path-reference.cpp | 53 | ||||
| -rw-r--r-- | src/live_effects/parameter/path-reference.h | 60 | ||||
| -rw-r--r-- | src/live_effects/parameter/path.cpp | 155 | ||||
| -rw-r--r-- | src/live_effects/parameter/path.h | 14 | ||||
| -rw-r--r-- | src/ui/clipboard.cpp | 21 | ||||
| -rw-r--r-- | src/ui/clipboard.h | 2 |
7 files changed, 277 insertions, 30 deletions
diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index f56000fce..484060384 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -17,6 +17,8 @@ live_effects_parameter_liblpeparam_a_SOURCES = \ live_effects/parameter/pointparam-knotholder.cpp \ live_effects/parameter/pointparam-knotholder.h \ live_effects/parameter/enum.h \ + live_effects/parameter/path-reference.cpp \ + live_effects/parameter/path-reference.h \ live_effects/parameter/path.cpp \ live_effects/parameter/path.h diff --git a/src/live_effects/parameter/path-reference.cpp b/src/live_effects/parameter/path-reference.cpp new file mode 100644 index 000000000..6a48f446b --- /dev/null +++ b/src/live_effects/parameter/path-reference.cpp @@ -0,0 +1,53 @@ +/*
+ * The reference corresponding to href of LPE Path parameter.
+ *
+ * Copyright (C) 2008 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include "live_effects/parameter/path-reference.h"
+
+#include <cstring>
+#include <string>
+#include <string.h>
+
+#include "enums.h"
+
+#include "display/curve.h"
+#include "livarot/Path.h"
+#include "prefs-utils.h"
+#include "sp-shape.h"
+#include "sp-text.h"
+#include "uri.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+bool PathReference::_acceptObject(SPObject * const obj) const
+{
+ if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj)) {
+ /* Refuse references to lpeobject */
+ if (obj == getOwner()) {
+ return false;
+ }
+ // TODO: check whether the referred path has this LPE applied, if so: deny deny deny!
+ return true;
+ } else {
+ return false;
+ }
+}
+
+} // namespace LivePathEffect
+} // namespace Inkscape
+
+/*
+ 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:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/live_effects/parameter/path-reference.h b/src/live_effects/parameter/path-reference.h new file mode 100644 index 000000000..88147d908 --- /dev/null +++ b/src/live_effects/parameter/path-reference.h @@ -0,0 +1,60 @@ +#ifndef SEEN_LPE_PATH_REFERENCE_H
+#define SEEN_LPE_PATH_REFERENCE_H
+
+/*
+ * The reference corresponding to href of LPE PathParam.
+ *
+ * Copyright (C) 2008 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include <forward.h>
+#include <uri-references.h>
+#include <sigc++/sigc++.h>
+
+class Path;
+
+namespace Inkscape {
+
+namespace XML {
+ struct Node;
+}
+
+namespace LivePathEffect {
+
+
+class PathReference : public Inkscape::URIReference {
+public:
+ PathReference(SPObject *owner) : URIReference(owner) {}
+
+ SPItem *getObject() const {
+ return (SPItem *)URIReference::getObject();
+ }
+
+protected:
+ virtual bool _acceptObject(SPObject * const obj) const;
+
+private:
+ PathReference(const PathReference&);
+ PathReference& operator=(const PathReference&);
+};
+
+} // namespace LivePathEffect
+
+} // namespace Inkscape
+
+
+
+#endif /* !SEEN_LPE_PATH_REFERENCE_H */
+
+/*
+ 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:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index db4102635..be26006c7 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -34,6 +34,12 @@ #include "nodepath.h" // clipboard support #include "ui/clipboard.h" +// required for linking to other paths +#include "uri.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "display/curve.h" + namespace Inkscape { @@ -46,15 +52,21 @@ PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip, _pathvector(), _pwd2(), must_recalculate_pwd2(false), - href(NULL) + href(NULL), + ref( (SPObject*)effect->getLPEObj() ) { defvalue = g_strdup(default_value); param_readSVGValue(defvalue); oncanvas_editable = true; + + ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &PathParam::ref_changed)); + } PathParam::~PathParam() { + remove_link(); + g_free(defvalue); } @@ -88,16 +100,22 @@ PathParam::param_readSVGValue(const gchar * strvalue) { if (strvalue) { _pathvector.clear(); - if (href) { - g_free(href); - href = NULL; - } + remove_link(); must_recalculate_pwd2 = true; - if (false /*if strvalue is xlink*/) { + if (strvalue[0] == '#') { + if (href) + g_free(href); href = g_strdup(strvalue); - update_from_referred(); - // TODO: add listener, because we must update when referred updates. we must always be up-to-date with referred path data + + // Now do the attaching, which emits the changed signal. + try { + ref.attach(Inkscape::URI(href)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + ref.detach(); + _pathvector = SVGD_to_2GeomPath(defvalue); + } } else { _pathvector = SVGD_to_2GeomPath(strvalue); } @@ -112,8 +130,12 @@ PathParam::param_readSVGValue(const gchar * strvalue) gchar * PathParam::param_writeSVGValue() const { - gchar * svgd = SVGD_from_2GeomPath( _pathvector ); - return svgd; + if (href) { + return href; + } else { + gchar * svgd = SVGD_from_2GeomPath( _pathvector ); + return svgd; + } } Gtk::Widget * @@ -155,6 +177,16 @@ PathParam::param_newWidget(Gtk::Tooltips * tooltips) static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true); tooltips->set_tip(*pButton, _("Paste path")); + pIcon = Gtk::manage( sp_icon_get_icon( "edit_clone", Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); + static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true); + tooltips->set_tip(*pButton, _("Link to path")); + static_cast<Gtk::HBox*>(_widget)->show_all_children(); return dynamic_cast<Gtk::Widget *> (_widget); @@ -187,8 +219,9 @@ PathParam::param_setup_nodepath(Inkscape::NodePath::Path *np) void PathParam::param_transform_multiply(Geom::Matrix const& postmul, bool /*set*/) { - // TODO: recode this to apply transform to _pathvector instead? if (!href) { + // TODO: recode this to apply transform to _pathvector instead? + // only apply transform when not referring to other path ensure_pwd2(); param_set_and_write_new_value( _pwd2 * postmul ); @@ -198,6 +231,7 @@ PathParam::param_transform_multiply(Geom::Matrix const& postmul, bool /*set*/) void PathParam::param_set_and_write_new_value (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & newpath) { + remove_link(); _pathvector = Geom::path_from_piecewise(newpath, LPE_CONVERSION_TOLERANCE); gchar * svgd = SVGD_from_2GeomPath( _pathvector ); param_write_to_repr(svgd); @@ -221,16 +255,71 @@ PathParam::ensure_pwd2() } void -PathParam::update_from_referred() +PathParam::start_listening(SPObject * to) { - if (!href) { - g_warning("PathParam::update_from_referred - logical error, this should not possible"); + if ( to == NULL ) { return; } + linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &PathParam::linked_delete)); + linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &PathParam::linked_modified)); + linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated +} - // TODO: implement! - - // optimize, only update from referred when referred changed. +void +PathParam::quit_listening(void) +{ + linked_modified_connection.disconnect(); + linked_delete_connection.disconnect(); +} + +void +PathParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref) +{ + quit_listening(); + if ( new_ref ) { + start_listening(new_ref); + } +} + +void +PathParam::remove_link() +{ + if (href) { + ref.detach(); + g_free(href); + href = NULL; + } +} + +void +PathParam::linked_delete(SPObject */*deleted*/) +{ +// don't know what to do yet. not acting probably crashes inkscape. + g_message("PathParam::linked_delete"); +} + +void +PathParam::linked_modified(SPObject *linked_obj, guint /*flags*/) +{ + SPCurve *curve = NULL; + if (SP_IS_SHAPE(linked_obj)) { + curve = sp_shape_get_curve(SP_SHAPE(linked_obj)); + } + if (SP_IS_TEXT(linked_obj)) { + curve = SP_TEXT(linked_obj)->getNormalizedBpath(); + } + + if (curve == NULL) { + // curve invalid, set default value + _pathvector = SVGD_to_2GeomPath(defvalue); + } else { + _pathvector = BPath_to_2GeomPath(SP_CURVE_BPATH(curve)); + sp_curve_unref(curve); + } + + must_recalculate_pwd2 = true; + signal_path_changed.emit(); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* CALLBACK FUNCTIONS FOR THE BUTTONS */ @@ -249,7 +338,8 @@ PathParam::on_paste_button_click() Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); Glib::ustring svgd = cm->getPathParameter(); - if (svgd == "") return; + if (svgd == "") + return; // Temporary hack until 2Geom supports arcs in SVGD if (svgd.find('A') != Glib::ustring::npos) { @@ -257,6 +347,9 @@ PathParam::on_paste_button_click() _("This effect does not support arcs yet, try to convert to path.") ); return; } else { + // remove possible link to path + remove_link(); + param_write_to_repr(svgd.data()); signal_path_pasted.emit(); sp_document_done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, @@ -271,6 +364,32 @@ PathParam::on_copy_button_click() cm->copyPathParameter(this); } +void +PathParam::on_link_button_click() +{ + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + Glib::ustring pathid = cm->getShapeOrTextObjectId(); + + if (pathid == "") { + return; + } + + // add '#' at start to make it an uri. + pathid.insert(pathid.begin(), '#'); + if ( href && strcmp(pathid.c_str(), href) == 0 ) { + // no change, do nothing + return; + } else { + // TODO: + // check if id really exists in document, or only in clipboard document: if only in clipboard then invalid + // check if linking to object to which LPE is applied (maybe delegated to PathReference + + param_write_to_repr(pathid.c_str()); + sp_document_done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Link path parameter to path")); + } +} + } /* namespace LivePathEffect */ } /* namespace Inkscape */ diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h index b294c0d2e..1f2be32c8 100644 --- a/src/live_effects/parameter/path.h +++ b/src/live_effects/parameter/path.h @@ -15,7 +15,7 @@ #include <gtkmm/tooltips.h> #include "live_effects/parameter/parameter.h" - +#include "live_effects/parameter/path-reference.h" #include <sigc++/sigc++.h> namespace Inkscape { @@ -60,11 +60,21 @@ protected: void ensure_pwd2(); // ensures _pwd2 is up to date gchar * href; // contains link to other object, e.g. "#path2428", NULL if PathParam contains pathdata itself - void update_from_referred(); // updates path data by looking up refered path + PathReference ref; + sigc::connection ref_changed_connection; + sigc::connection linked_delete_connection; + sigc::connection linked_modified_connection; + void ref_changed(SPObject *old_ref, SPObject *new_ref); + void remove_link(); + void start_listening(SPObject * to); + void quit_listening(void); + void linked_delete(SPObject *deleted); + void linked_modified(SPObject *linked_obj, guint flags); void on_edit_button_click(); void on_paste_button_click(); void on_copy_button_click(); + void on_link_button_click(); gchar * defvalue; diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 31a943365..081657cf0 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -95,7 +95,7 @@ public: virtual bool pasteSize(bool, bool, bool); virtual bool pastePathEffect(); virtual Glib::ustring getPathParameter(); - virtual Glib::ustring getPathObjectId(); + virtual Glib::ustring getShapeOrTextObjectId(); ClipboardManagerImpl(); ~ClipboardManagerImpl(); @@ -439,25 +439,28 @@ Glib::ustring ClipboardManagerImpl::getPathParameter() /** - * @brief Get path object id from the clipboard - * @return The retrieved path id string (contents of the id attribute), or "" if no path was found + * @brief Get object id of a shape or text item from the clipboard + * @return The retrieved id string (contents of the id attribute), or "" if no shape or text item was found */ -Glib::ustring ClipboardManagerImpl::getPathObjectId() +Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId() { SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(SP_ACTIVE_DESKTOP, _("Nothing on the clipboard.")); return ""; } - Inkscape::XML::Node - *root = sp_document_repr_root(tempdoc), - *path = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth - if ( path == NULL ) { + Inkscape::XML::Node *root = sp_document_repr_root(tempdoc); + + Inkscape::XML::Node *repr = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth + if ( repr == NULL ) + repr = sp_repr_lookup_name(root, "svg:text", -1); + + if ( repr == NULL ) { _userWarn(SP_ACTIVE_DESKTOP, _("Clipboard does not contain a path.")); sp_document_unref(tempdoc); return ""; } - gchar const *svgd = path->attribute("id"); + gchar const *svgd = repr->attribute("id"); return svgd; } diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h index bb214dbf7..609f2a93c 100644 --- a/src/ui/clipboard.h +++ b/src/ui/clipboard.h @@ -46,7 +46,7 @@ public: virtual bool pasteSize(bool separately, bool apply_x, bool apply_y) = 0; virtual bool pastePathEffect() = 0; virtual Glib::ustring getPathParameter() = 0; - virtual Glib::ustring getPathObjectId() = 0; + virtual Glib::ustring getShapeOrTextObjectId() = 0; static ClipboardManager *get(); protected: |
