summaryrefslogtreecommitdiffstats
path: root/src/widgets/connector-toolbar.cpp
diff options
context:
space:
mode:
authorJohn Smith <john.smith7545@yahoo.com>2012-05-08 05:21:59 +0000
committerJohn Smith <removethis.john.q.public@bigmail.com>2012-05-08 05:21:59 +0000
commit7572ee2641532716d219a9a11f03e87511ed0bab (patch)
tree72c9ccfe5b54a179a32ddbf4cae9ee07f34ce90b /src/widgets/connector-toolbar.cpp
parentFixing to use explicit enum types instead of generic guint & bool. (diff)
downloadinkscape-7572ee2641532716d219a9a11f03e87511ed0bab.tar.gz
inkscape-7572ee2641532716d219a9a11f03e87511ed0bab.zip
Fix for 986446 : Refactor toolbox into tool specific files
(bzr r11346)
Diffstat (limited to 'src/widgets/connector-toolbar.cpp')
-rw-r--r--src/widgets/connector-toolbar.cpp532
1 files changed, 532 insertions, 0 deletions
diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp
new file mode 100644
index 000000000..7112037f2
--- /dev/null
+++ b/src/widgets/connector-toolbar.cpp
@@ -0,0 +1,532 @@
+/**
+ * @file
+ * Connector aux toolbar
+ */
+/* Authors:
+ * MenTaLguY <mental@rydia.net>
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * bulia byak <buliabyak@users.sf.net>
+ * Frank Felfe <innerspace@iname.com>
+ * John Cliff <simarilius@yahoo.com>
+ * David Turner <novalis@gnu.org>
+ * Josh Andler <scislac@scislac.com>
+ * Jon A. Cruz <jon@joncruz.org>
+ * Maximilian Albert <maximilian.albert@gmail.com>
+ * Tavmjong Bah <tavmjong@free.fr>
+ * Abhishek Sharma
+ * Kris De Gussem <Kris.DeGussem@gmail.com>
+ *
+ * Copyright (C) 2004 David Turner
+ * Copyright (C) 2003 MenTaLguY
+ * Copyright (C) 1999-2011 authors
+ * Copyright (C) 2001-2002 Ximian, Inc.
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include "toolbox.h"
+#include "connector-toolbar.h"
+
+#include "../desktop.h"
+#include "../desktop-handles.h"
+#include "document-undo.h"
+#include "../verbs.h"
+#include "../inkscape.h"
+#include "../selection-chemistry.h"
+#include "../selection.h"
+
+#include "../ege-adjustment-action.h"
+#include "../ege-output-action.h"
+#include "../ege-select-one-action.h"
+#include "../ink-action.h"
+#include "../ink-comboboxentry-action.h"
+
+#include "../widgets/button.h"
+#include "../widgets/spinbutton-events.h"
+#include "ui/widget/spinbutton.h"
+#include "../widgets/spw-utilities.h"
+#include "../widgets/widget-sizes.h"
+#include "../xml/node-event-vector.h"
+#include "../xml/repr.h"
+#include "ui/uxmanager.h"
+#include "../ui/icon-names.h"
+#include "../helper/unit-menu.h"
+#include "../helper/units.h"
+#include "../helper/unit-tracker.h"
+#include "../pen-context.h"
+#include "../sp-namedview.h"
+#include "../conn-avoid-ref.h"
+#include "../connector-context.h"
+#include "../graphlayout.h"
+#include "../sp-path.h"
+
+
+using Inkscape::UnitTracker;
+using Inkscape::UI::UXManager;
+using Inkscape::DocumentUndo;
+using Inkscape::UI::ToolboxFactory;
+using Inkscape::UI::PrefPusher;
+
+
+
+//#########################
+//## Connector ##
+//#########################
+
+static void sp_connector_mode_toggled( GtkToggleAction* act, GObject * /*tbl*/ )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/tools/connector/mode",
+ gtk_toggle_action_get_active( act ));
+}
+
+static void sp_connector_path_set_avoid(void)
+{
+ cc_selection_set_avoid(true);
+}
+
+
+static void sp_connector_path_set_ignore(void)
+{
+ cc_selection_set_avoid(false);
+}
+
+static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl )
+{
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+ Inkscape::Selection * selection = sp_desktop_selection(desktop);
+ SPDocument *doc = sp_desktop_document(desktop);
+
+ if (!DocumentUndo::getUndoSensitive(doc)) {
+ return;
+ }
+
+
+ // quit if run by the _changed callbacks
+ if (g_object_get_data( tbl, "freeze" )) {
+ return;
+ }
+
+ // in turn, prevent callbacks from responding
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ bool is_orthog = gtk_toggle_action_get_active( act );
+ gchar orthog_str[] = "orthogonal";
+ gchar polyline_str[] = "polyline";
+ gchar *value = is_orthog ? orthog_str : polyline_str ;
+
+ bool modmade = false;
+ GSList *l = (GSList *) selection->itemList();
+ while (l) {
+ SPItem *item = (SPItem *) l->data;
+
+ if (cc_item_is_connector(item)) {
+ item->setAttribute( "inkscape:connector-type",
+ value, NULL);
+ item->avoidRef->handleSettingChange();
+ modmade = true;
+ }
+ l = l->next;
+ }
+
+ if (!modmade) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/tools/connector/orthogonal", is_orthog);
+ } else {
+
+ DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR,
+ is_orthog ? _("Set connector type: orthogonal"): _("Set connector type: polyline"));
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl)
+{
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+ Inkscape::Selection * selection = sp_desktop_selection(desktop);
+ SPDocument *doc = sp_desktop_document(desktop);
+
+ if (!DocumentUndo::getUndoSensitive(doc)) {
+ return;
+ }
+
+
+ // quit if run by the _changed callbacks
+ if (g_object_get_data( tbl, "freeze" )) {
+ return;
+ }
+
+ // in turn, prevent callbacks from responding
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ gdouble newValue = gtk_adjustment_get_value(adj);
+ gchar value[G_ASCII_DTOSTR_BUF_SIZE];
+ g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue);
+
+ bool modmade = false;
+ GSList *l = (GSList *) selection->itemList();
+ while (l) {
+ SPItem *item = (SPItem *) l->data;
+
+ if (cc_item_is_connector(item)) {
+ item->setAttribute( "inkscape:connector-curvature",
+ value, NULL);
+ item->avoidRef->handleSettingChange();
+ modmade = true;
+ }
+ l = l->next;
+ }
+
+ if (!modmade) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble(Glib::ustring("/tools/connector/curvature"), newValue);
+ }
+ else {
+ DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR,
+ _("Change connector curvature"));
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+
+static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl)
+{
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+ SPDocument *doc = sp_desktop_document(desktop);
+
+ if (!DocumentUndo::getUndoSensitive(doc)) {
+ return;
+ }
+
+ Inkscape::XML::Node *repr = desktop->namedview->getRepr();
+
+ if ( !repr->attribute("inkscape:connector-spacing") &&
+ ( gtk_adjustment_get_value(adj) == defaultConnSpacing )) {
+ // Don't need to update the repr if the attribute doesn't
+ // exist and it is being set to the default value -- as will
+ // happen at startup.
+ return;
+ }
+
+ // quit if run by the attr_changed listener
+ if (g_object_get_data( tbl, "freeze" )) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
+
+ sp_repr_set_css_double(repr, "inkscape:connector-spacing", gtk_adjustment_get_value(adj));
+ desktop->namedview->updateRepr();
+ bool modmade = false;
+
+ GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop);
+ for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) {
+ SPItem *item = reinterpret_cast<SPItem *>(iter->data);
+ Geom::Affine m = Geom::identity();
+ avoid_item_move(&m, item);
+ modmade = true;
+ }
+
+ if (items) {
+ g_slist_free(items);
+ }
+ if(modmade) {
+ DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR,
+ _("Change connector spacing"));
+ }
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+static void sp_connector_graph_layout(void)
+{
+ if (!SP_ACTIVE_DESKTOP) {
+ return;
+ }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ // hack for clones, see comment in align-and-distribute.cpp
+ int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+ prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+
+ graphlayout(sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList());
+
+ prefs->setInt("/options/clonecompensation/value", saved_compensation);
+
+ DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network"));
+}
+
+static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/tools/connector/directedlayout",
+ gtk_toggle_action_get_active( act ));
+}
+
+static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/tools/connector/avoidoverlaplayout",
+ gtk_toggle_action_get_active( act ));
+}
+
+
+static void connector_length_changed(GtkAdjustment *adj, GObject* /*tbl*/)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/tools/connector/length", gtk_adjustment_get_value(adj));
+}
+
+static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr,
+ gchar const *name, gchar const * /*old_value*/, gchar const * /*new_value*/,
+ bool /*is_interactive*/, gpointer data)
+{
+ GtkWidget *tbl = GTK_WIDGET(data);
+
+ if ( !g_object_get_data(G_OBJECT(tbl), "freeze")
+ && (strcmp(name, "inkscape:connector-spacing") == 0) ) {
+ GtkAdjustment *adj = static_cast<GtkAdjustment*>(g_object_get_data(G_OBJECT(tbl), "spacing"));
+ gdouble spacing = defaultConnSpacing;
+ sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing);
+
+ gtk_adjustment_set_value(adj, spacing);
+ gtk_adjustment_value_changed(adj);
+
+ spinbutton_defocus(tbl);
+ }
+}
+
+static void sp_connector_new_connection_point(GtkWidget *, GObject *tbl)
+{
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+ SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
+
+ if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
+ cc_create_connection_point(cc);
+ }
+}
+
+static void sp_connector_remove_connection_point(GtkWidget *, GObject *tbl)
+{
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+ SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
+
+ if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
+ cc_remove_connection_point(cc);
+ }
+}
+
+static Inkscape::XML::NodeEventVector connector_tb_repr_events = {
+ NULL, /* child_added */
+ NULL, /* child_removed */
+ connector_tb_event_attr_changed,
+ NULL, /* content_changed */
+ NULL /* order_changed */
+};
+
+static void sp_connector_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
+{
+ GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "curvature" ) );
+ GtkToggleAction *act = GTK_TOGGLE_ACTION( g_object_get_data( tbl, "orthogonal" ) );
+ SPItem *item = selection->singleItem();
+ if (SP_IS_PATH(item))
+ {
+ gdouble curvature = SP_PATH(item)->connEndPair.getCurvature();
+ bool is_orthog = SP_PATH(item)->connEndPair.isOrthogonal();
+ gtk_toggle_action_set_active(act, is_orthog);
+ gtk_adjustment_set_value(adj, curvature);
+ }
+
+}
+
+void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
+
+ // Editing mode toggle button
+ {
+ InkToggleAction* act = ink_toggle_action_new( "ConnectorEditModeAction",
+ _("EditMode"),
+ _("Switch between connection point editing and connector drawing mode"),
+ INKSCAPE_ICON("connector-edit"),
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+
+ bool tbuttonstate = prefs->getBool("/tools/connector/mode");
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE ));
+ g_object_set_data( holder, "mode", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_mode_toggled), holder );
+ }
+
+
+ {
+ InkAction* inky = ink_action_new( "ConnectorAvoidAction",
+ _("Avoid"),
+ _("Make connectors avoid selected objects"),
+ INKSCAPE_ICON("connector-avoid"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ }
+
+ {
+ InkAction* inky = ink_action_new( "ConnectorIgnoreAction",
+ _("Ignore"),
+ _("Make connectors ignore selected objects"),
+ INKSCAPE_ICON("connector-ignore"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ }
+
+ // Orthogonal connectors toggle button
+ {
+ InkToggleAction* act = ink_toggle_action_new( "ConnectorOrthogonalAction",
+ _("Orthogonal"),
+ _("Make connector orthogonal or polyline"),
+ INKSCAPE_ICON("connector-orthogonal"),
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+
+ bool tbuttonstate = prefs->getBool("/tools/connector/orthogonal");
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE ));
+ g_object_set_data( holder, "orthogonal", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_orthogonal_toggled), holder );
+ }
+
+ EgeAdjustmentAction* eact = 0;
+ // Curvature spinbox
+ eact = create_adjustment_action( "ConnectorCurvatureAction",
+ _("Connector Curvature"), _("Curvature:"),
+ _("The amount of connectors curvature"),
+ "/tools/connector/curvature", defaultConnCurvature,
+ GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-curvature",
+ 0, 100, 1.0, 10.0,
+ 0, 0, 0,
+ connector_curvature_changed, 1, 0 );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+
+ // Spacing spinbox
+ eact = create_adjustment_action( "ConnectorSpacingAction",
+ _("Connector Spacing"), _("Spacing:"),
+ _("The amount of space left around objects by auto-routing connectors"),
+ "/tools/connector/spacing", defaultConnSpacing,
+ GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-spacing",
+ 0, 100, 1.0, 10.0,
+ 0, 0, 0,
+ connector_spacing_changed, 1, 0 );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+
+ // Graph (connector network) layout
+ {
+ InkAction* inky = ink_action_new( "ConnectorGraphAction",
+ _("Graph"),
+ _("Nicely arrange selected connector network"),
+ INKSCAPE_ICON("distribute-graph"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ }
+
+ // Default connector length spinbox
+ eact = create_adjustment_action( "ConnectorLengthAction",
+ _("Connector Length"), _("Length:"),
+ _("Ideal length for connectors when layout is applied"),
+ "/tools/connector/length", 100,
+ GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-length",
+ 10, 1000, 10.0, 100.0,
+ 0, 0, 0,
+ connector_length_changed, 1, 0 );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+
+
+ // Directed edges toggle button
+ {
+ InkToggleAction* act = ink_toggle_action_new( "ConnectorDirectedAction",
+ _("Downwards"),
+ _("Make connectors with end-markers (arrows) point downwards"),
+ INKSCAPE_ICON("distribute-graph-directed"),
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+
+ bool tbuttonstate = prefs->getBool("/tools/connector/directedlayout");
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE ));
+
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder );
+ sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), (GObject *)holder));
+ }
+
+ // Avoid overlaps toggle button
+ {
+ InkToggleAction* act = ink_toggle_action_new( "ConnectorOverlapAction",
+ _("Remove overlaps"),
+ _("Do not allow overlapping shapes"),
+ INKSCAPE_ICON("distribute-remove-overlaps"),
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+
+ bool tbuttonstate = prefs->getBool("/tools/connector/avoidoverlaplayout");
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), (tbuttonstate ? TRUE : FALSE ));
+
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_nooverlaps_graph_layout_toggled), holder );
+ }
+
+
+ // New connection point button
+ {
+ InkAction* inky = ink_action_new( "ConnectorNewConnPointAction",
+ _("New connection point"),
+ _("Add a new connection point to the currently selected item"),
+ INKSCAPE_ICON("connector-new-connpoint"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ }
+
+ // Remove selected connection point button
+
+ {
+ InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction",
+ _("Remove connection point"),
+ _("Remove the currently selected connection point"),
+ INKSCAPE_ICON("connector-remove-connpoint"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ }
+
+
+ // Code to watch for changes to the connector-spacing attribute in
+ // the XML.
+ Inkscape::XML::Node *repr = desktop->namedview->getRepr();
+ g_assert(repr != NULL);
+
+ purge_repr_listener( holder, holder );
+
+ if (repr) {
+ g_object_set_data( holder, "repr", repr );
+ Inkscape::GC::anchor(repr);
+ sp_repr_add_listener( repr, &connector_tb_repr_events, holder );
+ sp_repr_synthesize_events( repr, &connector_tb_repr_events, holder );
+ }
+} // end of sp_connector_toolbox_prep()
+
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :