summaryrefslogtreecommitdiffstats
path: root/src/live_effects/parameter/satellite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/live_effects/parameter/satellite.cpp')
-rw-r--r--src/live_effects/parameter/satellite.cpp295
1 files changed, 295 insertions, 0 deletions
diff --git a/src/live_effects/parameter/satellite.cpp b/src/live_effects/parameter/satellite.cpp
new file mode 100644
index 0000000..989a73a
--- /dev/null
+++ b/src/live_effects/parameter/satellite.cpp
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Abhishek Sharma
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include "live_effects/parameter/satellite.h"
+
+#include "bad-uri-exception.h"
+#include "desktop.h"
+#include "enums.h"
+#include "inkscape.h"
+#include "live_effects/effect.h"
+#include "live_effects/lpeobject.h"
+#include "message-stack.h"
+#include "selection-chemistry.h"
+#include "svg/svg.h"
+#include "ui/icon-loader.h"
+#include "ui/widget/point.h"
+#include "xml/repr.h"
+// clipboard support
+#include "ui/clipboard.h"
+// required for linking to other paths
+#include <glibmm/i18n.h>
+
+#include "bad-uri-exception.h"
+#include "object/sp-item.h"
+#include "object/uri.h"
+#include "ui/icon-names.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+SatelliteParam::SatelliteParam(const Glib::ustring &label, const Glib::ustring &tip, const Glib::ustring &key,
+ Inkscape::UI::Widget::Registry *wr, Effect *effect)
+ : Parameter(label, tip, key, wr, effect)
+ , lperef(std::make_shared<SatelliteReference>(param_effect->getLPEObj(), false))
+ , last_transform(Geom::identity())
+{}
+
+SatelliteParam::~SatelliteParam()
+{
+ quit_listening();
+}
+
+std::vector<SPObject *> SatelliteParam::param_get_satellites()
+{
+ std::vector<SPObject *> objs;
+ // we reload connexions in case are lost for example item recreation on ungroup
+ if (!linked_transformed_connection) {
+ write_to_SVG();
+ }
+
+ SPObject * linked_obj = lperef->getObject();
+ if (linked_obj) {
+ objs.push_back(linked_obj);
+ }
+ return objs;
+}
+
+bool SatelliteParam::param_readSVGValue(const gchar *strvalue)
+{
+ if (strvalue) {
+ bool write = false;
+ auto lpeitems = param_effect->getCurrrentLPEItems();
+ Glib::ustring id_tmp;
+ if (!lpeitems.size() && !param_effect->is_applied && !param_effect->getSPDoc()->isSeeking()) {
+ SPObject * old_ref = param_effect->getSPDoc()->getObjectByHref(strvalue);
+ if (old_ref) {
+ SPObject * successor = old_ref->_successor;
+ // cast to effect is not possible now
+ if (!g_strcmp0("clone_original", param_effect->getLPEObj()->getAttribute("effect"))) {
+ id_tmp = strvalue;
+ }
+ if (successor) {
+ id_tmp = successor->getId();
+ id_tmp.insert(id_tmp.begin(), '#');
+ write = true;
+ }
+ strvalue = id_tmp.c_str();
+ }
+ }
+ SPObject *old_ref = lperef->getObject();
+ if (old_ref) {
+ unlink();
+ }
+ if (strvalue[0] == '#') {
+ try {
+ lperef->attach(Inkscape::URI(g_strdup(strvalue)));
+ // lp:1299948
+ SPObject *new_ref = lperef->getObject();
+ if (new_ref) {
+ linked_changed(old_ref, new_ref);
+ // linked_modified(new_ref, SP_OBJECT_STYLESHEET_MODIFIED_FLAG);
+ } // else: document still processing new events. Repr of the linked object not created yet.
+ } catch (Inkscape::BadURIException &e) {
+ g_warning("%s", e.what());
+ lperef->detach();
+ }
+ } else if (!lpeitems.size() && !param_effect->is_applied && !param_effect->getSPDoc()->isSeeking()) {
+ param_write_to_repr("");
+ }
+ if (write) {
+ auto full = param_getSVGValue();
+ param_write_to_repr(full.c_str());
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool SatelliteParam::linksToItem() const
+{
+ return lperef->isAttached();
+}
+
+SPObject *SatelliteParam::getObject() const
+{
+ return lperef->isAttached() ? lperef->getObject() : nullptr;
+}
+
+Glib::ustring SatelliteParam::param_getSVGValue() const
+{
+ if (lperef->getURI()) {
+ return lperef->getURI()->str();
+ }
+ return "";
+}
+
+Glib::ustring SatelliteParam::param_getDefaultSVGValue() const
+{
+ return "";
+}
+
+void SatelliteParam::param_set_default()
+{
+ param_readSVGValue("");
+}
+
+void SatelliteParam::unlink()
+{
+ quit_listening();
+ if (linksToItem()) {
+ lperef->detach();
+ }
+}
+
+void SatelliteParam::link(Glib::ustring itemid)
+{
+ if (itemid.empty()) {
+ return;
+ }
+ auto *document = param_effect->getSPDoc();
+ SPObject *object = document->getObjectById(itemid);
+
+ if (object && object != getObject()) {
+ itemid.insert(itemid.begin(), '#');
+ param_write_to_repr(itemid.c_str());
+ } else {
+ param_write_to_repr("");
+ }
+ DocumentUndo::done(document, _("Link item parameter to path"), "");
+}
+
+// SIGNALS
+
+void SatelliteParam::start_listening(SPObject *to)
+{
+ if (!to) {
+ return;
+ }
+ quit_listening();
+ linked_changed_connection = lperef->changedSignal().connect(sigc::mem_fun(*this, &SatelliteParam::linked_changed));
+ SPItem *item = dynamic_cast<SPItem *>(to);
+ if (item) {
+ linked_released_connection = item->connectRelease(sigc::mem_fun(*this, &SatelliteParam::linked_released));
+ linked_modified_connection = item->connectModified(sigc::mem_fun(*this, &SatelliteParam::linked_modified));
+ linked_transformed_connection =
+ item->connectTransformed(sigc::mem_fun(*this, &SatelliteParam::linked_transformed));
+ if (!param_effect->is_load) {
+ linked_modified(item, SP_OBJECT_MODIFIED_FLAG);
+ }
+ }
+}
+
+void SatelliteParam::quit_listening()
+{
+ if (linked_changed_connection) {
+ linked_changed_connection.disconnect();
+ }
+ if (linked_released_connection) {
+ linked_released_connection.disconnect();
+ }
+ if (linked_modified_connection) {
+ linked_modified_connection.disconnect();
+ }
+ if (linked_transformed_connection) {
+ linked_transformed_connection.disconnect();
+ }
+}
+
+void SatelliteParam::linked_changed(SPObject *old_obj, SPObject *new_obj)
+{
+ quit_listening();
+ if (new_obj) {
+ start_listening(new_obj);
+ }
+}
+
+void SatelliteParam::linked_released(SPObject *released)
+{
+ unlink();
+ param_effect->processObjects(LPE_UPDATE);
+}
+
+
+void SatelliteParam::linked_modified(SPObject *linked_obj, guint flags)
+{
+ if (!_updating && (!param_effect->is_load || ownerlocator || !SP_ACTIVE_DESKTOP) &&
+ flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
+ SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG))
+ {
+ param_effect->getLPEObj()->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ last_transform = Geom::identity();
+ if (effectType() != CLONE_ORIGINAL) {
+ update_satellites();
+ }
+ }
+}
+
+void SatelliteParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item)
+{
+ if (!_updating) {
+ update_satellites();
+ }
+}
+
+// UI
+
+void SatelliteParam::addCanvasIndicators(SPLPEItem const * /*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) {}
+
+void SatelliteParam::on_link_button_click()
+{
+ Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
+ // here prevent item is reseted transform on link
+ if (effectType() == CLONE_ORIGINAL) {
+ param_effect->is_load = false;
+ }
+ auto itemid = cm->getFirstObjectID();
+ if (itemid.empty()) {
+ return;
+ }
+
+ link(itemid);
+}
+
+Gtk::Widget *SatelliteParam::param_newWidget()
+{
+ Gtk::Box *_widget = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
+ Gtk::Image *pIcon = Gtk::manage(sp_get_icon_image("edit-clone", Gtk::ICON_SIZE_BUTTON));
+ Gtk::Button *pButton = Gtk::manage(new Gtk::Button());
+ Gtk::Label *pLabel = Gtk::manage(new Gtk::Label(param_label));
+ _widget->pack_start(*pLabel, true, true);
+ pLabel->set_tooltip_text(param_tooltip);
+ pButton->set_relief(Gtk::RELIEF_NONE);
+ pIcon->show();
+ pButton->add(*pIcon);
+ pButton->show();
+ pButton->signal_clicked().connect(sigc::mem_fun(*this, &SatelliteParam::on_link_button_click));
+ _widget->pack_start(*pButton, true, true);
+ pButton->set_tooltip_text(_("Link to item on clipboard"));
+
+ _widget->show_all_children();
+
+ return dynamic_cast<Gtk::Widget *>(_widget);
+}
+
+} /* 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 :