summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7d4c2b0)
raw | patch | inline | side by side (parent: 7d4c2b0)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Thu, 27 Mar 2008 23:02:23 +0000 (23:02 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Thu, 27 Mar 2008 23:02:23 +0000 (23:02 +0000) |
src/live_effects/parameter/Makefile_insert | patch | blob | history | |
src/live_effects/parameter/path-reference.cpp | [new file with mode: 0644] | patch | blob |
src/live_effects/parameter/path-reference.h | [new file with mode: 0644] | patch | blob |
src/live_effects/parameter/path.cpp | patch | blob | history | |
src/live_effects/parameter/path.h | patch | blob | history | |
src/ui/clipboard.cpp | patch | blob | history | |
src/ui/clipboard.h | patch | blob | history |
diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert
index f56000fce33b3bec5aaf5145e8ddc046636ee7bb..484060384ef40e9223daa58addf353f227ab5baf 100644 (file)
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
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * The reference corresponding to href of LPE Path parameter.\r
+ *\r
+ * Copyright (C) 2008 Johan Engelen\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information.\r
+ */\r
+\r
+#include "live_effects/parameter/path-reference.h"\r
+\r
+#include <cstring>\r
+#include <string>\r
+#include <string.h>\r
+\r
+#include "enums.h"\r
+\r
+#include "display/curve.h"\r
+#include "livarot/Path.h"\r
+#include "prefs-utils.h"\r
+#include "sp-shape.h"\r
+#include "sp-text.h"\r
+#include "uri.h"\r
+\r
+namespace Inkscape {\r
+namespace LivePathEffect {\r
+\r
+bool PathReference::_acceptObject(SPObject * const obj) const\r
+{\r
+ if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj)) {\r
+ /* Refuse references to lpeobject */\r
+ if (obj == getOwner()) {\r
+ return false;\r
+ }\r
+ // TODO: check whether the referred path has this LPE applied, if so: deny deny deny!\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+}\r
+\r
+} // namespace LivePathEffect\r
+} // namespace Inkscape\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
diff --git a/src/live_effects/parameter/path-reference.h b/src/live_effects/parameter/path-reference.h
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef SEEN_LPE_PATH_REFERENCE_H\r
+#define SEEN_LPE_PATH_REFERENCE_H\r
+\r
+/*\r
+ * The reference corresponding to href of LPE PathParam.\r
+ *\r
+ * Copyright (C) 2008 Johan Engelen\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information.\r
+ */\r
+\r
+#include <forward.h>\r
+#include <uri-references.h>\r
+#include <sigc++/sigc++.h>\r
+\r
+class Path;\r
+\r
+namespace Inkscape {\r
+\r
+namespace XML {\r
+ struct Node;\r
+}\r
+\r
+namespace LivePathEffect {\r
+\r
+\r
+class PathReference : public Inkscape::URIReference {\r
+public:\r
+ PathReference(SPObject *owner) : URIReference(owner) {}\r
+\r
+ SPItem *getObject() const {\r
+ return (SPItem *)URIReference::getObject();\r
+ }\r
+\r
+protected:\r
+ virtual bool _acceptObject(SPObject * const obj) const;\r
+\r
+private:\r
+ PathReference(const PathReference&);\r
+ PathReference& operator=(const PathReference&);\r
+};\r
+\r
+} // namespace LivePathEffect\r
+\r
+} // namespace Inkscape\r
+\r
+\r
+\r
+#endif /* !SEEN_LPE_PATH_REFERENCE_H */\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
index db4102635fd01e40ca6461926c0d2cc9e50290d0..be26006c7e726f3e3295389c571425091ecbfaea 100644 (file)
#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 {
_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);
}
{
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);
}
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 *
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);
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 );
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);
}
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 */
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) {
_("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,
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 */
index b294c0d2e00fb445531bfc3232076290df12de1e..1f2be32c8a605e569bf9ac12828d12d309522cd0 100644 (file)
#include <gtkmm/tooltips.h>
#include "live_effects/parameter/parameter.h"
-
+#include "live_effects/parameter/path-reference.h"
#include <sigc++/sigc++.h>
namespace Inkscape {
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 31a9433658657a2d44f392ce6333b018e97bfb5f..081657cf02552e7b3dfddc547f34f569f7456c3f 100644 (file)
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
virtual bool pasteSize(bool, bool, bool);
virtual bool pastePathEffect();
virtual Glib::ustring getPathParameter();
- virtual Glib::ustring getPathObjectId();
+ virtual Glib::ustring getShapeOrTextObjectId();
ClipboardManagerImpl();
~ClipboardManagerImpl();
/**
- * @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 bb214dbf7f10e210b2e117a1602340f72453cd69..609f2a93cfbe11ad7b53d56cd1db9c524c6f9323 100644 (file)
--- a/src/ui/clipboard.h
+++ b/src/ui/clipboard.h
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: