summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2008-03-27 23:02:23 +0000
committerjohanengelen <johanengelen@users.sourceforge.net>2008-03-27 23:02:23 +0000
commit1d5965fea00bedb49232c419c22382dbf6581309 (patch)
treeaff38e478e9a621178ab80bd87ba630e8e11dac1 /src
parentcomment #define BYPASS_GLIB_SPAWN 1 to fix build on windows (diff)
downloadinkscape-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_insert2
-rw-r--r--src/live_effects/parameter/path-reference.cpp53
-rw-r--r--src/live_effects/parameter/path-reference.h60
-rw-r--r--src/live_effects/parameter/path.cpp155
-rw-r--r--src/live_effects/parameter/path.h14
-rw-r--r--src/ui/clipboard.cpp21
-rw-r--r--src/ui/clipboard.h2
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: