From c3a160589a9cb41c70a56e5e7b66a65857a0d10e Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Mon, 1 Jul 2013 21:04:32 +0100 Subject: Factored layer model out into new Inkscape::LayerModel class. This allows Inkscape::Selection to use a LayerModel that is not associated with a UI. Changed the interface of verbs (SPAction) to use a new ActionContext rather than UI::View::View, again so that verbs may be used in a console mode. Modified boolean operation verbs to work in console-only mode. Fixed up DESKTOP_IS_ACTIVE macro to work in the case of no desktops. Modified main.cpp to process selections and verbs in no-GUI mode. Other changes are all consequences of the SPDesktop, Selection and LayerModel interface changes. (bzr r12387.1.1) --- src/CMakeLists.txt | 2 + src/Makefile_insert | 1 + src/desktop.cpp | 172 ++++++------------------ src/desktop.h | 10 +- src/dyna-draw-context.cpp | 4 +- src/eraser-context.cpp | 2 +- src/extension/dbus/document-interface.cpp | 5 +- src/extension/effect.cpp | 4 +- src/extension/effect.h | 2 +- src/extension/internal/bluredge.cpp | 5 +- src/extension/internal/filter/filter-all.cpp | 0 src/flood-context.cpp | 2 +- src/helper/CMakeLists.txt | 2 + src/helper/Makefile_insert | 2 + src/helper/action.cpp | 36 +++-- src/helper/action.h | 11 +- src/inkscape.cpp | 2 +- src/interface.cpp | 23 ++-- src/main-cmdlineact.cpp | 24 ++-- src/main-cmdlineact.h | 7 +- src/main.cpp | 18 ++- src/selection-describer.cpp | 5 +- src/selection.cpp | 16 +-- src/selection.h | 23 +++- src/shortcuts.cpp | 3 +- src/splivarot.cpp | 81 ++++++----- src/splivarot.h | 25 ++-- src/spray-context.cpp | 2 +- src/ui/dialog/layers.cpp | 7 +- src/ui/dialog/swatches.cpp | 3 +- src/ui/dialog/symbols.cpp | 5 +- src/ui/widget/page-sizer.cpp | 3 +- src/ui/widget/style-swatch.cpp | 3 +- src/verbs.cpp | 193 ++++++++++++++------------- src/verbs.h | 9 +- src/widgets/button.cpp | 3 +- src/widgets/desktop-widget.cpp | 6 +- src/widgets/gradient-selector.cpp | 3 +- src/widgets/lpe-toolbar.cpp | 4 +- src/widgets/select-toolbar.cpp | 4 +- src/widgets/toolbox.cpp | 14 +- 41 files changed, 384 insertions(+), 362 deletions(-) mode change 100755 => 100644 src/extension/internal/filter/filter-all.cpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 49f32fdea..fa54940db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -239,6 +239,7 @@ set(inkscape_SRC knotholder.cpp layer-fns.cpp layer-manager.cpp + layer-model.cpp line-geometry.cpp line-snapper.cpp lpe-tool-context.cpp @@ -398,6 +399,7 @@ set(inkscape_SRC knotholder.h layer-fns.h layer-manager.h + layer-model.h line-geometry.h line-snapper.h lpe-tool-context.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 87b2545c8..023d640ca 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -92,6 +92,7 @@ ink_common_sources += \ knot-holder-entity.h knot-holder-entity.cpp \ layer-fns.cpp layer-fns.h \ layer-manager.cpp layer-manager.h \ + layer-model.cpp layer-model.h \ line-geometry.cpp line-geometry.h \ line-snapper.cpp line-snapper.h \ lpe-tool-context.cpp lpe-tool-context.h \ diff --git a/src/desktop.cpp b/src/desktop.cpp index 17548ee56..485fcfcc4 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -53,15 +53,16 @@ #include "display/sp-canvas-util.h" #include "document.h" #include "event-log.h" +#include "helper/action-context.h" #include "helper/units.h" #include "interface.h" #include "inkscape-private.h" #include "layer-fns.h" #include "layer-manager.h" +#include "layer-model.h" #include "macros.h" #include "message-context.h" #include "message-stack.h" -#include "object-hierarchy.h" #include "preferences.h" #include "resource-manager.h" #include "select-context.h" @@ -95,6 +96,7 @@ SPDesktop::SPDesktop() : _dlg_mgr( 0 ), namedview( 0 ), canvas( 0 ), + layer_model( 0 ), selection( 0 ), event_context( 0 ), layer_manager( 0 ), @@ -125,7 +127,6 @@ SPDesktop::SPDesktop() : gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), gr_fill_or_stroke( Inkscape::FOR_FILL ), - _layer_hierarchy( 0 ), _reconstruction_old_layer_id(), // an id attribute is not allowed to be the empty string _display_mode(Inkscape::RENDERMODE_NORMAL), _display_color_mode(Inkscape::COLORMODE_NORMAL), @@ -140,8 +141,12 @@ SPDesktop::SPDesktop() : { _d2w.setIdentity(); _w2d.setIdentity(); - - selection = Inkscape::GC::release( new Inkscape::Selection(this) ); + + layer_model = new Inkscape::LayerModel(); + layer_model->_layer_activated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_activated), this)); + layer_model->_layer_deactivated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); + layer_model->_layer_changed_signal.connect(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); + selection = Inkscape::GC::release( new Inkscape::Selection(layer_model, this) ); } void @@ -170,6 +175,9 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid dkey = SPItem::display_key_new(1); + /* Connect display key to layer model */ + layer_model->setDisplayKey(dkey); + /* Connect document */ setDocument (document); @@ -359,10 +367,7 @@ void SPDesktop::destroy() g_object_unref (G_OBJECT (ec)); } - if (_layer_hierarchy) { - delete _layer_hierarchy; -// _layer_hierarchy = NULL; //this should be here, but commented to find other bug somewhere else. - } + delete layer_model; if (layer_manager) { delete layer_manager; @@ -483,134 +488,45 @@ void SPDesktop::displayColorModeToggle() { } } -/** - * Returns current root (=bottom) layer. - */ +// Pass-through LayerModel functions SPObject *SPDesktop::currentRoot() const { - return _layer_hierarchy ? _layer_hierarchy->top() : NULL; + return layer_model->currentRoot(); } -/** - * Returns current top layer. - */ SPObject *SPDesktop::currentLayer() const { - return _layer_hierarchy ? _layer_hierarchy->bottom() : NULL; -} - -/** - * Sets the current layer of the desktop. - * - * Make \a object the top layer. - */ -void SPDesktop::setCurrentLayer(SPObject *object) { - g_return_if_fail(SP_IS_GROUP(object)); - g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); - // printf("Set Layer to ID: %s\n", object->getId()); - _layer_hierarchy->setBottom(object); + return layer_model->currentLayer(); } -void SPDesktop::toggleHideAllLayers(bool hide) { - - for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), currentRoot()); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { - SP_ITEM(obj)->setHidden(hide); - } +void SPDesktop::setCurrentLayer(SPObject *object) +{ + layer_model->setCurrentLayer(object); } -void SPDesktop::toggleLockAllLayers(bool lock) { - - for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), currentRoot()); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { - SP_ITEM(obj)->setLocked(lock); - } +void SPDesktop::toggleLayerSolo(SPObject *object) +{ + layer_model->toggleLayerSolo(object); } -void SPDesktop::toggleLockOtherLayers(SPObject *object) { - g_return_if_fail(SP_IS_GROUP(object)); - g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); - - bool othersLocked = false; - std::vector layers; - for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) { - // Dont lock any ancestors, since that would in turn lock the layer as well - if (!obj->isAncestorOf(object)) { - layers.push_back(obj); - othersLocked |= !SP_ITEM(obj)->isLocked(); - } - } - for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { - if (!obj->isAncestorOf(object)) { - layers.push_back(obj); - othersLocked |= !SP_ITEM(obj)->isLocked(); - } - } - - SPItem *item = SP_ITEM(object); - if ( item->isLocked() ) { - item->setLocked(false); - } - - for ( std::vector::iterator it = layers.begin(); it != layers.end(); ++it ) { - SP_ITEM(*it)->setLocked(othersLocked); - } +void SPDesktop::toggleHideAllLayers(bool hide) +{ + layer_model->toggleHideAllLayers(hide); } - -void SPDesktop::toggleLayerSolo(SPObject *object) { - g_return_if_fail(SP_IS_GROUP(object)); - g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); - - bool othersShowing = false; - std::vector layers; - for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) { - // Don't hide ancestors, since that would in turn hide the layer as well - if (!obj->isAncestorOf(object)) { - layers.push_back(obj); - othersShowing |= !SP_ITEM(obj)->isHidden(); - } - } - for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { - if (!obj->isAncestorOf(object)) { - layers.push_back(obj); - othersShowing |= !SP_ITEM(obj)->isHidden(); - } - } - - - SPItem *item = SP_ITEM(object); - if ( item->isHidden() ) { - item->setHidden(false); - } - - for ( std::vector::iterator it = layers.begin(); it != layers.end(); ++it ) { - SP_ITEM(*it)->setHidden(othersShowing); - } +void SPDesktop::toggleLockAllLayers(bool lock) +{ + layer_model->toggleLockAllLayers(lock); } -/** - * Return layer that contains \a object. - */ -SPObject *SPDesktop::layerForObject(SPObject *object) { - g_return_val_if_fail(object != NULL, NULL); - - SPObject *root=currentRoot(); - object = object->parent; - while ( object && object != root && !isLayer(object) ) { - // Objects in defs have no layer and are NOT in the root layer - if(SP_IS_DEFS(object)) - return NULL; - object = object->parent; - } - return object; +void SPDesktop::toggleLockOtherLayers(SPObject *object) +{ + layer_model->toggleLockOtherLayers(object); } -/** - * True if object is a layer. - */ -bool SPDesktop::isLayer(SPObject *object) const { - return ( SP_IS_GROUP(object) - && ( SP_GROUP(object)->effectiveLayerMode(this->dkey) - == SPGroup::LAYER ) ); +bool SPDesktop::isLayer(SPObject *object) const +{ + return layer_model->isLayer(object); } /** @@ -1575,15 +1491,7 @@ SPDesktop::setDocument (SPDocument *doc) this->doc()->getRoot()->invoke_hide(dkey); } - if (_layer_hierarchy) { - _layer_hierarchy->clear(); - delete _layer_hierarchy; - } - _layer_hierarchy = new Inkscape::ObjectHierarchy(NULL); - _layer_hierarchy->connectAdded(sigc::bind(sigc::ptr_fun(_layer_activated), this)); - _layer_hierarchy->connectRemoved(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); - _layer_hierarchy->connectChanged(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); - _layer_hierarchy->setTop(doc->getRoot()); + layer_model->setDocument(doc); // remove old EventLog if it exists (see also: bug #1071082) if (event_log) { @@ -1691,9 +1599,9 @@ _onSelectionChanged */ SPItem *item=selection->singleItem(); if (item) { - SPObject *layer=desktop->layerForObject(item); + SPObject *layer=desktop->layer_model->layerForObject(item); if ( layer && layer != desktop->currentLayer() ) { - desktop->setCurrentLayer(layer); + desktop->layer_model->setCurrentLayer(layer); } } } @@ -1740,7 +1648,7 @@ static void _reconstruction_start(SPDesktop * desktop) { // printf("Desktop, starting reconstruction\n"); desktop->_reconstruction_old_layer_id = desktop->currentLayer()->getId() ? desktop->currentLayer()->getId() : ""; - desktop->_layer_hierarchy->setBottom(desktop->currentRoot()); + desktop->layer_model->reset(); /* GSList const * selection_objs = desktop->selection->list(); @@ -1760,7 +1668,7 @@ static void _reconstruction_finish(SPDesktop * desktop) if ( !desktop->_reconstruction_old_layer_id.empty() ) { SPObject * newLayer = desktop->namedview->document->getObjectById(desktop->_reconstruction_old_layer_id); if (newLayer != NULL) { - desktop->setCurrentLayer(newLayer); + desktop->layer_model->setCurrentLayer(newLayer); } desktop->_reconstruction_old_layer_id.clear(); @@ -1931,7 +1839,7 @@ SPDesktop::show_dialogs() if (visible) { Inkscape::Verb *verb = Inkscape::Verb::get(verbId); if (verb) { - SPAction *action = verb->get_action(this); + SPAction *action = verb->get_action(Inkscape::ActionContext(this)); if (action) { sp_action_perform(action, NULL); } diff --git a/src/desktop.h b/src/desktop.h index 56de56c65..661470ded 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -62,9 +62,9 @@ typedef struct _GdkEventWindowState GdkEventWindowState; namespace Inkscape { struct Application; + class LayerModel; class MessageContext; class Selection; - class ObjectHierarchy; class LayerManager; class EventLog; namespace UI { @@ -125,6 +125,7 @@ public: Inkscape::UI::Dialog::DialogManager *_dlg_mgr; SPNamedView *namedview; SPCanvas *canvas; + Inkscape::LayerModel *layer_model; /// current selection; will never generally be NULL Inkscape::Selection *selection; SPEventContext *event_context; @@ -170,8 +171,6 @@ public: guint gr_point_i; Inkscape::PaintTarget gr_fill_or_stroke; - - Inkscape::ObjectHierarchy *_layer_hierarchy; Glib::ustring _reconstruction_old_layer_id; sigc::signal _tool_changed; @@ -264,17 +263,16 @@ public: void set_active (bool new_active); - // TODO look into making these return a more specific subclass: + // Could make all callers use layer_model instead of passing calls through? SPObject *currentRoot() const; SPObject *currentLayer() const; - void setCurrentLayer(SPObject *object); void toggleLayerSolo(SPObject *object); void toggleHideAllLayers(bool hide); void toggleLockAllLayers(bool lock); void toggleLockOtherLayers(SPObject *object); - SPObject *layerForObject(SPObject *object); bool isLayer(SPObject *object) const; + bool isWithinViewport(SPItem *item) const; bool itemIsHidden(SPItem const *item) const; diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index 605e487ab..c37f9cb4b 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -999,10 +999,10 @@ set_to_accumulated(SPDynaDrawContext *dc, bool unionize, bool subtract) if (unionize) { sp_desktop_selection(desktop)->add(dc->repr); - sp_selected_path_union_skip_undo(desktop); + sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); } else if (subtract) { sp_desktop_selection(desktop)->add(dc->repr); - sp_selected_path_diff_skip_undo(desktop); + sp_selected_path_diff_skip_undo(sp_desktop_selection(desktop), desktop); } else { if (dc->keep_selected) { sp_desktop_selection(desktop)->set(dc->repr); diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp index b34e3352c..a337f941b 100644 --- a/src/eraser-context.cpp +++ b/src/eraser-context.cpp @@ -751,7 +751,7 @@ set_to_accumulated(SPEraserContext *dc) selection->set(item); selection->add(dup); - sp_selected_path_diff_skip_undo(desktop); + sp_selected_path_diff_skip_undo(selection, desktop); workDone = true; // TODO set this only if something was cut. if ( !selection->isEmpty() ) { // If the item was not completely erased, track the new remainder. diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index 56d1dfdbd..bdf1fa98c 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -30,6 +30,7 @@ #include "extension/system.h" //IO #include "file.h" //IO #include "helper/action.h" //sp_action_perform +#include "helper/action-context.h" #include "inkscape.h" //inkscape_find_desktop_by_dkey, activate desktops #include "layer-fns.h" //LPOS_BELOW #include "live_effects/parameter/text.h" //text @@ -263,7 +264,7 @@ dbus_call_verb (DocumentInterface *object, int verbid, GError **error) if ( desk2 ) { Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); if ( verb ) { - SPAction *action = verb->get_action(desk2); + SPAction *action = verb->get_action(Inkscape::ActionContext(desk2)); if ( action ) { //if (!object->updates) //document_interface_pause_updates (object, error); @@ -342,7 +343,7 @@ document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError * if ( desk2 ) { Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid ); if ( verb ) { - SPAction *action = verb->get_action(desk2); + SPAction *action = verb->get_action(Inkscape::ActionContext(desk2)); if ( action ) { sp_action_perform( action, NULL ); if (object->updates) { diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 1df8002ad..22c5e4989 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -359,9 +359,9 @@ Effect::set_pref_dialog (PrefDialog * prefdialog) } SPAction * -Effect::EffectVerb::make_action (Inkscape::UI::View::View * view) +Effect::EffectVerb::make_action (Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform, static_cast(this)); + return make_action_helper(context, &perform, static_cast(this)); } /** \brief Decode the verb code and take appropriate action */ diff --git a/src/extension/effect.h b/src/extension/effect.h index 193b90a97..a14cc6e7d 100644 --- a/src/extension/effect.h +++ b/src/extension/effect.h @@ -58,7 +58,7 @@ class Effect : public Extension { /** \brief Name with elipses if that makes sense */ gchar * _elip_name; protected: - virtual SPAction * make_action (Inkscape::UI::View::View * view); + virtual SPAction * make_action (Inkscape::ActionContext const & context); public: /** \brief Use the Verb initializer with the same parameters. */ EffectVerb(gchar const * id, diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index 8f1e07211..a3d2fd6e5 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -17,6 +17,7 @@ #include "document.h" #include "selection.h" #include "helper/action.h" +#include "helper/action-context.h" #include "preferences.h" #include "path-chemistry.h" #include "sp-item.h" @@ -99,10 +100,10 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View /* Doing an inset here folks */ offset *= -1.0; prefs->setDoubleUnit("/options/defaultoffsetwidth/value", offset, "px"); - sp_action_perform(Inkscape::Verb::get(SP_VERB_SELECTION_INSET)->get_action(desktop), NULL); + sp_action_perform(Inkscape::Verb::get(SP_VERB_SELECTION_INSET)->get_action(Inkscape::ActionContext(desktop)), NULL); } else if (offset > 0.0) { prefs->setDoubleUnit("/options/defaultoffsetwidth/value", offset, "px"); - sp_action_perform(Inkscape::Verb::get(SP_VERB_SELECTION_OFFSET)->get_action(desktop), NULL); + sp_action_perform(Inkscape::Verb::get(SP_VERB_SELECTION_OFFSET)->get_action(Inkscape::ActionContext(desktop)), NULL); } selection->clear(); diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp old mode 100755 new mode 100644 diff --git a/src/flood-context.cpp b/src/flood-context.cpp index bb6864f7e..8fde11f88 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -511,7 +511,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto ngettext("Area filled, path with %d node created and unioned with selection.","Area filled, path with %d nodes created and unioned with selection.", SP_PATH(reprobj)->nodesInPath()), SP_PATH(reprobj)->nodesInPath() ); selection->add(reprobj); - sp_selected_path_union_skip_undo(desktop); + sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); } else { desktop->messageStack()->flashF( Inkscape::WARNING_MESSAGE, ngettext("Area filled, path with %d node created.","Area filled, path with %d nodes created.", diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt index f709c7386..2e1e724f5 100644 --- a/src/helper/CMakeLists.txt +++ b/src/helper/CMakeLists.txt @@ -10,6 +10,7 @@ set(sp_marshal_SRC set(helper_SRC action.cpp + action-context.cpp geom.cpp geom-nodetype.cpp gnome-utils.cpp @@ -29,6 +30,7 @@ set(helper_SRC # ------- # Headers action.h + action-context.h geom-curves.h geom-nodetype.h geom.h diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert index 2be40e0e0..790d87b14 100644 --- a/src/helper/Makefile_insert +++ b/src/helper/Makefile_insert @@ -5,6 +5,8 @@ helper/unit-menu.$(OBJEXT): helper/sp-marshal.h ink_common_sources += \ helper/action.cpp \ helper/action.h \ + helper/action-context.cpp \ + helper/action-context.h \ helper/geom.cpp \ helper/geom.h \ helper/geom-curves.h \ diff --git a/src/helper/action.cpp b/src/helper/action.cpp index 0e9957ca3..107d0179b 100644 --- a/src/helper/action.cpp +++ b/src/helper/action.cpp @@ -41,7 +41,7 @@ sp_action_init (SPAction *action) { action->sensitive = 0; action->active = 0; - action->view = NULL; + action->context = Inkscape::ActionContext(); action->id = action->name = action->tip = NULL; action->image = NULL; @@ -76,7 +76,7 @@ sp_action_finalize (GObject *object) * Create new SPAction object and set its properties. */ SPAction * -sp_action_new(Inkscape::UI::View::View *view, +sp_action_new(Inkscape::ActionContext const &context, const gchar *id, const gchar *name, const gchar *tip, @@ -85,7 +85,7 @@ sp_action_new(Inkscape::UI::View::View *view, { SPAction *action = (SPAction *)g_object_new(SP_TYPE_ACTION, NULL); - action->view = view; + action->context = context; action->sensitive = TRUE; action->id = g_strdup (id); action->name = g_strdup (name); @@ -111,11 +111,9 @@ public: : ActionEventBase(share_static_string("action")) { _addProperty(share_static_string("timestamp"), timestamp()); - if (action->view) { - SPDocument *document = action->view->doc(); - if (document) { - _addProperty(share_static_string("document"), document->serial()); - } + SPDocument *document = action->context.getDocument(); + if (document) { + _addProperty(share_static_string("document"), document->serial()); } _addProperty(share_static_string("verb"), action->id); } @@ -169,6 +167,26 @@ sp_action_set_name (SPAction *action, Glib::ustring const &name) action->signal_set_name.emit(name); } +/** + * Return Document associated with the action. + */ +SPDocument * +sp_action_get_document (SPAction *action) +{ + g_return_val_if_fail (SP_IS_ACTION (action), NULL); + return action->context.getDocument(); +} + +/** + * Return Selection associated with the action + */ +Inkscape::Selection * +sp_action_get_selection (SPAction *action) +{ + g_return_val_if_fail (SP_IS_ACTION (action), NULL); + return action->context.getSelection(); +} + /** * Return View associated with the action. */ @@ -176,7 +194,7 @@ Inkscape::UI::View::View * sp_action_get_view (SPAction *action) { g_return_val_if_fail (SP_IS_ACTION (action), NULL); - return action->view; + return action->context.getView(); } /* diff --git a/src/helper/action.h b/src/helper/action.h index 0cd010b34..49816e3c9 100644 --- a/src/helper/action.h +++ b/src/helper/action.h @@ -12,6 +12,7 @@ #ifndef SEEN_INKSCAPE_SP_ACTION_H #define SEEN_INKSCAPE_SP_ACTION_H +#include "helper/action-context.h" #include #include #include @@ -24,8 +25,12 @@ struct SPActionClass; #define SP_ACTION_CLASS(o) (G_TYPE_CHECK_CLASS_CAST((o), SP_TYPE_ACTION, SPActionClass)) #define SP_IS_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_ACTION)) +class SPDocument; namespace Inkscape { + +class Selection; class Verb; + namespace UI { namespace View { class View; @@ -39,7 +44,7 @@ class View; struct SPAction : public GObject { unsigned sensitive : 1; /**< Value to track whether the action is sensitive */ unsigned active : 1; /**< Value to track whether the action is active */ - Inkscape::UI::View::View *view; /**< The View to which this action is attached */ + Inkscape::ActionContext context; /**< The context (doc/view) to which this action is attached */ gchar *id; /**< The identifier for the action */ gchar *name; /**< Full text name of the action */ gchar *tip; /**< A tooltip to describe the action */ @@ -59,7 +64,7 @@ struct SPActionClass { GType sp_action_get_type(); -SPAction *sp_action_new(Inkscape::UI::View::View *view, +SPAction *sp_action_new(Inkscape::ActionContext const &context, gchar const *id, gchar const *name, gchar const *tip, @@ -70,6 +75,8 @@ void sp_action_perform(SPAction *action, void *data); void sp_action_set_active(SPAction *action, unsigned active); void sp_action_set_sensitive(SPAction *action, unsigned sensitive); void sp_action_set_name(SPAction *action, Glib::ustring const &name); +SPDocument *sp_action_get_document(SPAction *action); +Inkscape::Selection *sp_action_get_selection(SPAction *action); Inkscape::UI::View::View *sp_action_get_view(SPAction *action); #endif diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 7e570deb7..125a7176a 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -87,7 +87,7 @@ enum { LAST_SIGNAL }; -#define DESKTOP_IS_ACTIVE(d) ((d) == inkscape->desktops->data) +#define DESKTOP_IS_ACTIVE(d) (inkscape->desktops && ((d) == inkscape->desktops->data)) /*################################ diff --git a/src/interface.cpp b/src/interface.cpp index 986d3107f..e3036afdd 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -53,6 +53,7 @@ #include "sp-namedview.h" #include "ui/view/view.h" #include "helper/action.h" +#include "helper/action-context.h" #include "helper/gnome-utils.h" #include "helper/window.h" #include "io/sys.h" @@ -370,13 +371,13 @@ sp_ui_menu_activate(void */*object*/, SPAction *action) static void sp_ui_menu_select_action(void */*object*/, SPAction *action) { - action->view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); + sp_action_get_view(action)->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); } static void sp_ui_menu_deselect_action(void */*object*/, SPAction *action) { - action->view->tipsMessageContext()->clear(); + sp_action_get_view(action)->tipsMessageContext()->clear(); } static void @@ -419,7 +420,7 @@ sp_ui_dialog_title_string(Inkscape::Verb *verb, gchar *c) gchar *s; gchar *atitle; - action = verb->get_action(NULL); + action = verb->get_action(Inkscape::ActionContext()); if (!action) return; @@ -456,7 +457,7 @@ static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb } else { - action = verb->get_action(view); + action = verb->get_action(Inkscape::ActionContext(view)); if (!action) return NULL; if (radio) { @@ -670,7 +671,7 @@ sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View * Inkscape::Verb *verb) { unsigned int shortcut = (verb) ? sp_shortcut_get_primary(verb) : 0; - SPAction *action = (verb) ? verb->get_action(view) : 0; + SPAction *action = (verb) ? verb->get_action(Inkscape::ActionContext(view)) : 0; GtkWidget *item = gtk_check_menu_item_new_with_mnemonic(action ? action->name : label); #if 0 @@ -955,7 +956,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); } if (verb->get_code() != SP_VERB_NONE) { - SPAction *action = verb->get_action(view); + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect( G_OBJECT(item), "draw", (GCallback) update_view_menu, (void *) action); #else @@ -965,7 +966,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I } else if (menu_pntr->attribute("check") != NULL) { SPAction *action = NULL; if (verb->get_code() != SP_VERB_NONE) { - action = verb->get_action(view); + action = verb->get_action(Inkscape::ActionContext(view)); } sp_ui_menu_append_check_item_from_verb(GTK_MENU(menu), view, action->name, action->tip, NULL, checkitem_toggled, checkitem_update, verb); @@ -1671,7 +1672,7 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)// item->show(); append(*item); } else { - action = verb->get_action(view); + action = verb->get_action(Inkscape::ActionContext(view)); if (!action) { return; } @@ -2035,7 +2036,7 @@ void ContextMenu::AnchorLinkFollow(void) // Opening the selected links with a python extension Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.inkscape.followlink" ); if (verb) { - SPAction *action = verb->get_action(_desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); if (action) { sp_action_perform(action, NULL); } @@ -2205,7 +2206,7 @@ void ContextMenu::ImageEmbed(void) Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); if (verb) { - SPAction *action = verb->get_action(_desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); if (action) { sp_action_perform(action, NULL); } @@ -2220,7 +2221,7 @@ void ContextMenu::ImageExtract(void) Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); if (verb) { - SPAction *action = verb->get_action(_desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); if (action) { sp_action_perform(action, NULL); } diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp index 9f700292e..6af616e34 100644 --- a/src/main-cmdlineact.cpp +++ b/src/main-cmdlineact.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ CmdLineAction::~CmdLineAction () { } void -CmdLineAction::doIt (Inkscape::UI::View::View * view) { +CmdLineAction::doIt (ActionContext const & context) { //printf("Doing: %s\n", _arg); if (_isVerb) { Inkscape::Verb * verb = Inkscape::Verb::getbyid(_arg); @@ -49,32 +50,33 @@ CmdLineAction::doIt (Inkscape::UI::View::View * view) { printf(_("Unable to find verb ID '%s' specified on the command line.\n"), _arg); return; } - SPAction * action = verb->get_action(view); + SPAction * action = verb->get_action(context); sp_action_perform(action, NULL); } else { - SPDesktop * desktop = dynamic_cast(view); - if (desktop == NULL) { return; } + if (context.getDocument() == NULL || context.getSelection() == NULL) { return; } - SPDocument * doc = view->doc(); + SPDocument * doc = context.getDocument(); SPObject * obj = doc->getObjectById(_arg); if (obj == NULL) { printf(_("Unable to find node ID: '%s'\n"), _arg); return; } - Inkscape::Selection * selection = sp_desktop_selection(desktop); + Inkscape::Selection * selection = context.getSelection(); selection->add(obj, false); } return; } -void -CmdLineAction::doList (Inkscape::UI::View::View * view) { +bool +CmdLineAction::doList (ActionContext const & context) { + bool hasActions = !_list.empty(); for (std::list::iterator i = _list.begin(); i != _list.end(); ++i) { CmdLineAction * entry = *i; - entry->doIt(view); + entry->doIt(context); } + return hasActions; } bool @@ -87,8 +89,8 @@ CmdLineAction::idle (void) { for (std::list::iterator i = desktops.begin(); i != desktops.end(); ++i) { SPDesktop * desktop = *i; - //Inkscape::UI::View::View * view = dynamic_cast(desktop); - doList(desktop); + //Inkscape::UI::View::View * view = dynamic_cast(desktop); + doList(ActionContext(desktop)); } return false; } diff --git a/src/main-cmdlineact.h b/src/main-cmdlineact.h index 03f0eb0fc..fe11357fa 100644 --- a/src/main-cmdlineact.h +++ b/src/main-cmdlineact.h @@ -19,6 +19,8 @@ namespace Inkscape { +class ActionContext; + class CmdLineAction { bool _isVerb; gchar * _arg; @@ -29,8 +31,9 @@ public: CmdLineAction (bool isVerb, gchar const * arg); virtual ~CmdLineAction (); - void doIt (Inkscape::UI::View::View * view); - static void doList (Inkscape::UI::View::View * view); + void doIt (ActionContext const & context); + /** Return true if any actions were performed */ + static bool doList (ActionContext const & context); static bool idle (void); }; diff --git a/src/main.cpp b/src/main.cpp index 19ea3f181..49ef33fc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,6 +60,8 @@ #include "macros.h" #include "file.h" #include "document.h" +#include "layer-model.h" +#include "selection.h" #include "sp-object.h" #include "interface.h" #include "print.h" @@ -85,6 +87,7 @@ #include "debug/logger.h" #include "debug/log-display-config.h" +#include "helper/action-context.h" #include "helper/png-write.h" #include "helper/geom.h" @@ -1066,7 +1069,20 @@ static int sp_process_file_list(GSList *fl) if (sp_vacuum_defs) { doc->vacuumDocument(); } - if (sp_vacuum_defs && !sp_export_svg) { + + bool has_performed_actions = false; + { + // Create layer model and selection model so we can run some verbs without a GUI + Inkscape::LayerModel layer_model; + layer_model.setDocument(doc); + Inkscape::Selection *selection = Inkscape::GC::release(new Inkscape::Selection(&layer_model, NULL)); + + // Execute command-line actions (selections and verbs) using our local models + Inkscape::ActionContext context(selection); + has_performed_actions = Inkscape::CmdLineAction::doList(context); + } + + if (!sp_export_svg && (sp_vacuum_defs || has_performed_actions)) { // save under the name given in the command line sp_repr_save_file(doc->rdoc, filename, SP_SVG_NS_URI); } diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 72467c187..ce2d1c90b 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -17,6 +17,7 @@ #include #include "xml/quote.h" +#include "layer-model.h" #include "selection.h" #include "selection-describer.h" #include "desktop.h" @@ -144,8 +145,8 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select _context.set(Inkscape::NORMAL_MESSAGE, _when_nothing); } else { SPItem *item = SP_ITEM(items->data); - SPObject *layer = selection->desktop()->layerForObject(item); - SPObject *root = selection->desktop()->currentRoot(); + SPObject *layer = selection->layerModel()->layerForObject(item); + SPObject *root = selection->layerModel()->currentRoot(); // Layer name gchar *layer_name; diff --git a/src/selection.cpp b/src/selection.cpp index 564f1fdd3..76f49f544 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -21,9 +21,8 @@ #endif #include "macros.h" #include "inkscape-private.h" -#include "desktop.h" -#include "desktop-handles.h" #include "document.h" +#include "layer-model.h" #include "selection.h" #include <2geom/rect.h> #include "xml/repr.h" @@ -42,10 +41,11 @@ namespace Inkscape { -Selection::Selection(SPDesktop *desktop) : +Selection::Selection(LayerModel *layer_model, SPDesktop *desktop) : _objs(NULL), _reprs(NULL), _items(NULL), + _layer_model(layer_model), _desktop(desktop), _selection_context(NULL), _flags(0), @@ -55,7 +55,7 @@ Selection::Selection(SPDesktop *desktop) : Selection::~Selection() { _clear(); - _desktop = NULL; + _layer_model = NULL; if (_idle) { g_source_remove(_idle); _idle = 0; @@ -96,7 +96,7 @@ void Selection::_emitModified(guint flags) { void Selection::_emitChanged(bool persist_selection_context/* = false */) { if (persist_selection_context) { if (NULL == _selection_context) { - _selection_context = desktop()->currentLayer(); + _selection_context = _layer_model->currentLayer(); sp_object_ref(_selection_context, NULL); _context_release_connection = _selection_context->connectRelease(sigc::mem_fun(*this, &Selection::_releaseContext)); } @@ -139,7 +139,7 @@ void Selection::_clear() { SPObject *Selection::activeContext() { if (NULL != _selection_context) return _selection_context; - return desktop()->currentLayer(); + return _layer_model->currentLayer(); } bool Selection::includes(SPObject *obj) const { @@ -487,7 +487,7 @@ SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { g_return_val_if_fail(repr != NULL, NULL); gchar const *id = repr->attribute("id"); g_return_val_if_fail(id != NULL, NULL); - SPObject *object=sp_desktop_document(_desktop)->getObjectById(id); + SPObject *object=_layer_model->getDocument()->getObjectById(id); g_return_val_if_fail(object != NULL, NULL); return object; } @@ -496,7 +496,7 @@ guint Selection::numberOfLayers() { GSList const *items = const_cast(this)->itemList(); GSList *layers = NULL; for (GSList const *iter = items; iter != NULL; iter = iter->next) { - SPObject *layer = desktop()->layerForObject(SP_OBJECT(iter->data)); + SPObject *layer = _layer_model->layerForObject(SP_OBJECT(iter->data)); if (g_slist_find (layers, layer) == NULL) { layers = g_slist_prepend (layers, layer); } diff --git a/src/selection.h b/src/selection.h index 10775dcb5..65a6c5140 100644 --- a/src/selection.h +++ b/src/selection.h @@ -33,6 +33,7 @@ class SPBox3D; struct Persp3D; namespace Inkscape { +class LayerModel; namespace XML { class Node; } @@ -41,10 +42,10 @@ class Node; namespace Inkscape { /** - * The set of selected SPObjects for a given desktop. + * The set of selected SPObjects for a given document and layer model. * * This class represents the set of selected SPItems for a given - * SPDesktop. + * document (referenced in LayerModel). * * An SPObject and its parent cannot be simultaneously selected; * selecting an SPObjects has the side-effect of unselecting any of @@ -64,17 +65,26 @@ class Selection : public Inkscape::GC::Managed<>, public: /** * Constructs an selection object, bound to a particular - * SPDesktop + * layer model * - * @param desktop the desktop in question + * @param layer_model the layer model (for the SPDesktop, if GUI) + * @param desktop the desktop associated with the layer model, or NULL if in console mode */ - Selection(SPDesktop *desktop); + Selection(LayerModel *layer_model, SPDesktop *desktop); ~Selection(); + /** + * Returns the layer model the selection is bound to (works in console or GUI mode) + * + * @return the layer model the selection is bound to, which is the same as the desktop + * layer model for GUI mode + */ + LayerModel *layerModel() { return _layer_model; } + /** * Returns the desktop the selection is bound to * - * @return the desktop the selection is bound to + * @return the desktop the selection is bound to, or NULL if in console mode */ SPDesktop *desktop() { return _desktop; } @@ -342,6 +352,7 @@ private: std::list _3dboxes; + LayerModel *_layer_model; GC::soft_ptr _desktop; SPObject* _selection_context; guint _flags; diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index 2af04929e..231e33e4a 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -35,6 +35,7 @@ #include #include "helper/action.h" +#include "helper/action-context.h" #include "io/sys.h" #include "io/resource.h" #include "verbs.h" @@ -68,7 +69,7 @@ sp_shortcut_invoke(unsigned int shortcut, Inkscape::UI::View::View *view) { Inkscape::Verb *verb = sp_shortcut_get_verb(shortcut); if (verb) { - SPAction *action = verb->get_action(view); + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); if (action) { sp_action_perform(action, NULL); return true; diff --git a/src/splivarot.cpp b/src/splivarot.cpp index e45712134..0ec9da2a7 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -34,6 +34,7 @@ #include "style.h" #include "document.h" #include "document-undo.h" +#include "layer-model.h" #include "message-stack.h" #include "selection.h" #include "desktop-handles.h" @@ -58,79 +59,89 @@ using Inkscape::DocumentUndo; bool Ancetre(Inkscape::XML::Node *a, Inkscape::XML::Node *who); -void sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb=SP_VERB_NONE, const Glib::ustring description=""); +void sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb=SP_VERB_NONE, const Glib::ustring description=""); void sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset); void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating); void -sp_selected_path_union(SPDesktop *desktop) +sp_selected_path_union(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_union, SP_VERB_SELECTION_UNION, _("Union")); + sp_selected_path_boolop(selection, desktop, bool_op_union, SP_VERB_SELECTION_UNION, _("Union")); } void -sp_selected_path_union_skip_undo(SPDesktop *desktop) +sp_selected_path_union_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_union, SP_VERB_NONE, _("Union")); + sp_selected_path_boolop(selection, desktop, bool_op_union, SP_VERB_NONE, _("Union")); } void -sp_selected_path_intersect(SPDesktop *desktop) +sp_selected_path_intersect(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection")); + sp_selected_path_boolop(selection, desktop, bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection")); } void -sp_selected_path_diff(SPDesktop *desktop) +sp_selected_path_diff(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference")); + sp_selected_path_boolop(selection, desktop, bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference")); } void -sp_selected_path_diff_skip_undo(SPDesktop *desktop) +sp_selected_path_diff_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_diff, SP_VERB_NONE, _("Difference")); + sp_selected_path_boolop(selection, desktop, bool_op_diff, SP_VERB_NONE, _("Difference")); } void -sp_selected_path_symdiff(SPDesktop *desktop) +sp_selected_path_symdiff(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion")); + sp_selected_path_boolop(selection, desktop, bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion")); } void -sp_selected_path_cut(SPDesktop *desktop) +sp_selected_path_cut(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division")); + sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division")); } void -sp_selected_path_slice(SPDesktop *desktop) +sp_selected_path_slice(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(desktop, bool_op_slice, SP_VERB_SELECTION_SLICE, _("Cut path")); + sp_selected_path_boolop(selection, desktop, bool_op_slice, SP_VERB_SELECTION_SLICE, _("Cut path")); } +// helper for printing error messages, regardless of whether we have a GUI or not +// If desktop == NULL, errors will be shown on stderr +static void +boolop_display_error_message(SPDesktop *desktop, Glib::ustring const &msg) +{ + if (desktop) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, msg); + } else { + g_printerr("%s\n", msg.c_str()); + } +} // boolean operations // take the source paths from the file, do the operation, delete the originals and add the results void -sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description) +sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - + SPDocument *doc = selection->layerModel()->getDocument(); GSList *il = (GSList *) selection->itemList(); // allow union on a single object for the purpose of removing self overlapse (svn log, revision 13334) if ( (g_slist_length(il) < 2) && (bop != bool_op_union)) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Select at least 2 paths to perform a boolean operation.")); + boolop_display_error_message(desktop, _("Select at least 2 paths to perform a boolean operation.")); return; } else if ( g_slist_length(il) < 1 ) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Select at least 1 path to perform a boolean union.")); + boolop_display_error_message(desktop, _("Select at least 1 path to perform a boolean union.")); return; } if (g_slist_length(il) > 2) { if (bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice ) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Select exactly 2 paths to perform difference, division, or path cut.")); + boolop_display_error_message(desktop, _("Select exactly 2 paths to perform difference, division, or path cut.")); return; } } @@ -146,7 +157,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb Inkscape::XML::Node *b = reinterpret_cast(il->next->data)->getRepr(); if (a == NULL || b == NULL) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Unable to determine the z-order of the objects selected for difference, XOR, division, or path cut.")); + boolop_display_error_message(desktop, _("Unable to determine the z-order of the objects selected for difference, XOR, division, or path cut.")); return; } @@ -161,7 +172,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb // find their lowest common ancestor Inkscape::XML::Node *dad = LCA(a, b); if (dad == NULL) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Unable to determine the z-order of the objects selected for difference, XOR, division, or path cut.")); + boolop_display_error_message(desktop, _("Unable to determine the z-order of the objects selected for difference, XOR, division, or path cut.")); return; } @@ -191,7 +202,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb SPItem *item = SP_ITEM(l->data); if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item) && !SP_IS_FLOWTEXT(item)) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("One of the objects is not a path, cannot perform boolean operation.")); + boolop_display_error_message(desktop, _("One of the objects is not a path, cannot perform boolean operation.")); g_slist_free(il); return; } @@ -432,8 +443,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb { SP_OBJECT(l->data)->deleteObject(); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, - description); + DocumentUndo::done(doc, SP_VERB_NONE, description); selection->clear(); delete res; @@ -455,8 +465,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb sorted = g_slist_sort(sorted, (GCompareFunc) sp_repr_compare_position); - source = sp_desktop_document(desktop)-> - getObjectByRepr((Inkscape::XML::Node *)sorted->data); + source = doc->getObjectByRepr((Inkscape::XML::Node *)sorted->data); g_slist_free(sorted); } @@ -496,7 +505,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb g_slist_free(il); // premultiply by the inverse of parent's repr - SPItem *parent_item = SP_ITEM(sp_desktop_document(desktop)->getObjectByRepr(parent)); + SPItem *parent_item = SP_ITEM(doc->getObjectByRepr(parent)); Geom::Affine local (parent_item->i2doc_affine()); gchar *transform = sp_svg_transform_write(local.inverse()); @@ -526,7 +535,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb for (int i=0;isvg_dump_path(); - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); repr->setAttribute("style", style); if (mask) @@ -572,7 +581,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb } else { gchar *d = res->svg_dump_path(); - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); repr->setAttribute("style", style); @@ -590,10 +599,10 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb repr->setAttribute("id", id); parent->appendChild(repr); if (title) { - sp_desktop_document(desktop)->getObjectByRepr(repr)->setTitle(title); + doc->getObjectByRepr(repr)->setTitle(title); } if (desc) { - sp_desktop_document(desktop)->getObjectByRepr(repr)->setDesc(desc); + doc->getObjectByRepr(repr)->setDesc(desc); } repr->setPosition(pos > 0 ? pos : 0); @@ -606,7 +615,7 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb if (desc) g_free(desc); if (verb != SP_VERB_NONE) { - DocumentUndo::done(sp_desktop_document(desktop), verb, description); + DocumentUndo::done(doc, verb, description); } delete res; diff --git a/src/splivarot.h b/src/splivarot.h index 3d2a1ee58..0cefed3c2 100644 --- a/src/splivarot.h +++ b/src/splivarot.h @@ -11,19 +11,28 @@ #include <2geom/forward.h> #include <2geom/path.h> class SPCurve; +class SPDesktop; class SPItem; +namespace Inkscape { + class Selection; +} + // boolean operations // work on the current selection // selection has 2 contain exactly 2 items -void sp_selected_path_union (SPDesktop *desktop); -void sp_selected_path_union_skip_undo (SPDesktop *desktop); -void sp_selected_path_intersect (SPDesktop *desktop); -void sp_selected_path_diff (SPDesktop *desktop); -void sp_selected_path_diff_skip_undo (SPDesktop *desktop); -void sp_selected_path_symdiff (SPDesktop *desktop); -void sp_selected_path_cut (SPDesktop *desktop); -void sp_selected_path_slice (SPDesktop *desktop); + +// UPDATE: these signatures have been modified so they may work in +// command-line mode, i.e. without a desktop. If a desktop is not +// provided (desktop == NULL), error messages will be shown on stderr. +void sp_selected_path_union (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_union_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_intersect (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_diff (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_diff_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_symdiff (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_cut (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_slice (Inkscape::Selection *selection, SPDesktop *desktop); // offset/inset of a curve // takes the fill-rule in consideration diff --git a/src/spray-context.cpp b/src/spray-context.cpp index b8172fa4c..7690d0373 100644 --- a/src/spray-context.cpp +++ b/src/spray-context.cpp @@ -505,7 +505,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, selection->clear(); selection->add(item_copied); selection->add(unionResult); - sp_selected_path_union_skip_undo(selection->desktop()); + sp_selected_path_union_skip_undo(selection, selection->desktop()); selection->add(father); Inkscape::GC::release(copy2); did = true; diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index 5cc9578f1..32d85574d 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -27,6 +27,7 @@ #include "document.h" #include "document-undo.h" #include "helper/action.h" +#include "helper/action-context.h" #include "inkscape.h" #include "layer-fns.h" #include "layer-manager.h" @@ -99,7 +100,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i if ( desktop ) { Verb *verb = Verb::get( code ); if ( verb ) { - SPAction *action = verb->get_action(desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(desktop)); if ( !set && action && action->image ) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); gtk_widget_show( child ); @@ -131,7 +132,7 @@ Gtk::MenuItem& LayersPanel::_addPopupItem( SPDesktop *desktop, unsigned int code if ( desktop ) { Verb *verb = Verb::get( code ); if ( verb ) { - SPAction *action = verb->get_action(desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(desktop)); if ( !iconWidget && action && action->image ) { iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); } @@ -172,7 +173,7 @@ void LayersPanel::_fireAction( unsigned int code ) if ( _desktop ) { Verb *verb = Verb::get( code ); if ( verb ) { - SPAction *action = verb->get_action(_desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); if ( action ) { sp_action_perform( action, NULL ); // } else { diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 90cb1cdc9..094a6fa6a 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -57,6 +57,7 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" +#include "helper/action-context.h" namespace Inkscape { namespace UI { @@ -154,7 +155,7 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) // Invoke the gradient tool Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); if ( verb ) { - SPAction *action = verb->get_action( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP); + SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); if ( action ) { sp_action_perform( action, NULL ); } diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 5eb7084d6..09bf1a863 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -66,6 +66,7 @@ #include "verbs.h" #include "helper/action.h" +#include "helper/action-context.h" #include "xml/repr.h" namespace Inkscape { @@ -328,13 +329,13 @@ void SymbolsDialog::rebuild() { void SymbolsDialog::insertSymbol() { Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_SYMBOL ); - SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->currentDesktop); + SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) this->currentDesktop) ); sp_action_perform (action, NULL); } void SymbolsDialog::revertSymbol() { Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_UNSYMBOL ); - SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->currentDesktop); + SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) this->currentDesktop ) ); sp_action_perform (action, NULL); } diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index fa3f8e3a1..988c4e5de 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -36,6 +36,7 @@ #include "document.h" #include "desktop.h" #include "helper/action.h" +#include "helper/action-context.h" #include "helper/units.h" #include "inkscape.h" #include "sp-namedview.h" @@ -619,7 +620,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing() Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING ); if (verb) { - SPAction *action = verb->get_action(dt); + SPAction *action = verb->get_action(Inkscape::ActionContext(dt)); if (action) { sp_action_perform(action, NULL); } diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index a89f42575..aedab3fa5 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -28,6 +28,7 @@ #include "widgets/widget-sizes.h" #include "helper/units.h" #include "helper/action.h" +#include "helper/action-context.h" #include "preferences.h" #include "inkscape.h" #include "verbs.h" @@ -200,7 +201,7 @@ StyleSwatch::on_click(GdkEventButton */*event*/) { if (this->_desktop && this->_verb_t != SP_VERB_NONE) { Inkscape::Verb *verb = Inkscape::Verb::get(this->_verb_t); - SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->_desktop); + SPAction *action = verb->get_action(Inkscape::ActionContext((Inkscape::UI::View::View *) this->_desktop)); sp_action_perform (action, NULL); return true; } diff --git a/src/verbs.cpp b/src/verbs.cpp index 6f83b3dfb..4bbd3f9df 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -50,6 +50,7 @@ #include "file.h" #include "gradient-drag.h" #include "helper/action.h" +#include "helper/action-context.h" #include "help.h" #include "inkscape-private.h" #include "interface.h" @@ -124,7 +125,7 @@ class FileVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ FileVerb(unsigned int const code, @@ -143,7 +144,7 @@ class EditVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ EditVerb(unsigned int const code, @@ -162,7 +163,7 @@ class SelectionVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ SelectionVerb(unsigned int const code, @@ -181,7 +182,7 @@ class LayerVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ LayerVerb(unsigned int const code, @@ -200,7 +201,7 @@ class ObjectVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ ObjectVerb(unsigned int const code, @@ -219,7 +220,7 @@ class ContextVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ ContextVerb(unsigned int const code, @@ -238,7 +239,7 @@ class ZoomVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ ZoomVerb(unsigned int const code, @@ -258,7 +259,7 @@ class DialogVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ DialogVerb(unsigned int const code, @@ -277,7 +278,7 @@ class HelpVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ HelpVerb(unsigned int const code, @@ -296,7 +297,7 @@ class TutorialVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ TutorialVerb(unsigned int const code, @@ -315,7 +316,7 @@ class TextVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ TextVerb(unsigned int const code, @@ -382,10 +383,10 @@ Verb::~Verb(void) * for a function that every subclass should write. Most * can be written using \c make_action_helper. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return NULL to represent error (this function shouldn't ever be called) */ -SPAction *Verb::make_action(Inkscape::UI::View::View */*view*/) +SPAction *Verb::make_action(Inkscape::ActionContext const & /*context*/) { //std::cout << "make_action" << std::endl; return NULL; @@ -395,13 +396,13 @@ SPAction *Verb::make_action(Inkscape::UI::View::View */*view*/) * Create an action for a \c FileVerb. * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *FileVerb::make_action(Inkscape::UI::View::View *view) +SPAction *FileVerb::make_action(Inkscape::ActionContext const & context) { //std::cout << "fileverb: make_action: " << &perform << std::endl; - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -409,13 +410,13 @@ SPAction *FileVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *EditVerb::make_action(Inkscape::UI::View::View *view) +SPAction *EditVerb::make_action(Inkscape::ActionContext const & context) { //std::cout << "editverb: make_action: " << &perform << std::endl; - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -423,12 +424,12 @@ SPAction *EditVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *SelectionVerb::make_action(Inkscape::UI::View::View *view) +SPAction *SelectionVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -436,12 +437,12 @@ SPAction *SelectionVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *LayerVerb::make_action(Inkscape::UI::View::View *view) +SPAction *LayerVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -449,12 +450,12 @@ SPAction *LayerVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *ObjectVerb::make_action(Inkscape::UI::View::View *view) +SPAction *ObjectVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -462,12 +463,12 @@ SPAction *ObjectVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *ContextVerb::make_action(Inkscape::UI::View::View *view) +SPAction *ContextVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -475,12 +476,12 @@ SPAction *ContextVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *ZoomVerb::make_action(Inkscape::UI::View::View *view) +SPAction *ZoomVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -488,12 +489,12 @@ SPAction *ZoomVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *DialogVerb::make_action(Inkscape::UI::View::View *view) +SPAction *DialogVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -501,12 +502,12 @@ SPAction *DialogVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *HelpVerb::make_action(Inkscape::UI::View::View *view) +SPAction *HelpVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -514,12 +515,12 @@ SPAction *HelpVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *TutorialVerb::make_action(Inkscape::UI::View::View *view) +SPAction *TutorialVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -527,12 +528,12 @@ SPAction *TutorialVerb::make_action(Inkscape::UI::View::View *view) * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *TextVerb::make_action(Inkscape::UI::View::View *view) +SPAction *TextVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -546,16 +547,16 @@ SPAction *TextVerb::make_action(Inkscape::UI::View::View *view) * if the action gets crated, a listener is added to the action with * the vector that is passed in. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @param vector The function vector for the verb. * @return The created action. */ -SPAction *Verb::make_action_helper(Inkscape::UI::View::View *view, void (*perform_fun)(SPAction *, void *), void *in_pntr) +SPAction *Verb::make_action_helper(Inkscape::ActionContext const & context, void (*perform_fun)(SPAction *, void *), void *in_pntr) { SPAction *action; //std::cout << "Adding action: " << _code << std::endl; - action = sp_action_new(view, _id, _(_name), + action = sp_action_new(context, _id, _(_name), _(_tip), _image, this); if (action == NULL) return NULL; @@ -587,22 +588,22 @@ SPAction *Verb::make_action_helper(Inkscape::UI::View::View *view, void (*perfor * looked for, and the sensitivity is matched. Unfortunately, this is * currently a linear search. * - * @param view The view which this action would relate to. + * @param context The action context which this action relates to. * @return The action, or NULL if there is an error. */ -SPAction *Verb::get_action(Inkscape::UI::View::View *view) +SPAction *Verb::get_action(Inkscape::ActionContext const & context) { SPAction *action = NULL; if ( _actions == NULL ) { _actions = new ActionTable; } - ActionTable::iterator action_found = _actions->find(view); + ActionTable::iterator action_found = _actions->find(context.getView()); if (action_found != _actions->end()) { action = action_found->second; } else { - action = this->make_action(view); + action = this->make_action(context); // if (action == NULL) printf("Hmm, NULL in %s\n", _name); if (action == NULL) printf("Hmm, NULL in %s\n", _name); @@ -610,16 +611,16 @@ SPAction *Verb::get_action(Inkscape::UI::View::View *view) sp_action_set_sensitive(action, 0); } else { for (ActionTable::iterator cur_action = _actions->begin(); - cur_action != _actions->end() && view != NULL; + cur_action != _actions->end() && context.getView() != NULL; ++cur_action) { - if (cur_action->first != NULL && cur_action->first->doc() == view->doc()) { + if (cur_action->first != NULL && cur_action->first->doc() == context.getDocument()) { sp_action_set_sensitive(action, cur_action->second->sensitive); break; } } } - _actions->insert(ActionTable::value_type(view, action)); + _actions->insert(ActionTable::value_type(context.getView(), action)); } return action; @@ -802,8 +803,7 @@ void FileVerb::perform(SPAction *action, void *data) #if 0 // These aren't used, but are here to remind people not to use // the CURRENT_DOCUMENT macros unless they really have to. - Inkscape::UI::View::View *current_view = sp_action_get_view(action); - SPDocument *current_document = current_view->doc(); + SPDocument *current_document = sp_action_get_document(action); #endif SPDesktop *desktop = dynamic_cast(sp_action_get_view(action)); @@ -1028,8 +1028,39 @@ void EditVerb::perform(SPAction *action, void *data) */ void SelectionVerb::perform(SPAction *action, void *data) { + Inkscape::Selection *selection = sp_action_get_selection(action); SPDesktop *dt = static_cast(sp_action_get_view(action)); + // Some of these operations have been modified so they work in command-line mode! + // In this case, all we need is a selection + if (!selection) { + return; + } + + switch (reinterpret_cast(data)) { + case SP_VERB_SELECTION_UNION: + sp_selected_path_union(selection, dt); + break; + case SP_VERB_SELECTION_INTERSECT: + sp_selected_path_intersect(selection, dt); + break; + case SP_VERB_SELECTION_DIFF: + sp_selected_path_diff(selection, dt); + break; + case SP_VERB_SELECTION_SYMDIFF: + sp_selected_path_symdiff(selection, dt); + break; + case SP_VERB_SELECTION_CUT: + sp_selected_path_cut(selection, dt); + break; + case SP_VERB_SELECTION_SLICE: + sp_selected_path_slice(selection, dt); + break; + default: + break; + } + + // The remaining operations require a desktop if (!dt) return; @@ -1065,26 +1096,6 @@ void SelectionVerb::perform(SPAction *action, void *data) text_remove_all_kerns(); break; - case SP_VERB_SELECTION_UNION: - sp_selected_path_union(dt); - break; - case SP_VERB_SELECTION_INTERSECT: - sp_selected_path_intersect(dt); - break; - case SP_VERB_SELECTION_DIFF: - sp_selected_path_diff(dt); - break; - case SP_VERB_SELECTION_SYMDIFF: - sp_selected_path_symdiff(dt); - break; - - case SP_VERB_SELECTION_CUT: - sp_selected_path_cut(dt); - break; - case SP_VERB_SELECTION_SLICE: - sp_selected_path_slice(dt); - break; - case SP_VERB_SELECTION_OFFSET: sp_selected_path_offset(dt); break; @@ -1500,7 +1511,7 @@ void ContextVerb::perform(SPAction *action, void *data) */ for (vidx = SP_VERB_CONTEXT_SELECT; vidx <= SP_VERB_CONTEXT_PAINTBUCKET_PREFS; vidx++) { - SPAction *tool_action= get((sp_verb_t)vidx)->get_action(dt); + SPAction *tool_action= get((sp_verb_t)vidx)->get_action(action->context); if (tool_action) { sp_action_set_active(tool_action, vidx == (int)verb); } @@ -2090,7 +2101,7 @@ class EffectLastVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ EffectLastVerb(unsigned int const code, @@ -2109,12 +2120,12 @@ public: * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *EffectLastVerb::make_action(Inkscape::UI::View::View *view) +SPAction *EffectLastVerb::make_action(Inkscape::ActionContext const & context) { - return make_action_helper(view, &perform); + return make_action_helper(context, &perform); } /** @@ -2155,7 +2166,7 @@ class FitCanvasVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ FitCanvasVerb(unsigned int const code, @@ -2174,12 +2185,12 @@ public: * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *FitCanvasVerb::make_action(Inkscape::UI::View::View *view) +SPAction *FitCanvasVerb::make_action(Inkscape::ActionContext const & context) { - SPAction *action = make_action_helper(view, &perform); + SPAction *action = make_action_helper(context, &perform); return action; } @@ -2221,7 +2232,7 @@ class LockAndHideVerb : public Verb { private: static void perform(SPAction *action, void *mydata); protected: - virtual SPAction *make_action(Inkscape::UI::View::View *view); + virtual SPAction *make_action(Inkscape::ActionContext const & context); public: /** Use the Verb initializer with the same parameters. */ LockAndHideVerb(unsigned int const code, @@ -2240,12 +2251,12 @@ public: * * Calls \c make_action_helper with the \c vector. * - * @param view Which view the action should be created for. + * @param context Which context the action should be created for. * @return The built action. */ -SPAction *LockAndHideVerb::make_action(Inkscape::UI::View::View *view) +SPAction *LockAndHideVerb::make_action(Inkscape::ActionContext const & context) { - SPAction *action = make_action_helper(view, &perform); + SPAction *action = make_action_helper(context, &perform); return action; } diff --git a/src/verbs.h b/src/verbs.h index dab524d7a..35165822a 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -23,6 +23,9 @@ struct SPAction; class SPDocument; namespace Inkscape { + +class ActionContext; + namespace UI { namespace View { class View; @@ -472,8 +475,8 @@ public: protected: - SPAction *make_action_helper (Inkscape::UI::View::View *view, void (*perform_fun)(SPAction *, void *), void *in_pntr = NULL); - virtual SPAction *make_action (Inkscape::UI::View::View *view); + SPAction *make_action_helper (Inkscape::ActionContext const & context, void (*perform_fun)(SPAction *, void *), void *in_pntr = NULL); + virtual SPAction *make_action (Inkscape::ActionContext const & context); public: @@ -521,7 +524,7 @@ public: Verb (gchar const * id, gchar const * name, gchar const * tip, gchar const * image, gchar const * group); virtual ~Verb (void); - SPAction * get_action(Inkscape::UI::View::View * view); + SPAction * get_action(Inkscape::ActionContext const & context); private: static Verb * get_search (unsigned int code); diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 467f0d70e..a1bd9b792 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -20,6 +20,7 @@ #include "icon.h" #include "shortcuts.h" #include "interface.h" +#include "helper/action-context.h" #include @@ -309,7 +310,7 @@ sp_button_new_from_data( Inkscape::IconSize size, const gchar *tip ) { GtkWidget *button; - SPAction *action=sp_action_new(view, name, name, tip, name, 0); + SPAction *action=sp_action_new(Inkscape::ActionContext(view), name, name, tip, name, 0); button = sp_button_new (size, type, action, NULL); g_object_unref(action); return button; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 814298041..c1214c1a4 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -41,6 +41,8 @@ #include "ege-select-one-action.h" #include #include "file.h" +#include "helper/action.h" +#include "helper/action-context.h" #include "helper/units.h" #include "helper/unit-tracker.h" #include "inkscape-private.h" @@ -485,7 +487,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gchar const* tip = ""; Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); if ( verb ) { - SPAction *act = verb->get_action( dtw->viewwidget.view ); + SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); if ( act && act->tip ) { tip = act->tip; } @@ -1060,7 +1062,7 @@ void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled ) { Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); if ( verb ) { - SPAction *act = verb->get_action( dtw->viewwidget.view ); + SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); if ( act ) { sp_action_set_sensitive( act, enabled ); } diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 7a7f0d8ff..5ac994509 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -26,6 +26,7 @@ #include "inkscape.h" #include "verbs.h" #include "helper/action.h" +#include "helper/action-context.h" #include "preferences.h" #include @@ -535,7 +536,7 @@ sp_gradient_selector_edit_vector_clicked (GtkWidget */*w*/, SPGradientSelector * // Invoke the gradient tool Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); if ( verb ) { - SPAction *action = verb->get_action( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP); + SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); if ( action ) { sp_action_perform( action, NULL ); } diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 3126175b3..c7659ab42 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -55,6 +55,8 @@ #include "../xml/repr.h" #include "ui/uxmanager.h" #include "../ui/icon-names.h" +#include "../helper/action.h" +#include "../helper/action-context.h" #include "../helper/unit-menu.h" #include "../helper/units.h" #include "../helper/unit-tracker.h" @@ -286,7 +288,7 @@ static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data) SPDesktop *desktop = static_cast(data); if (tools_isactive(desktop, TOOLS_LPETOOL)) { - sp_action_perform(Inkscape::Verb::get(SP_VERB_DIALOG_LIVE_PATH_EFFECT)->get_action(desktop), NULL); + sp_action_perform(Inkscape::Verb::get(SP_VERB_DIALOG_LIVE_PATH_EFFECT)->get_action(Inkscape::ActionContext(desktop)), NULL); } gtk_toggle_action_set_active(act, false); } diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 549581610..1bfc841e3 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -37,6 +37,8 @@ #include "sp-namedview.h" #include "toolbox.h" #include +#include "helper/action.h" +#include "helper/action-context.h" #include "helper/unit-menu.h" #include "helper/units.h" #include "inkscape.h" @@ -413,7 +415,7 @@ static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::Vi { GtkAction* act = 0; - SPAction* targetAction = verb->get_action(view); + SPAction* targetAction = verb->get_action(Inkscape::ActionContext(view)); InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size ); act = GTK_ACTION(inky); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 0fdf36d5f..ca593976f 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -47,6 +47,8 @@ #include "../ege-output-action.h" #include "../ege-select-one-action.h" #include "../graphlayout.h" +#include "../helper/action.h" +#include "../helper/action-context.h" #include "../helper/unit-menu.h" #include "../helper/units.h" #include "../helper/unit-tracker.h" @@ -591,9 +593,9 @@ private: Glib::RefPtr VerbAction::create(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view) { Glib::RefPtr result; - SPAction *action = verb->get_action(view); + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); if ( action ) { - //SPAction* action2 = verb2 ? verb2->get_action(view) : 0; + //SPAction* action2 = verb2 ? verb2->get_action(Inkscape::ActionContext(view)) : 0; result = Glib::RefPtr(new VerbAction(verb, verb2, view)); } @@ -680,7 +682,7 @@ void VerbAction::set_active(bool active) void VerbAction::on_activate() { if ( verb ) { - SPAction *action = verb->get_action(view); + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); if ( action ) { sp_action_perform(action, 0); } @@ -770,14 +772,14 @@ GtkToolItem * sp_toolbox_button_item_new_from_verb_with_doubleclick(GtkWidget *t Inkscape::Verb *verb, Inkscape::Verb *doubleclick_verb, Inkscape::UI::View::View *view) { - SPAction *action = verb->get_action(view); + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); if (!action) { return NULL; } SPAction *doubleclick_action; if (doubleclick_verb) { - doubleclick_action = doubleclick_verb->get_action(view); + doubleclick_action = doubleclick_verb->get_action(Inkscape::ActionContext(view)); } else { doubleclick_action = NULL; } @@ -822,7 +824,7 @@ static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::Vi { GtkAction* act = 0; - SPAction* targetAction = verb->get_action(view); + SPAction* targetAction = verb->get_action(Inkscape::ActionContext(view)); InkAction* inky = ink_action_new( verb->get_id(), _(verb->get_name()), verb->get_tip(), verb->get_image(), size ); act = GTK_ACTION(inky); gtk_action_set_sensitive( act, targetAction->sensitive ); -- cgit v1.2.3 From 6fe6a37589cbd6e53bf763879503ace16260e7a2 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Mon, 1 Jul 2013 21:09:53 +0100 Subject: Added new files referenced in previous commit message (forgot to add!) (bzr r12387.1.2) --- src/helper/action-context.cpp | 74 ++++++++++++ src/helper/action-context.h | 78 +++++++++++++ src/layer-model.cpp | 259 ++++++++++++++++++++++++++++++++++++++++++ src/layer-model.h | 104 +++++++++++++++++ 4 files changed, 515 insertions(+) create mode 100644 src/helper/action-context.cpp create mode 100644 src/helper/action-context.h create mode 100644 src/layer-model.cpp create mode 100644 src/layer-model.h (limited to 'src') diff --git a/src/helper/action-context.cpp b/src/helper/action-context.cpp new file mode 100644 index 000000000..c88086f7f --- /dev/null +++ b/src/helper/action-context.cpp @@ -0,0 +1,74 @@ +/* + * ActionContext implementation. + * + * Author: + * Eric Greveson + * + * Copyright (C) 2013 Eric Greveson + * + * This code is in public domain + */ + +#include "desktop.h" +#include "document.h" +#include "layer-model.h" +#include "selection.h" +#include "helper/action-context.h" +#include "ui/view/view.h" + +namespace Inkscape { + +ActionContext::ActionContext() + : _selection(NULL) + , _view(NULL) +{ +} + +ActionContext::ActionContext(Selection *selection) + : _selection(selection) + , _view(NULL) +{ +} + +ActionContext::ActionContext(UI::View::View *view) + : _selection(NULL) + , _view(view) +{ + SPDesktop *desktop = static_cast(view); + if (desktop) { + _selection = desktop->selection; + } +} + +SPDocument *ActionContext::getDocument() const +{ + if (_selection == NULL) { + return NULL; + } + + // Should be the same as the view's document, if view is non-NULL + return _selection->layerModel()->getDocument(); +} + +Selection *ActionContext::getSelection() const +{ + return _selection; +} + +UI::View::View *ActionContext::getView() const +{ + return _view; +} + +} // 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/helper/action-context.h b/src/helper/action-context.h new file mode 100644 index 000000000..de09f94f4 --- /dev/null +++ b/src/helper/action-context.h @@ -0,0 +1,78 @@ +/** \file + * Inkscape UI action context implementation + *//* + * Author: + * Eric Greveson + * + * Copyright (C) 2013 Eric Greveson + * + * This code is in public domain + */ + +#ifndef SEEN_INKSCAPE_ACTION_CONTEXT_H +#define SEEN_INKSCAPE_ACTION_CONTEXT_H + +class SPDocument; + +namespace Inkscape { + +class Selection; + +namespace UI { +namespace View { +class View; +} // namespace View +} // namespace UI + +/** This structure contains all the document/view context required + for an action. Some actions may be executed on a document without + requiring a GUI, hence not providing the info directly through + Inkscape::UI::View::View. Actions that do require GUI objects should + check to see if the relevant pointers are NULL before attempting to + use them. + + ActionContext is designed to be copyable, so it may be used with stack + storage if required. */ +class ActionContext { + // NB: Only one of these is typically set - selection model if in console mode, view if in GUI mode + Selection *_selection; /**< The selection model to which this action applies, if running in console mode. May be NULL. */ + UI::View::View *_view; /**< The view to which this action applies. May be NULL (e.g. if running in console mode). */ + +public: + /** Construct without any document or GUI */ + ActionContext(); + + /** Construct an action context for when the app is being run without + any GUI, i.e. in console mode */ + ActionContext(Selection *selection); + + /** Construct an action context for when the app is being run in GUI mode */ + ActionContext(UI::View::View *view); + + /** Get the document for the action context. May be NULL. Prefer this + function to getView()->doc() if the action doesn't require a GUI. */ + SPDocument *getDocument() const; + + /** Get the selection for the action context. May be NULL. Should be + non-NULL if getDocument() is non-NULL. */ + Selection *getSelection() const; + + /** Get the view for the action context. May be NULL. Guaranteed to be + NULL if running in console mode. */ + UI::View::View *getView() const; +}; + +} // namespace Inkscape + +#endif + +/* + 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 : diff --git a/src/layer-model.cpp b/src/layer-model.cpp new file mode 100644 index 000000000..6833852ad --- /dev/null +++ b/src/layer-model.cpp @@ -0,0 +1,259 @@ +/* + * Editable view implementation + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * Ralf Stephan + * John Bintz + * Johan Engelen + * Jon A. Cruz + * Abhishek Sharma + * + * Copyright (C) 2007 Jon A. Cruz + * Copyright (C) 2006-2008 Johan Engelen + * Copyright (C) 2006 John Bintz + * Copyright (C) 2004 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "document.h" +#include "layer-fns.h" +#include "layer-model.h" +#include "object-hierarchy.h" +#include "sp-defs.h" +#include "sp-item.h" +#include "sp-item-group.h" +#include "sp-object.h" +#include "sp-root.h" +#include +#include +#include + +// Callbacks +static void _layer_activated(SPObject *layer, Inkscape::LayerModel *layer_model); +static void _layer_deactivated(SPObject *layer, Inkscape::LayerModel *layer_model); +static void _layer_changed(SPObject *top, SPObject *bottom, Inkscape::LayerModel *layer_model); + +namespace Inkscape { + +LayerModel::LayerModel() + : _doc( 0 ) + , _layer_hierarchy( 0 ) + , _display_key( 0 ) +{ +} + +LayerModel::~LayerModel() +{ + if (_layer_hierarchy) { + delete _layer_hierarchy; +// _layer_hierarchy = NULL; //this should be here, but commented to find other bug somewhere else. + } +} + +void LayerModel::setDocument(SPDocument *doc) +{ + _doc = doc; + if (_layer_hierarchy) { + _layer_hierarchy->clear(); + delete _layer_hierarchy; + } + _layer_hierarchy = new Inkscape::ObjectHierarchy(NULL); + _layer_hierarchy->connectAdded(sigc::bind(sigc::ptr_fun(_layer_activated), this)); + _layer_hierarchy->connectRemoved(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); + _layer_hierarchy->connectChanged(sigc::bind(sigc::ptr_fun(_layer_changed), this)); + _layer_hierarchy->setTop(doc->getRoot()); +} + +void LayerModel::setDisplayKey(unsigned int display_key) +{ + _display_key = display_key; +} + +SPDocument *LayerModel::getDocument() +{ + return _doc; +} + +/** + * Returns current root (=bottom) layer. + */ +SPObject *LayerModel::currentRoot() const +{ + return _layer_hierarchy ? _layer_hierarchy->top() : NULL; +} + +/** + * Returns current top layer. + */ +SPObject *LayerModel::currentLayer() const +{ + return _layer_hierarchy ? _layer_hierarchy->bottom() : NULL; +} + +/** + * Resets the bottom layer to the current root + */ +void LayerModel::reset() { + if (_layer_hierarchy) { + _layer_hierarchy->setBottom(currentRoot()); + } +} + +/** + * Sets the current layer of the desktop. + * + * Make \a object the top layer. + */ +void LayerModel::setCurrentLayer(SPObject *object) { + g_return_if_fail(SP_IS_GROUP(object)); + g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); + // printf("Set Layer to ID: %s\n", object->getId()); + _layer_hierarchy->setBottom(object); +} + +void LayerModel::toggleHideAllLayers(bool hide) { + + for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), currentRoot()); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { + SP_ITEM(obj)->setHidden(hide); + } +} + +void LayerModel::toggleLockAllLayers(bool lock) { + + for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), currentRoot()); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { + SP_ITEM(obj)->setLocked(lock); + } +} + +void LayerModel::toggleLockOtherLayers(SPObject *object) { + g_return_if_fail(SP_IS_GROUP(object)); + g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); + + bool othersLocked = false; + std::vector layers; + for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) { + // Dont lock any ancestors, since that would in turn lock the layer as well + if (!obj->isAncestorOf(object)) { + layers.push_back(obj); + othersLocked |= !SP_ITEM(obj)->isLocked(); + } + } + for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { + if (!obj->isAncestorOf(object)) { + layers.push_back(obj); + othersLocked |= !SP_ITEM(obj)->isLocked(); + } + } + + SPItem *item = SP_ITEM(object); + if ( item->isLocked() ) { + item->setLocked(false); + } + + for ( std::vector::iterator it = layers.begin(); it != layers.end(); ++it ) { + SP_ITEM(*it)->setLocked(othersLocked); + } +} + + +void LayerModel::toggleLayerSolo(SPObject *object) { + g_return_if_fail(SP_IS_GROUP(object)); + g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); + + bool othersShowing = false; + std::vector layers; + for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) { + // Don't hide ancestors, since that would in turn hide the layer as well + if (!obj->isAncestorOf(object)) { + layers.push_back(obj); + othersShowing |= !SP_ITEM(obj)->isHidden(); + } + } + for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) { + if (!obj->isAncestorOf(object)) { + layers.push_back(obj); + othersShowing |= !SP_ITEM(obj)->isHidden(); + } + } + + + SPItem *item = SP_ITEM(object); + if ( item->isHidden() ) { + item->setHidden(false); + } + + for ( std::vector::iterator it = layers.begin(); it != layers.end(); ++it ) { + SP_ITEM(*it)->setHidden(othersShowing); + } +} + +/** + * Return layer that contains \a object. + */ +SPObject *LayerModel::layerForObject(SPObject *object) { + g_return_val_if_fail(object != NULL, NULL); + + SPObject *root=currentRoot(); + object = object->parent; + while ( object && object != root && !isLayer(object) ) { + // Objects in defs have no layer and are NOT in the root layer + if(SP_IS_DEFS(object)) + return NULL; + object = object->parent; + } + return object; +} + +/** + * True if object is a layer. + */ +bool LayerModel::isLayer(SPObject *object) const { + return ( SP_IS_GROUP(object) + && ( SP_GROUP(object)->effectiveLayerMode(_display_key) + == SPGroup::LAYER ) ); +} + +} // namespace Inkscape + + +/// Callback +static void +_layer_activated(SPObject *layer, Inkscape::LayerModel *layer_model) { + g_return_if_fail(SP_IS_GROUP(layer)); + layer_model->_layer_activated_signal.emit(layer); +} + +/// Callback +static void +_layer_deactivated(SPObject *layer, Inkscape::LayerModel *layer_model) { + g_return_if_fail(SP_IS_GROUP(layer)); + layer_model->_layer_deactivated_signal.emit(layer); +} + +/// Callback +static void +_layer_changed(SPObject *top, SPObject *bottom, Inkscape::LayerModel *layer_model) +{ + layer_model->_layer_changed_signal.emit (top, bottom); +} + +/* + 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 : diff --git a/src/layer-model.h b/src/layer-model.h new file mode 100644 index 000000000..79b7fbe44 --- /dev/null +++ b/src/layer-model.h @@ -0,0 +1,104 @@ +#ifndef SEEN_INKSCAPE_LAYER_MODEL_H +#define SEEN_INKSCAPE_LAYER_MODEL_H + +/* + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * Ralf Stephan + * John Bintz + * Johan Engelen + * Jon A. Cruz get + * Abhishek Sharma + * Eric Greveson + * + * Copyright (C) 2007 Johan Engelen + * Copyright (C) 2006 John Bintz + * Copyright (C) 1999-2013 authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +class SPDocument; +class SPObject; + +namespace Inkscape { + +class ObjectHierarchy; + +namespace XML { + class Node; +} + +/** + * The layer model for a document. + * + * This class represents the layer model for a document, typically (but + * not necessarily) displayed in an SPDesktop. + * + * It also implements its own asynchronous notification signals that + * UI elements can listen to. + */ +class LayerModel +{ + SPDocument *_doc; + Inkscape::ObjectHierarchy *_layer_hierarchy; + unsigned int _display_key; + +public: + /** Construct a layer model */ + LayerModel(); + + /** Destructor */ + ~LayerModel(); + + // Set document + void setDocument(SPDocument *doc); + + // Set display key. For GUI apps. + void setDisplayKey(unsigned int display_key); + + // Get the document that this layer model refers to. May be NULL. + SPDocument *getDocument(); + + // TODO look into making these return a more specific subclass: + SPObject *currentRoot() const; + SPObject *currentLayer() const; + + void reset(); + void setCurrentLayer(SPObject *object); + void toggleLayerSolo(SPObject *object); + void toggleHideAllLayers(bool hide); + void toggleLockAllLayers(bool lock); + void toggleLockOtherLayers(SPObject *object); + SPObject *layerForObject(SPObject *object); + bool isLayer(SPObject *object) const; + + sigc::signal _layer_activated_signal; + sigc::signal _layer_deactivated_signal; + sigc::signal _layer_changed_signal; +}; + +} // namespace Inkscape + +#endif +/* + 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 : -- cgit v1.2.3 From 2a53d44964f9105ce0f9c8725853150dc5360096 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Mon, 1 Jul 2013 22:27:23 +0100 Subject: Added error messages when attempting to use verbs requiring GUI in console (--without-gui) mode. (bzr r12387.1.3) --- src/extension/effect.cpp | 5 ++- src/verbs.cpp | 83 ++++++++++++++++++++++++++++++++++++++++-------- src/verbs.h | 5 +++ 3 files changed, 78 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 22c5e4989..93b1bb91d 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -369,12 +369,15 @@ void Effect::EffectVerb::perform( SPAction *action, void * data ) { Inkscape::UI::View::View * current_view = sp_action_get_view(action); + if (current_view == NULL) { + show_gui_required_message(action); + return; + } // SPDocument * current_document = current_view->doc; Effect::EffectVerb * ev = reinterpret_cast(data); Effect * effect = ev->_effect; if (effect == NULL) return; - if (current_view == NULL) return; if (ev->_showPrefs) { effect->prefs(current_view); diff --git a/src/verbs.cpp b/src/verbs.cpp index 4bbd3f9df..979267215 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -626,6 +626,12 @@ SPAction *Verb::get_action(Inkscape::ActionContext const & context) return action; } +/* static */ +void Verb::show_gui_required_message(SPAction *action) +{ + g_printerr("WARNING: ignoring verb %s - GUI required for this verb.\n", action->id); +} + void Verb::sensitive(SPDocument *in_doc, bool in_sensitive) { // printf("Setting sensitivity of \"%s\" to %d\n", _name, in_sensitive); @@ -807,7 +813,11 @@ void FileVerb::perform(SPAction *action, void *data) #endif SPDesktop *desktop = dynamic_cast(sp_action_get_view(action)); - g_assert(desktop != NULL); + if (desktop == NULL) { + show_gui_required_message(action); + return; + } + Gtk::Window *parent = desktop->getToplevel(); g_assert(parent != NULL); @@ -873,8 +883,10 @@ void FileVerb::perform(SPAction *action, void *data) void EditVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) + if (dt == NULL) { + show_gui_required_message(action); return; + } switch (reinterpret_cast(data)) { case SP_VERB_EDIT_UNDO: @@ -1037,6 +1049,7 @@ void SelectionVerb::perform(SPAction *action, void *data) return; } + bool handled = true; switch (reinterpret_cast(data)) { case SP_VERB_SELECTION_UNION: sp_selected_path_union(selection, dt); @@ -1057,12 +1070,19 @@ void SelectionVerb::perform(SPAction *action, void *data) sp_selected_path_slice(selection, dt); break; default: + handled = false; break; } + if (handled) { + return; + } + // The remaining operations require a desktop - if (!dt) + if (dt == NULL) { + show_gui_required_message(action); return; + } g_assert(dt->_dlg_mgr != NULL); @@ -1162,8 +1182,12 @@ void LayerVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); size_t verb = reinterpret_cast(data); - - if ( !dt || !dt->currentLayer() ) { + + if (dt == NULL) { + show_gui_required_message(action); + return; + } + if ( !dt->currentLayer() ) { return; } @@ -1412,8 +1436,10 @@ void LayerVerb::perform(SPAction *action, void *data) void ObjectVerb::perform( SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) + if (dt == NULL) { + show_gui_required_message(action); return; + } SPEventContext *ec = dt->event_context; @@ -1500,9 +1526,11 @@ void ContextVerb::perform(SPAction *action, void *data) int vidx; dt = static_cast(sp_action_get_view(action)); - - if (!dt) + + if (dt == NULL) { + show_gui_required_message(action); return; + } verb = (sp_verb_t)GPOINTER_TO_INT((gpointer)data); @@ -1701,8 +1729,10 @@ void ContextVerb::perform(SPAction *action, void *data) void TextVerb::perform(SPAction *action, void */*data*/) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) + if (dt == NULL) { + show_gui_required_message(action); return; + } SPDocument *doc = sp_desktop_document(dt); (void)doc; @@ -1716,8 +1746,10 @@ void TextVerb::perform(SPAction *action, void */*data*/) void ZoomVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) + if (dt == NULL) { + show_gui_required_message(action); return; + } SPEventContext *ec = dt->event_context; SPDocument *doc = sp_desktop_document(dt); @@ -1906,6 +1938,10 @@ void DialogVerb::perform(SPAction *action, void *data) } SPDesktop *dt = static_cast(sp_action_get_view(action)); + if (dt == NULL) { + show_gui_required_message(action); + return; + } g_assert(dt->_dlg_mgr != NULL); switch (reinterpret_cast(data)) { @@ -2018,6 +2054,10 @@ void DialogVerb::perform(SPAction *action, void *data) void HelpVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); + if (dt == NULL) { + show_gui_required_message(action); + return; + } g_assert(dt->_dlg_mgr != NULL); switch (reinterpret_cast(data)) { @@ -2050,8 +2090,12 @@ void HelpVerb::perform(SPAction *action, void *data) /** * Decode the verb code and take appropriate action. */ -void TutorialVerb::perform(SPAction */*action*/, void *data) +void TutorialVerb::perform(SPAction *action, void *data) { + if (sp_action_get_view(action) == NULL) { + show_gui_required_message(action); + return; + } switch (reinterpret_cast(data)) { case SP_VERB_TUTORIAL_BASIC: // TRANSLATORS: If you have translated the tutorial-basic.en.svgz file to your language, @@ -2136,11 +2180,14 @@ void EffectLastVerb::perform(SPAction *action, void *data) // These aren't used, but are here to remind people not to use // the CURRENT_DOCUMENT macros unless they really have to. Inkscape::UI::View::View *current_view = sp_action_get_view(action); + if (current_view == NULL) { + show_gui_required_message(action); + return; + } // SPDocument *current_document = SP_VIEW_DOCUMENT(current_view); Inkscape::Extension::Effect *effect = Inkscape::Extension::Effect::get_last_effect(); if (effect == NULL) return; - if (current_view == NULL) return; switch (reinterpret_cast(data)) { case SP_VERB_EFFECT_LAST_PREF: @@ -2200,7 +2247,11 @@ SPAction *FitCanvasVerb::make_action(Inkscape::ActionContext const & context) void FitCanvasVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) return; + if (dt == NULL) { + show_gui_required_message(action); + return; + } + SPDocument *doc = sp_desktop_document(dt); if (!doc) return; @@ -2266,7 +2317,11 @@ SPAction *LockAndHideVerb::make_action(Inkscape::ActionContext const & context) void LockAndHideVerb::perform(SPAction *action, void *data) { SPDesktop *dt = static_cast(sp_action_get_view(action)); - if (!dt) return; + if (dt == NULL) { + show_gui_required_message(action); + return; + } + SPDocument *doc = sp_desktop_document(dt); if (!doc) return; diff --git a/src/verbs.h b/src/verbs.h index 35165822a..dd58134dd 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -550,6 +550,11 @@ public: } } static Verb * getbyid (gchar const * id); + + /** + * Print a message to stderr indicating that this verb needs a GUI to run + */ + static void show_gui_required_message(SPAction *action); static void delete_all_view (Inkscape::UI::View::View * view); void delete_view (Inkscape::UI::View::View * view); -- cgit v1.2.3 From 4d9cb756267d624666ae792d621a255f4b209657 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 1 Jul 2013 22:23:13 -0400 Subject: Refactor resize, rotate, skew handle code (bzr r12400) --- src/seltrans-handles.cpp | 52 +++++---- src/seltrans-handles.h | 42 +++---- src/seltrans.cpp | 287 +++++++++++++++++------------------------------ src/seltrans.h | 13 ++- 4 files changed, 157 insertions(+), 237 deletions(-) (limited to 'src') diff --git a/src/seltrans-handles.cpp b/src/seltrans-handles.cpp index fc03789d6..cc11125f6 100644 --- a/src/seltrans-handles.cpp +++ b/src/seltrans-handles.cpp @@ -1,33 +1,39 @@ #include "seltrans-handles.h" +#ifdef __cplusplus +#undef N_ +#define N_(x) x +#endif -SPSelTransHandle const handles_scale[] = { -//anchor cursor control action request x y - {SP_ANCHOR_SE, GDK_TOP_LEFT_CORNER, 0, sp_sel_trans_scale, sp_sel_trans_scale_request, 0, 1}, - {SP_ANCHOR_S, GDK_TOP_SIDE, 3, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0.5, 1}, - {SP_ANCHOR_SW, GDK_TOP_RIGHT_CORNER, 1, sp_sel_trans_scale, sp_sel_trans_scale_request, 1, 1}, - {SP_ANCHOR_W, GDK_RIGHT_SIDE, 2, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 1, 0.5}, - {SP_ANCHOR_NW, GDK_BOTTOM_RIGHT_CORNER, 0, sp_sel_trans_scale, sp_sel_trans_scale_request, 1, 0}, - {SP_ANCHOR_N, GDK_BOTTOM_SIDE, 3, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0.5, 0}, - {SP_ANCHOR_NE, GDK_BOTTOM_LEFT_CORNER, 1, sp_sel_trans_scale, sp_sel_trans_scale_request, 0, 0}, - {SP_ANCHOR_E, GDK_LEFT_SIDE, 2, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0, 0.5} +SPSelTransTypeInfo const handtypes[] = { + {N_("Squeeze or stretch selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, + {N_("Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, + {N_("Skew selection; with Ctrl to snap angle; with Shift to skew around the opposite side") }, + {N_("Rotate selection; with Ctrl to snap angle; with Shift to rotate around the opposite corner") }, + {N_("Center of rotation and skewing: drag to reposition; scaling with Shift also uses this center") } }; -SPSelTransHandle const handles_rotate[] = { - {SP_ANCHOR_SE, GDK_EXCHANGE, 4, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 0, 1}, - {SP_ANCHOR_S, GDK_SB_H_DOUBLE_ARROW, 5, sp_sel_trans_skew, sp_sel_trans_skew_request, 0.5, 1}, - {SP_ANCHOR_SW, GDK_EXCHANGE, 6, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 1, 1}, - {SP_ANCHOR_W, GDK_SB_V_DOUBLE_ARROW, 7, sp_sel_trans_skew, sp_sel_trans_skew_request, 1, 0.5}, - {SP_ANCHOR_NW, GDK_EXCHANGE, 8, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 1, 0}, - {SP_ANCHOR_N, GDK_SB_H_DOUBLE_ARROW, 9, sp_sel_trans_skew, sp_sel_trans_skew_request, 0.5, 0}, - {SP_ANCHOR_NE, GDK_EXCHANGE, 10, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 0, 0}, - {SP_ANCHOR_E, GDK_SB_V_DOUBLE_ARROW, 11, sp_sel_trans_skew, sp_sel_trans_skew_request, 0, 0.5} +SPSelTransHandle const hands[] = { +//handle-type anchor cursor control x y + {HANDLE_STRETCH, SP_ANCHOR_S, GDK_TOP_SIDE, 3, 0.5, 1}, + {HANDLE_STRETCH, SP_ANCHOR_W, GDK_RIGHT_SIDE, 2, 1, 0.5}, + {HANDLE_STRETCH, SP_ANCHOR_N, GDK_BOTTOM_SIDE, 3, 0.5, 0}, + {HANDLE_STRETCH, SP_ANCHOR_E, GDK_LEFT_SIDE, 2, 0, 0.5}, + {HANDLE_SCALE, SP_ANCHOR_SE, GDK_TOP_LEFT_CORNER, 0, 0, 1}, + {HANDLE_SCALE, SP_ANCHOR_SW, GDK_TOP_RIGHT_CORNER, 1, 1, 1}, + {HANDLE_SCALE, SP_ANCHOR_NW, GDK_BOTTOM_RIGHT_CORNER, 0, 1, 0}, + {HANDLE_SCALE, SP_ANCHOR_NE, GDK_BOTTOM_LEFT_CORNER, 1, 0, 0}, + {HANDLE_SKEW, SP_ANCHOR_S, GDK_SB_H_DOUBLE_ARROW, 5, 0.5, 1}, + {HANDLE_SKEW, SP_ANCHOR_W, GDK_SB_V_DOUBLE_ARROW, 7, 1, 0.5}, + {HANDLE_SKEW, SP_ANCHOR_N, GDK_SB_H_DOUBLE_ARROW, 9, 0.5, 0}, + {HANDLE_SKEW, SP_ANCHOR_E, GDK_SB_V_DOUBLE_ARROW, 11, 0, 0.5}, + {HANDLE_ROTATE, SP_ANCHOR_SE, GDK_EXCHANGE, 4, 0, 1}, + {HANDLE_ROTATE, SP_ANCHOR_SW, GDK_EXCHANGE, 6, 1, 1}, + {HANDLE_ROTATE, SP_ANCHOR_NW, GDK_EXCHANGE, 8, 1, 0}, + {HANDLE_ROTATE, SP_ANCHOR_NE, GDK_EXCHANGE, 10, 0, 0}, + {HANDLE_CENTER, SP_ANCHOR_CENTER, GDK_CROSSHAIR, 12, 0.5, 0.5} }; -SPSelTransHandle const handle_center = - {SP_ANCHOR_CENTER, GDK_CROSSHAIR, 12, sp_sel_trans_center, sp_sel_trans_center_request, 0.5, 0.5}; - - /* Local Variables: mode:c++ diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index 14f50d784..ef285392b 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -21,40 +21,32 @@ namespace Inkscape class SelTrans; } -struct SPSelTransHandle; +enum SPSelTransType { + HANDLE_STRETCH, + HANDLE_SCALE, + HANDLE_SKEW, + HANDLE_ROTATE, + HANDLE_CENTER +}; -// request handlers -gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &p, guint state); -gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &p, guint state); -gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &p, guint state); -gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &p, guint state); -gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &p, guint state); +struct SPSelTransTypeInfo { + gchar const *tip; +}; +// One per handle type in order +extern SPSelTransTypeInfo const handtypes[5]; -// action handlers -void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); -void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); -void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); -void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); -void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); +struct SPSelTransHandle; struct SPSelTransHandle { + SPSelTransType type; SPAnchorType anchor; GdkCursorType cursor; guint control; - void (* action) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); - gboolean (* request) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); gdouble x, y; }; - -// TODO these must be purged: -extern SPSelTransHandle const handles_scale[8]; -extern SPSelTransHandle const handles_rotate[8]; -extern SPSelTransHandle const handle_center; +// These are 4 * each handle type + 1 for center +int const NUMHANDS = 17; +extern SPSelTransHandle const hands[17]; #endif // SEEN_SP_SELTRANS_HANDLES_H diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 84c73e452..016eba816 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -48,12 +48,11 @@ #include <2geom/angle.h> #include "display/snap-indicator.h" #include "ui/control-manager.h" +#include "seltrans-handles.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; -static void sp_remove_handles(SPKnot *knot[], gint num); - static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data); static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, gpointer data); static void sp_sel_trans_handle_click(SPKnot *knot, guint state, gpointer data); @@ -62,7 +61,7 @@ static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *p, guint extern GdkPixbuf *handles[]; -static gboolean sp_seltrans_handle_event(SPKnot *knot, GdkEvent *event, gpointer) +static gboolean sp_sel_trans_handle_event(SPKnot *knot, GdkEvent *event, gpointer) { switch (event->type) { case GDK_MOTION_NOTIFY: @@ -112,7 +111,6 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : _opposite_for_bboxpoints(Geom::Point(0,0)), _origin_for_specpoints(Geom::Point(0,0)), _origin_for_bboxpoints(Geom::Point(0,0)), - _chandle(NULL), _stamp_cache(NULL), _message_context(desktop->messageStack()), _bounding_box_prefs_observer(*this) @@ -124,16 +122,12 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : g_return_if_fail(desktop != NULL); - for (int i = 0; i < 8; i++) { - _shandle[i] = NULL; - _rhandle[i] = NULL; - } - _updateVolatileState(); _current_relative_affine.setIdentity(); _center_is_set = false; // reread _center from items, or set to bbox midpoint + _makeHandles(); _updateHandles(); _selection = sp_desktop_selection(desktop); @@ -190,19 +184,9 @@ Inkscape::SelTrans::~SelTrans() _sel_changed_connection.disconnect(); _sel_modified_connection.disconnect(); - for (unsigned int i = 0; i < 8; i++) { - if (_shandle[i]) { - g_object_unref(G_OBJECT(_shandle[i])); - _shandle[i] = NULL; - } - if (_rhandle[i]) { - g_object_unref(G_OBJECT(_rhandle[i])); - _rhandle[i] = NULL; - } - } - if (_chandle) { - g_object_unref(G_OBJECT(_chandle)); - _chandle = NULL; + for (int i = 0; i < NUMHANDS; i++) { + g_object_unref(G_OBJECT(knots[i])); + knots[i] = NULL; } if (_norm) { @@ -584,13 +568,11 @@ void Inkscape::SelTrans::stamp() void Inkscape::SelTrans::_updateHandles() { + for (int i = 0; i < NUMHANDS; i++) + sp_knot_hide(knots[i]); + if ( !_show_handles || _empty ) - { - sp_remove_handles(_shandle, 8); - sp_remove_handles(_rhandle, 8); - sp_remove_handles(&_chandle, 1); return; - } if (!_center_is_set) { _center = _desktop->selection->center(); @@ -598,57 +580,12 @@ void Inkscape::SelTrans::_updateHandles() } if ( _state == STATE_SCALE ) { - sp_remove_handles(_rhandle, 8); - sp_remove_handles(&_chandle, 1); - _showHandles(_shandle, handles_scale, 8, - _("Squeeze or stretch selection; with Ctrl to scale uniformly; with Shift to scale around rotation center"), - _("Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center")); + _showHandles(HANDLE_STRETCH); + _showHandles(HANDLE_SCALE); } else { - sp_remove_handles(_shandle, 8); - _showHandles(_rhandle, handles_rotate, 8, - _("Skew selection; with Ctrl to snap angle; with Shift to skew around the opposite side"), - _("Rotate selection; with Ctrl to snap angle; with Shift to rotate around the opposite corner")); - // center handle - /* Assuming that the center handle is in its default position, ie. in the center: - * Multiple handles will be shown, for rotating, skewing and the center handle. For straight lines, the bounding box of the center handle will be - * fully overlapped by bounding boxes of two of the skew handles. Due to the internals of sp_canvas_group_point, the center handle must be the - * last handle in the SPCanvasGroup if it is to be selectable in such a case. So we have made sure here that the center handle is added to the - * group after the rotation handles (determined by the chronological order of sp_knot_new() calls) - * Now when the center handle is in still in the center, the skew handles can be selected because because the bounding box of the - * center handle does not fully overlap the bounding box of either of the skew handles. However, if the center handle has been moved such that it - * covers one of the other eight handles, then either the opposite handle has to be used (in case of rotating), or the center handle has to be moved. - * Although this is annoying, this is still better than not being able to select the center handle at all - */ - if ( _chandle == NULL ) { - _chandle = sp_knot_new(_desktop, _("Center of rotation and skewing: drag to reposition; scaling with Shift also uses this center")); - - _chandle->setShape (SP_CTRL_SHAPE_BITMAP); - _chandle->setSize (13); - _chandle->setAnchor (handle_center.anchor); - _chandle->setMode (SP_CTRL_MODE_XOR); - _chandle->setFill(0x00000000, 0x00000000, 0x00000000); - _chandle->setStroke(0x000000ff, 0xff0000b0, 0xff0000b0); - _chandle->setPixbuf(handles[handle_center.control]); - sp_knot_update_ctrl(_chandle); - - g_signal_connect(G_OBJECT(_chandle), "request", - G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &handle_center); - g_signal_connect(G_OBJECT(_chandle), "moved", - G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &handle_center); - g_signal_connect(G_OBJECT(_chandle), "grabbed", - G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &handle_center); - g_signal_connect(G_OBJECT(_chandle), "ungrabbed", - G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &handle_center); - g_signal_connect(G_OBJECT(_chandle), "clicked", - G_CALLBACK(sp_sel_trans_handle_click), (gpointer) &handle_center); - } - - if ( _center ) { - sp_knot_show(_chandle); - sp_knot_moveto(_chandle, *_center); - } else { - sp_remove_handles(&_chandle, 1); - } + _showHandles(HANDLE_SKEW); + _showHandles(HANDLE_ROTATE); + _showHandles(HANDLE_CENTER); } } @@ -673,53 +610,60 @@ void Inkscape::SelTrans::_updateVolatileState() _strokewidth = stroke_average_width (selection->itemList()); } -static void sp_remove_handles(SPKnot *knot[], gint num) +void Inkscape::SelTrans::_showHandles(SPSelTransType type) { - for (int i = 0; i < num; i++) { - if (knot[i] != NULL) { - sp_knot_hide(knot[i]); - } + // shouldn't have nullary bbox, but knots + g_assert(_bbox); + + for (int i = 0; i < NUMHANDS; i++) { + if (hands[i].type != type) + continue; + + // Position knots to scale the selection bbox + Geom::Point const bpos(hands[i].x, hands[i].y); + Geom::Point p(_bbox->min() + (_bbox->dimensions() * Geom::Scale(bpos))); + sp_knot_moveto(knots[i], p); + sp_knot_show(knots[i]); + + // This controls the center handle's position, because the default can + // be moved and needs to be remembered. + if( type == HANDLE_CENTER && _center ) + sp_knot_moveto(knots[i], *_center); } } -void Inkscape::SelTrans::_showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num, - gchar const *even_tip, gchar const *odd_tip) +void Inkscape::SelTrans::_makeHandles() { - g_return_if_fail( !_empty ); - - for (int i = 0; i < num; i++) { - if (knot[i] == NULL) { - knot[i] = sp_knot_new(_desktop, i % 2 ? even_tip : odd_tip); - - knot[i]->setShape (SP_CTRL_SHAPE_BITMAP); - knot[i]->setSize (13); - knot[i]->setAnchor (handle[i].anchor); - knot[i]->setMode (SP_CTRL_MODE_XOR); - knot[i]->setFill(0x000000ff, 0x00ff6600, 0x00ff6600); // inversion, green, green - knot[i]->setStroke(0x000000ff, 0x000000ff, 0x000000ff); // inversion - knot[i]->setPixbuf(handles[handle[i].control]); - sp_knot_update_ctrl(knot[i]); - - g_signal_connect(G_OBJECT(knot[i]), "request", - G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &handle[i]); - g_signal_connect(G_OBJECT(knot[i]), "moved", - G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &handle[i]); - g_signal_connect(G_OBJECT(knot[i]), "grabbed", - G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &handle[i]); - g_signal_connect(G_OBJECT(knot[i]), "ungrabbed", - G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &handle[i]); - g_signal_connect(G_OBJECT(knot[i]), "event", G_CALLBACK(sp_seltrans_handle_event), (gpointer) &handle[i]); + for (int i = 0; i < NUMHANDS; i++) { + knots[i] = sp_knot_new(_desktop, handtypes[hands[i].type].tip); + + knots[i]->setShape(SP_CTRL_SHAPE_BITMAP); + knots[i]->setSize(13); + knots[i]->setAnchor(hands[i].anchor); + knots[i]->setMode(SP_CTRL_MODE_XOR); + knots[i]->setFill(0x000000ff, 0x00ff6600, 0x00ff6600); // invert+2*green + knots[i]->setStroke(0x000000ff, 0x000000ff, 0x000000ff); // 3*invert + knots[i]->setPixbuf(handles[hands[i].control]); + sp_knot_update_ctrl(knots[i]); + + if( hands[i].type == HANDLE_CENTER ) { + _center_handle = i; + knots[i]->setFill(0x00000000, 0x00000000, 0x00000000); + knots[i]->setStroke(0x000000ff, 0xff0000b0, 0xff0000b0); } - sp_knot_show(knot[i]); - - Geom::Point const handle_pt(handle[i].x, handle[i].y); - // shouldn't have nullary bbox, but knots - g_assert(_bbox); - Geom::Point p( _bbox->min() - + ( _bbox->dimensions() - * Geom::Scale(handle_pt) ) ); - sp_knot_moveto(knot[i], p); + g_signal_connect(G_OBJECT(knots[i]), "request", + G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &hands[i]); + g_signal_connect(G_OBJECT(knots[i]), "moved", + G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &hands[i]); + g_signal_connect(G_OBJECT(knots[i]), "grabbed", + G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &hands[i]); + g_signal_connect(G_OBJECT(knots[i]), "ungrabbed", + G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &hands[i]); + g_signal_connect(G_OBJECT(knots[i]), "clicked", + G_CALLBACK(sp_sel_trans_handle_click), (gpointer) &hands[i]); + g_signal_connect(G_OBJECT(knots[i]), "event", + G_CALLBACK(sp_sel_trans_handle_event), (gpointer) &hands[i]); } } @@ -758,8 +702,8 @@ static void sp_sel_trans_handle_click(SPKnot *knot, guint state, gpointer data) void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHandle const &handle) { - switch (handle.anchor) { - case SP_ANCHOR_CENTER: + switch (handle.type) { + case HANDLE_CENTER: if (state & GDK_SHIFT_MASK) { // Unset the center position for all selected items for (GSList const *l = _desktop->selection->itemList(); l; l = l->next) { @@ -780,8 +724,8 @@ void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHa void Inkscape::SelTrans::handleGrab(SPKnot *knot, guint /*state*/, SPSelTransHandle const &handle) { - switch (handle.anchor) { - case SP_ANCHOR_CENTER: + switch (handle.type) { + case HANDLE_CENTER: g_object_set(G_OBJECT(_grip), "shape", SP_CTRL_SHAPE_BITMAP, "size", 13.0, @@ -795,7 +739,6 @@ void Inkscape::SelTrans::handleGrab(SPKnot *knot, guint /*state*/, SPSelTransHan NULL); sp_canvas_item_show(_norm); sp_canvas_item_show(_grip); - break; } @@ -816,21 +759,35 @@ void Inkscape::SelTrans::handleNewEvent(SPKnot *knot, Geom::Point *position, gui return; } } - - handle.action(this, handle, *position, state); + switch (handle.type) { + case HANDLE_SCALE: + scale(*position, state); + break; + case HANDLE_STRETCH: + stretch(handle, *position, state); + break; + case HANDLE_SKEW: + skew(handle, *position, state); + break; + case HANDLE_ROTATE: + rotate(*position, state); + break; + case HANDLE_CENTER: + setCenter(*position); + break; + } } gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle) { - if (!SP_KNOT_IS_GRABBED(knot)) { + if (!SP_KNOT_IS_GRABBED(knot)) return TRUE; - } // When holding shift while rotating or skewing, the transformation will be // relative to the point opposite of the handle; otherwise it will be relative // to the center as set for the selection - if ((!(state & GDK_SHIFT_MASK) == !(_state == STATE_ROTATE)) && (&handle != &handle_center)) { + if ((!(state & GDK_SHIFT_MASK) == !(_state == STATE_ROTATE)) && (handle.type != HANDLE_CENTER)) { _origin = _opposite; _origin_for_bboxpoints = _opposite_for_bboxpoints; _origin_for_specpoints = _opposite_for_specpoints; @@ -842,10 +799,10 @@ gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, Geom::Point *position, // FIXME return TRUE; } - if (handle.request(this, handle, *position, state)) { + if (request(handle, *position, state)) { sp_knot_set_position(knot, *position, state); SP_CTRL(_grip)->moveto(*position); - if (&handle == &handle_center) { + if (handle.type == HANDLE_CENTER) { SP_CTRL(_norm)->moveto(*position); } else { SP_CTRL(_norm)->moveto(_origin); @@ -908,36 +865,6 @@ static double sign(double const x) : 1 ); } -gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, Geom::Point &pt, guint state) -{ - return seltrans->scaleRequest(pt, state); -} - -gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &pt, guint state) -{ - return seltrans->stretchRequest(handle, pt, state); -} - -gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, Geom::Point &pt, guint state) -{ - return seltrans->skewRequest(handle, pt, state); -} - -gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, Geom::Point &pt, guint state) -{ - return seltrans->rotateRequest(pt, state); -} - -gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, Geom::Point &pt, guint state) -{ - return seltrans->centerRequest(pt, state); -} - gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) { @@ -1117,6 +1044,24 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom return TRUE; } +gboolean Inkscape::SelTrans::request(SPSelTransHandle const &handle, Geom::Point &pt, guint state) +{ + // These _should_ be in the handstype somewhere instead + switch (handle.type) { + case HANDLE_SCALE: + return scaleRequest(pt, state); + case HANDLE_STRETCH: + return stretchRequest(handle, pt, state); + case HANDLE_SKEW: + return skewRequest(handle, pt, state); + case HANDLE_ROTATE: + return rotateRequest(pt, state); + case HANDLE_CENTER: + return centerRequest(pt, state); + } + return FALSE; +} + gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state) { /* When skewing (or rotating): @@ -1347,25 +1292,7 @@ gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state) * */ -void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &pt, guint state) -{ - seltrans->stretch(handle, pt, state); -} - -void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint state) -{ - seltrans->scale(pt, state); -} -void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &pt, guint state) -{ - seltrans->skew(handle, pt, state); -} - -void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint state) -{ - seltrans->rotate(pt, state); -} void Inkscape::SelTrans::stretch(SPSelTransHandle const &/*handle*/, Geom::Point &/*pt*/, guint /*state*/) { @@ -1387,12 +1314,6 @@ void Inkscape::SelTrans::rotate(Geom::Point &/*pt*/, guint /*state*/) transform(_relative_affine, _origin); } -void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint /*state*/) -{ - seltrans->setCenter(pt); -} - - void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) { SnapManager &m = _desktop->namedview->snap_manager; diff --git a/src/seltrans.h b/src/seltrans.h index 10860f58f..9cf4a7aaf 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -25,6 +25,7 @@ #include "message-context.h" #include #include "sp-item.h" +#include "seltrans-handles.h" struct SPKnot; class SPDesktop; @@ -64,6 +65,7 @@ public: void scale(Geom::Point &pt, guint state); void skew(SPSelTransHandle const &handle, Geom::Point &pt, guint state); void rotate(Geom::Point &pt, guint state); + gboolean request(SPSelTransHandle const &handle, Geom::Point &pt, guint state); gboolean scaleRequest(Geom::Point &pt, guint state); gboolean stretchRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); gboolean skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); @@ -91,7 +93,7 @@ public: return _grabbed; } bool centerIsVisible() { - return ( _chandle && SP_KNOT_IS_VISIBLE (_chandle) ); + return ( _center_handle && SP_KNOT_IS_VISIBLE (knots[_center_handle]) ); } void getNextClosestPoint(bool reverse); @@ -115,8 +117,8 @@ private: void _selChanged(Inkscape::Selection *selection); void _selModified(Inkscape::Selection *selection, guint flags); void _boundingBoxPrefsChanged(int prefs_bbox); - void _showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num, - gchar const *even_tip, gchar const *odd_tip); + void _makeHandles(); + void _showHandles(SPSelTransType type); Geom::Point _getGeomHandlePos(Geom::Point const &visual_handle_pos); Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale); Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale); @@ -176,10 +178,9 @@ private: boost::optional _center; bool _center_is_set; ///< we've already set _center, no need to reread it from items + int _center_handle; - SPKnot *_shandle[8]; - SPKnot *_rhandle[8]; - SPKnot *_chandle; + SPKnot *knots[27]; // Only some as shown at any time SPCanvasItem *_norm; SPCanvasItem *_grip; SPCtrlLine *_l[4]; -- cgit v1.2.3 From 419d9398abf7b8bae74548d5b2bbd8554b36a9b3 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 3 Jul 2013 12:59:04 -0400 Subject: Make handle colour a configurable property. (bzr r12401) --- src/seltrans-handles.cpp | 13 +++++++------ src/seltrans-handles.h | 4 ++++ src/seltrans.cpp | 13 ++++--------- src/seltrans.h | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/seltrans-handles.cpp b/src/seltrans-handles.cpp index cc11125f6..bacb1301e 100644 --- a/src/seltrans-handles.cpp +++ b/src/seltrans-handles.cpp @@ -6,14 +6,16 @@ #endif SPSelTransTypeInfo const handtypes[] = { - {N_("Squeeze or stretch selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, - {N_("Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, - {N_("Skew selection; with Ctrl to snap angle; with Shift to skew around the opposite side") }, - {N_("Rotate selection; with Ctrl to snap angle; with Shift to rotate around the opposite corner") }, - {N_("Center of rotation and skewing: drag to reposition; scaling with Shift also uses this center") } + { DEF_COLOR, N_("Squeeze or stretch selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, + { DEF_COLOR, N_("Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center") }, + { DEF_COLOR, N_("Skew selection; with Ctrl to snap angle; with Shift to skew around the opposite side") }, + { DEF_COLOR, N_("Rotate selection; with Ctrl to snap angle; with Shift to rotate around the opposite corner") }, + { CEN_COLOR, N_("Center of rotation and skewing: drag to reposition; scaling with Shift also uses this center") } }; SPSelTransHandle const hands[] = { +//center handle will be 0 so we can reference it quickly. + {HANDLE_CENTER, SP_ANCHOR_CENTER, GDK_CROSSHAIR, 12, 0.5, 0.5}, //handle-type anchor cursor control x y {HANDLE_STRETCH, SP_ANCHOR_S, GDK_TOP_SIDE, 3, 0.5, 1}, {HANDLE_STRETCH, SP_ANCHOR_W, GDK_RIGHT_SIDE, 2, 1, 0.5}, @@ -31,7 +33,6 @@ SPSelTransHandle const hands[] = { {HANDLE_ROTATE, SP_ANCHOR_SW, GDK_EXCHANGE, 6, 1, 1}, {HANDLE_ROTATE, SP_ANCHOR_NW, GDK_EXCHANGE, 8, 1, 0}, {HANDLE_ROTATE, SP_ANCHOR_NE, GDK_EXCHANGE, 10, 0, 0}, - {HANDLE_CENTER, SP_ANCHOR_CENTER, GDK_CROSSHAIR, 12, 0.5, 0.5} }; /* diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index ef285392b..5c3fdd269 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -21,6 +21,9 @@ namespace Inkscape class SelTrans; } +guint32 const DEF_COLOR[] = { 0xff, 0xff6600, 0xff6600, 0xff, 0xff, 0xff }; +guint32 const CEN_COLOR[] = { 0x0, 0x0, 0x0, 0xff, 0xff0000b0, 0xff0000b0 }; + enum SPSelTransType { HANDLE_STRETCH, HANDLE_SCALE, @@ -30,6 +33,7 @@ enum SPSelTransType { }; struct SPSelTransTypeInfo { + uint const *color; gchar const *tip; }; // One per handle type in order diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 016eba816..33bfe3e4a 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -635,23 +635,18 @@ void Inkscape::SelTrans::_showHandles(SPSelTransType type) void Inkscape::SelTrans::_makeHandles() { for (int i = 0; i < NUMHANDS; i++) { - knots[i] = sp_knot_new(_desktop, handtypes[hands[i].type].tip); + SPSelTransTypeInfo info = handtypes[hands[i].type]; + knots[i] = sp_knot_new(_desktop, info.tip); knots[i]->setShape(SP_CTRL_SHAPE_BITMAP); knots[i]->setSize(13); knots[i]->setAnchor(hands[i].anchor); knots[i]->setMode(SP_CTRL_MODE_XOR); - knots[i]->setFill(0x000000ff, 0x00ff6600, 0x00ff6600); // invert+2*green - knots[i]->setStroke(0x000000ff, 0x000000ff, 0x000000ff); // 3*invert + knots[i]->setFill(info.color[0], info.color[1], info.color[2]); + knots[i]->setStroke(info.color[3], info.color[4], info.color[5]); knots[i]->setPixbuf(handles[hands[i].control]); sp_knot_update_ctrl(knots[i]); - if( hands[i].type == HANDLE_CENTER ) { - _center_handle = i; - knots[i]->setFill(0x00000000, 0x00000000, 0x00000000); - knots[i]->setStroke(0x000000ff, 0xff0000b0, 0xff0000b0); - } - g_signal_connect(G_OBJECT(knots[i]), "request", G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &hands[i]); g_signal_connect(G_OBJECT(knots[i]), "moved", diff --git a/src/seltrans.h b/src/seltrans.h index 9cf4a7aaf..667dedaf0 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -93,7 +93,7 @@ public: return _grabbed; } bool centerIsVisible() { - return ( _center_handle && SP_KNOT_IS_VISIBLE (knots[_center_handle]) ); + return ( SP_KNOT_IS_VISIBLE (knots[0]) ); } void getNextClosestPoint(bool reverse); -- cgit v1.2.3 From 09ce234c1fc367a2607936e6cf106cb24c60e94f Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Wed, 3 Jul 2013 20:06:11 +0100 Subject: Modified dbus interface so that it works in console mode (--dbus-listen) Modified action context setup so that in console mode, when a document is added to the main inkscape app instance, it gets a selection model and layer model automatically set up for it Made a couple more verbs work in console mode (bzr r12387.1.4) --- src/extension/dbus/application-interface.cpp | 9 + src/extension/dbus/application-interface.h | 4 + src/extension/dbus/application-interface.xml | 18 +- src/extension/dbus/dbus-init.cpp | 40 ++- src/extension/dbus/dbus-init.h | 5 +- src/extension/dbus/document-interface.cpp | 361 +++++++++++++++------------ src/extension/dbus/document-interface.h | 10 +- src/file.cpp | 33 ++- src/file.h | 2 +- src/helper/action-context.cpp | 10 + src/helper/action-context.h | 11 + src/helper/action.cpp | 17 +- src/helper/action.h | 2 + src/inkscape.cpp | 54 ++++ src/inkscape.h | 11 + src/main.cpp | 53 +++- src/select-context.cpp | 32 +-- src/selection-chemistry.cpp | 37 +-- src/selection-chemistry.h | 6 +- src/verbs.cpp | 74 ++++-- 20 files changed, 536 insertions(+), 253 deletions(-) (limited to 'src') diff --git a/src/extension/dbus/application-interface.cpp b/src/extension/dbus/application-interface.cpp index 8ee7bd12f..399e1b244 100644 --- a/src/extension/dbus/application-interface.cpp +++ b/src/extension/dbus/application-interface.cpp @@ -18,6 +18,7 @@ #include "application-interface.h" #include #include "dbus-init.h" +#include "file.h" G_DEFINE_TYPE(ApplicationInterface, application_interface, G_TYPE_OBJECT) @@ -131,6 +132,7 @@ application_interface_desktop_close_all (ApplicationInterface *object, gboolean application_interface_exit (ApplicationInterface *object, GError **error) { + sp_file_exit(); return TRUE; } @@ -144,6 +146,13 @@ gchar* application_interface_document_new (ApplicationInterface *object, return (gchar*)Inkscape::Extension::Dbus::init_document(); } +gchar* +application_interface_get_active_document(ApplicationInterface *object, + GError **error) +{ + return (gchar*)Inkscape::Extension::Dbus::init_active_document(); +} + gchar** application_interface_get_document_list (ApplicationInterface *object) { diff --git a/src/extension/dbus/application-interface.h b/src/extension/dbus/application-interface.h index 88219a6b0..b01fee912 100644 --- a/src/extension/dbus/application-interface.h +++ b/src/extension/dbus/application-interface.h @@ -97,6 +97,10 @@ gchar* application_interface_document_new (ApplicationInterface *object, GError **error); +gchar* +application_interface_get_active_document(ApplicationInterface *object, + GError **error); + gchar** application_interface_get_document_list (ApplicationInterface *object); diff --git a/src/extension/dbus/application-interface.xml b/src/extension/dbus/application-interface.xml index ee2c4837b..4185c7e53 100644 --- a/src/extension/dbus/application-interface.xml +++ b/src/extension/dbus/application-interface.xml @@ -32,7 +32,7 @@ - Create a new document interface and return it's location. + Create a new document interface and return its location. @@ -59,7 +59,7 @@ - Exit Inkscape without saving. Fairly straightforward. + Exit Inkscape without saving (in GUI mode). Fairly straightforward. @@ -76,6 +76,20 @@ Originally, there were going to be two interfaces. A desktop and a document. Desktops would be used when the user wanted to see the result of their code and documents would be used when less overhead was desired. Unfortunately as more and more of the code can to rely on the desktop and it's associated support code (including selections and verbs) the document interface was looking more and more limited. Ultimately I decided to just go with the desktop interface since I didn't have a compelling reason for keeping the other one and having two similar interfaces could be very confusing. The desktop interface inherited the document name because I believe it's more familiar to people. Perhaps it would be best to have an option as to whether or not to create a window and fail with a good error message when they call a function that requires one. Or have a second interface for different use cases but have it be completely different, rather than a subset of the first if there are use cases that support it. + UPDATE: 3rd July 2013, Eric Greveson: After having done some initial work to attempt to decouple Inkscape "verbs" from desktops, it is now possible to run a limited subset of actions in command-line mode (with a selection model and document, but no desktop). I believe that the "single document interface" approach, with some functions that may require a GUI, is the better path, and so document interfaces without a desktop are now possible. Most functions still require the desktop to work, though, with the notable exception of selection methods and Boolean operations. + + + + + + + + This string can be used to connect to the current active document. + + + + + Get the location of the current active document (e.g. when running in console mode, when desktops are not available). diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index 9ff6897e5..96d72c0f6 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -108,7 +108,11 @@ init_document (void) { doc = SPDocument::createNewDoc(NULL, 1, TRUE); std::string name("/org/inkscape/"); - name.append(doc->getName()); + // This only works because a new document's name happens to contain + // only valid DBus characters [A-Z][a-z][0-9]_ + // TODO: use the document->serial() instead, like below, and similar to + // how desktops work? + name.append(doc->getName()); std::replace(name.begin(), name.end(), ' ', '_'); connection = dbus_get_connection(); @@ -122,6 +126,38 @@ init_document (void) { return strdup(name.c_str()); } //init_document +gchar * +init_active_document() +{ + SPDocument *doc = inkscape_active_document(); + if (!doc) { + return NULL; + } + + // Document name is not suitable for DBus name, as it might contain invalid chars + std::string name("/org/inkscape/document_"); + std::stringstream ss; + ss << doc->serial(); + name.append(ss.str()); + + DBusGConnection *connection = dbus_get_connection(); + DBusGProxy *proxy = dbus_get_proxy(connection); + + // Has the active document already been registered? + if (!dbus_g_connection_lookup_g_object(connection, name.c_str())) { + // No - register it + DocumentInterface *obj = (DocumentInterface*) dbus_register_object (connection, + proxy, + TYPE_DOCUMENT_INTERFACE, + &dbus_glib_document_interface_object_info, + name.c_str()); + + // Set the document info for this interface + obj->context = inkscape_active_action_context(); + } + return strdup(name.c_str()); +} + gchar * dbus_init_desktop_interface (SPDesktop * dt) { @@ -142,7 +178,7 @@ dbus_init_desktop_interface (SPDesktop * dt) obj = (DocumentInterface*) dbus_register_object (connection, proxy, TYPE_DOCUMENT_INTERFACE, &dbus_glib_document_interface_object_info, name.c_str()); - obj->desk = dt; + obj->context = Inkscape::ActionContext(dt); obj->updates = TRUE; dt->dbus_document_interface=obj; return strdup(name.c_str()); diff --git a/src/extension/dbus/dbus-init.h b/src/extension/dbus/dbus-init.h index 025011f28..486e55b86 100644 --- a/src/extension/dbus/dbus-init.h +++ b/src/extension/dbus/dbus-init.h @@ -10,8 +10,7 @@ #ifndef INKSCAPE_EXTENSION_DBUS_INIT_H__ #define INKSCAPE_EXTENSION_DBUS_INIT_H__ -#include "desktop.h" - +class SPDesktop; namespace Inkscape { namespace Extension { @@ -23,6 +22,8 @@ void init (void); gchar * init_document (void); +gchar * init_active_document (); + gchar * init_desktop (void); gchar * dbus_init_desktop_interface (SPDesktop * dt); diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index bdf1fa98c..f0cc71de1 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -20,6 +20,7 @@ #include "application-interface.h" #include #include +#include "desktop.h" #include "desktop-handles.h" //sp_desktop_document() #include "desktop-style.h" //sp_desktop_get_style #include "display/canvas-text.h" //text @@ -33,6 +34,7 @@ #include "helper/action-context.h" #include "inkscape.h" //inkscape_find_desktop_by_dkey, activate desktops #include "layer-fns.h" //LPOS_BELOW +#include "layer-model.h" #include "live_effects/parameter/text.h" //text #include "print.h" //IO #include "selection-chemistry.h"// lots of selection functions @@ -92,12 +94,12 @@ * place to adjust things. */ Inkscape::XML::Node * -get_repr_by_name (SPDesktop *desk, gchar *name, GError **error) +get_repr_by_name (SPDocument *doc, gchar *name, GError **error) { /* ALTERNATIVE (is this faster if only repr is needed?) Inkscape::XML::Node *node = sp_repr_lookup_name((doc->root)->repr, name); */ - SPObject * obj = sp_desktop_document(desk)->getObjectById(name); + SPObject * obj = doc->getObjectById(name); if (!obj) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OBJECT, "Object '%s' not found in document.", name); @@ -110,9 +112,9 @@ get_repr_by_name (SPDesktop *desk, gchar *name, GError **error) * See comment for get_repr_by_name, above. */ SPObject * -get_object_by_name (SPDesktop *desk, gchar *name, GError **error) +get_object_by_name (SPDocument *doc, gchar *name, GError **error) { - SPObject * obj = sp_desktop_document(desk)->getObjectById(name); + SPObject * obj = doc->getObjectById(name); if (!obj) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OBJECT, "Object '%s' not found in document.", name); @@ -184,12 +186,11 @@ selection_get_center_y (Inkscape::Selection *sel){ * they might see the selection box flicker if used in a loop. */ const GSList * -selection_swap(SPDesktop *desk, gchar *name, GError **error) +selection_swap(Inkscape::Selection *sel, gchar *name, GError **error) { - Inkscape::Selection *sel = sp_desktop_selection(desk); const GSList *oldsel = g_slist_copy((GSList *)sel->list()); - sel->set(get_object_by_name(desk, name, error)); + sel->set(get_object_by_name(sel->layerModel()->getDocument(), name, error)); return oldsel; } @@ -197,9 +198,8 @@ selection_swap(SPDesktop *desk, gchar *name, GError **error) * See selection_swap, above */ void -selection_restore(SPDesktop *desk, const GSList * oldsel) +selection_restore(Inkscape::Selection *sel, const GSList * oldsel) { - Inkscape::Selection *sel = sp_desktop_selection(desk); sel->setList(oldsel); } @@ -207,9 +207,8 @@ selection_restore(SPDesktop *desk, const GSList * oldsel) * Shortcut for creating a Node. */ Inkscape::XML::Node * -dbus_create_node (SPDesktop *desk, const gchar *type) +dbus_create_node (SPDocument *doc, const gchar *type) { - SPDocument * doc = sp_desktop_document (desk); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); return xml_doc->createElement(type); @@ -224,8 +223,10 @@ dbus_create_node (SPDesktop *desk, const gchar *type) */ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inkscape::XML::Node *newNode, gchar *desc) { - SPCSSAttr *style = sp_desktop_get_style(object->desk, TRUE); - + SPCSSAttr *style = NULL; + if (object->context.getDesktop()) { + style = sp_desktop_get_style(object->context.getDesktop(), TRUE); + } if (style) { Glib::ustring str; sp_repr_css_write_string(style, str); @@ -235,11 +236,11 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks newNode->setAttribute("style", "fill:#0000ff;fill-opacity:1;stroke:#c900b9;stroke-width:0;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none", TRUE); } - object->desk->currentLayer()->appendChildRepr(newNode); - object->desk->currentLayer()->updateRepr(); + object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); + object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); if (object->updates) { - Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), 0, (gchar *)desc); + Inkscape::DocumentUndo::done(object->context.getDocument(), 0, (gchar *)desc); //} else { //document_interface_pause_updates(object, error); } @@ -258,23 +259,22 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks gboolean dbus_call_verb (DocumentInterface *object, int verbid, GError **error) { - SPDesktop *desk2 = object->desk; - desktop_ensure_active (desk2); - - if ( desk2 ) { - Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); - if ( verb ) { - SPAction *action = verb->get_action(Inkscape::ActionContext(desk2)); - if ( action ) { - //if (!object->updates) - //document_interface_pause_updates (object, error); - sp_action_perform( action, NULL ); - if (object->updates) - Inkscape::DocumentUndo::done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip())); - //if (!object->updates) - //document_interface_pause_updates (object, error); - return TRUE; - } + SPDesktop *desk = object->context.getDesktop(); + if ( desk ) { + desktop_ensure_active (desk); + } + Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); + if ( verb ) { + SPAction *action = verb->get_action(object->context); + if ( action ) { + //if (!object->updates) + //document_interface_pause_updates (object, error); + sp_action_perform( action, NULL ); + if (object->updates) + Inkscape::DocumentUndo::done(object->context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + //if (!object->updates) + //document_interface_pause_updates (object, error); + return TRUE; } } g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_VERB, "Verb failed to execute"); @@ -313,7 +313,7 @@ document_interface_class_init (DocumentInterfaceClass *klass) static void document_interface_init (DocumentInterface *object) { - object->desk = NULL; + object->context = Inkscape::ActionContext(); } @@ -331,26 +331,26 @@ document_interface_new (void) gboolean document_interface_delete_all(DocumentInterface *object, GError ** /*error*/) { - sp_edit_clear_all(object->desk); + sp_edit_clear_all(object->context.getSelection()); return TRUE; } gboolean document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error) { - SPDesktop *desk2 = object->desk; - desktop_ensure_active (object->desk); - if ( desk2 ) { - Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid ); - if ( verb ) { - SPAction *action = verb->get_action(Inkscape::ActionContext(desk2)); - if ( action ) { - sp_action_perform( action, NULL ); - if (object->updates) { - Inkscape::DocumentUndo::done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip())); - } - return TRUE; + SPDesktop *desk = object->context.getDesktop(); + if ( desk ) { + desktop_ensure_active (desk); + } + Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid ); + if ( verb ) { + SPAction *action = verb->get_action(object->context); + if ( action ) { + sp_action_perform( action, NULL ); + if (object->updates) { + Inkscape::DocumentUndo::done(object->context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); } + return TRUE; } } g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_VERB, "Verb '%s' failed to execute or was not found.", verbid); @@ -368,7 +368,7 @@ document_interface_rectangle (DocumentInterface *object, int x, int y, { - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:rect"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:rect"); sp_repr_set_int(newNode, "x", x); //could also use newNode->setAttribute() sp_repr_set_int(newNode, "y", y); sp_repr_set_int(newNode, "width", width); @@ -380,7 +380,7 @@ gchar* document_interface_ellipse_center (DocumentInterface *object, int cx, int cy, int rx, int ry, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "arc"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); @@ -395,7 +395,7 @@ document_interface_polygon (DocumentInterface *object, int cx, int cy, GError **error) { gdouble rot = ((rotation / 180.0) * 3.14159265) - ( 3.14159265 / 2.0); - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "true"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -416,7 +416,7 @@ document_interface_star (DocumentInterface *object, int cx, int cy, int r1, int r2, int sides, gdouble rounded, gdouble arg1, gdouble arg2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "false"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -445,7 +445,7 @@ gchar* document_interface_line (DocumentInterface *object, int x, int y, int x2, int y2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); std::stringstream out; // Not sure why this works. out << "m " << x << "," << y << " " << x2 - x << "," << y2 - y; @@ -457,7 +457,7 @@ gchar* document_interface_spiral (DocumentInterface *object, int cx, int cy, int r, int revolutions, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "spiral"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); @@ -478,13 +478,13 @@ gchar* document_interface_text (DocumentInterface *object, int x, int y, gchar *text, GError **error) { - Inkscape::XML::Node *text_node = dbus_create_node(object->desk, "svg:text"); + Inkscape::XML::Node *text_node = dbus_create_node(object->context.getDocument(), "svg:text"); sp_repr_set_int(text_node, "x", x); sp_repr_set_int(text_node, "y", y); //just a workaround so i can get an spitem from the name gchar *name = finish_create_shape (object, error, text_node, (gchar *)"create text"); - SPItem* text_obj=(SPItem* )get_object_by_name(object->desk, name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); sp_te_set_repr_text_multiline(text_obj, text); return name; @@ -497,16 +497,16 @@ document_interface_image (DocumentInterface *object, int x, int y, gchar *filena if (!uri) return FALSE; - Inkscape::XML::Node *newNode = dbus_create_node(object->desk, "svg:image"); + Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:image"); sp_repr_set_int(newNode, "x", x); sp_repr_set_int(newNode, "y", y); newNode->setAttribute("xlink:href", uri); - object->desk->currentLayer()->appendChildRepr(newNode); - object->desk->currentLayer()->updateRepr(); + object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); + object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); if (object->updates) - Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), 0, "Imported bitmap."); + Inkscape::DocumentUndo::done(object->context.getDocument(), 0, "Imported bitmap."); //g_free(uri); return strdup(newNode->attribute("id")); @@ -514,16 +514,16 @@ document_interface_image (DocumentInterface *object, int x, int y, gchar *filena gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** /*error*/) { - SPDocument * doc = sp_desktop_document (object->desk); + SPDocument * doc = object->context.getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *newNode = xml_doc->createElement(type); - object->desk->currentLayer()->appendChildRepr(newNode); - object->desk->currentLayer()->updateRepr(); + object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); + object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); if (object->updates) { - Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), 0, (gchar *)"created empty node"); + Inkscape::DocumentUndo::done(doc, 0, (gchar *)"created empty node"); //} else { //document_interface_pause_updates(object, error); } @@ -537,39 +537,54 @@ gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** gdouble document_interface_document_get_width (DocumentInterface *object) { - return sp_desktop_document(object->desk)->getWidth(); + return object->context.getDocument()->getWidth(); } gdouble document_interface_document_get_height (DocumentInterface *object) { - return sp_desktop_document(object->desk)->getHeight(); + return object->context.getDocument()->getHeight(); } -gchar *document_interface_document_get_css(DocumentInterface *object, GError ** /*error*/) +gchar *document_interface_document_get_css(DocumentInterface *object, GError ** error) { - SPCSSAttr *current = (object->desk)->current; + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document get CSS requires a GUI"); + return NULL; + } + SPCSSAttr *current = desk->current; Glib::ustring str; sp_repr_css_write_string(current, str); return (str.empty() ? NULL : g_strdup (str.c_str())); } gboolean document_interface_document_merge_css(DocumentInterface *object, - gchar *stylestring, GError ** /*error*/) + gchar *stylestring, GError ** error) { + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document merge CSS requires a GUI"); + return FALSE; + } SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(style, stylestring); - sp_desktop_set_style(object->desk, style); + sp_desktop_set_style(desk, style); return TRUE; } gboolean document_interface_document_set_css(DocumentInterface *object, - gchar *stylestring, GError ** /*error*/) + gchar *stylestring, GError ** error) { + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document set CSS requires a GUI"); + return FALSE; + } SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string (style, stylestring); //Memory leak? - object->desk->current = style; + desk->current = style; return TRUE; } @@ -589,19 +604,28 @@ document_interface_document_set_display_area (DocumentInterface *object, double border, GError **error) { - object->desk->set_display_area (x0, + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document set display area requires a GUI"); + return FALSE; + } + desk->set_display_area (x0, y0, x1, y1, border, false); - return TRUE; + return TRUE; } GArray * document_interface_document_get_display_area (DocumentInterface *object) { - Geom::Rect const d = object->desk->get_display_area(); + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + return NULL; + } + Geom::Rect const d = desk->get_display_area(); GArray * dArr = g_array_new (TRUE, TRUE, sizeof(double)); @@ -626,7 +650,7 @@ gboolean document_interface_set_attribute (DocumentInterface *object, char *shape, char *attribute, char *newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->desk, shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(object->context.getDocument(), shape, error); /* ALTERNATIVE (is this faster?) Inkscape::XML::Node *newnode = sp_repr_lookup_name((doc->root)->repr, name); @@ -646,7 +670,7 @@ document_interface_set_int_attribute (DocumentInterface *object, char *shape, char *attribute, int newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->desk, shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (object->context.getDocument(), shape, error); if (!newNode) return FALSE; @@ -660,7 +684,7 @@ document_interface_set_double_attribute (DocumentInterface *object, char *shape, char *attribute, double newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->desk, shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (object->context.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "New value string was empty.")) return FALSE; @@ -675,7 +699,7 @@ gchar * document_interface_get_attribute (DocumentInterface *object, char *shape, char *attribute, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->desk, shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(object->context.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "Attribute name empty.")) return NULL; @@ -689,11 +713,11 @@ gboolean document_interface_move (DocumentInterface *object, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->desk, name, error); + const GSList *oldsel = selection_swap(object->context.getSelection(), name, error); if (!oldsel) return FALSE; - sp_selection_move (object->desk, x, 0 - y); - selection_restore(object->desk, oldsel); + sp_selection_move (object->context.getSelection(), x, 0 - y); + selection_restore(object->context.getSelection(), oldsel); return TRUE; } @@ -701,13 +725,13 @@ gboolean document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->desk, name, error); + const GSList *oldsel = selection_swap(object->context.getSelection(), name, error); if (!oldsel) return FALSE; - Inkscape::Selection * sel = sp_desktop_selection(object->desk); - sp_selection_move (object->desk, x - selection_get_center_x(sel), + Inkscape::Selection * sel = object->context.getSelection(); + sp_selection_move (object->context.getSelection(), x - selection_get_center_x(sel), 0 - (y - selection_get_center_y(sel))); - selection_restore(object->desk, oldsel); + selection_restore(object->context.getSelection(), oldsel); return TRUE; } @@ -715,18 +739,18 @@ gboolean document_interface_object_to_path (DocumentInterface *object, char *shape, GError **error) { - const GSList *oldsel = selection_swap(object->desk, shape, error); + const GSList *oldsel = selection_swap(object->context.getSelection(), shape, error); if (!oldsel) return FALSE; dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); - selection_restore(object->desk, oldsel); + selection_restore(object->context.getSelection(), oldsel); return TRUE; } gchar * document_interface_get_path (DocumentInterface *object, char *pathname, GError **error) { - Inkscape::XML::Node *node = get_repr_by_name(object->desk, pathname, error); + Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), pathname, error); if (!node) return NULL; @@ -763,7 +787,7 @@ document_interface_modify_css (DocumentInterface *object, gchar *shape, { // Doesn't like non-variable strings for some reason. gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->desk, shape, error); + Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), shape, error); if (!dbus_check_string (cssattrb, error, "Attribute string empty.")) return FALSE; @@ -784,7 +808,7 @@ document_interface_merge_css (DocumentInterface *object, gchar *shape, { gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->desk, shape, error); + Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), shape, error); if (!dbus_check_string (stylestring, error, "Style string empty.")) return FALSE; @@ -830,12 +854,12 @@ gboolean document_interface_move_to_layer (DocumentInterface *object, gchar *shape, gchar *layerstr, GError **error) { - const GSList *oldsel = selection_swap(object->desk, shape, error); + const GSList *oldsel = selection_swap(object->context.getSelection(), shape, error); if (!oldsel) return FALSE; document_interface_selection_move_to_layer(object, layerstr, error); - selection_restore(object->desk, oldsel); + selection_restore(object->context.getSelection(), oldsel); return TRUE; } @@ -843,7 +867,7 @@ GArray *document_interface_get_node_coordinates(DocumentInterface * /*object*/, { //FIXME: Needs lot's of work. /* - Inkscape::XML::Node *shapenode = get_repr_by_name (object->desk, shape, error); + Inkscape::XML::Node *shapenode = get_repr_by_name (object->context.getDocument(), shape, error); if (shapenode == NULL || shapenode->attribute("d") == NULL) { return FALSE; } @@ -861,7 +885,7 @@ gboolean document_interface_set_text (DocumentInterface *object, gchar *name, gchar *text, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->desk, name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); //TODO verify object type if (!text_obj) return FALSE; @@ -878,7 +902,7 @@ document_interface_text_apply_style (DocumentInterface *object, gchar *name, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->desk, name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); //void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPCSSAttr const *css) //TODO verify object type @@ -907,7 +931,7 @@ document_interface_text_apply_style (DocumentInterface *object, gchar *name, gboolean document_interface_save (DocumentInterface *object, GError **error) { - SPDocument * doc = sp_desktop_document(object->desk); + SPDocument * doc = object->context.getDocument(); printf("1: %s\n2: %s\n3: %s\n", doc->getURI(), doc->getBase(), doc->getName()); if (doc->getURI()) return document_interface_save_as (object, doc->getURI(), error); @@ -917,11 +941,14 @@ document_interface_save (DocumentInterface *object, GError **error) gboolean document_interface_load(DocumentInterface *object, gchar *filename, GError ** /*error*/) { - desktop_ensure_active(object->desk); + SPDesktop *desk = object->context.getDesktop(); + if (desk) { + desktop_ensure_active(desk); + } const Glib::ustring file(filename); sp_file_open(file, NULL, TRUE, TRUE); if (object->updates) { - Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), SP_VERB_FILE_OPEN, "Opened File"); + Inkscape::DocumentUndo::done(object->context.getDocument(), SP_VERB_FILE_OPEN, "Opened File"); } return TRUE; } @@ -930,9 +957,12 @@ gchar * document_interface_import (DocumentInterface *object, gchar *filename, GError **error) { - desktop_ensure_active (object->desk); + SPDesktop *desk = object->context.getDesktop(); + if (desk) { + desktop_ensure_active(desk); + } const Glib::ustring file(filename); - SPDocument * doc = sp_desktop_document(object->desk); + SPDocument * doc = object->context.getDocument(); SPObject *new_obj = NULL; new_obj = file_import(doc, file, NULL); @@ -943,7 +973,7 @@ gboolean document_interface_save_as (DocumentInterface *object, const gchar *filename, GError **error) { - SPDocument * doc = sp_desktop_document(object->desk); + SPDocument * doc = object->context.getDocument(); #ifdef WITH_GNOME_VFS const Glib::ustring file(filename); return file_save_remote(doc, file, NULL, TRUE, TRUE); @@ -967,7 +997,7 @@ document_interface_save_as (DocumentInterface *object, gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError ** /*error*/) { - SPDocument * doc = sp_desktop_document(object->desk); + SPDocument * doc = object->context.getDocument(); if (doc) { doc->modified_since_save = FALSE; } @@ -978,7 +1008,7 @@ gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError gboolean document_interface_print_to_file (DocumentInterface *object, GError **error) { - SPDocument * doc = sp_desktop_document(object->desk); + SPDocument * doc = object->context.getDocument(); sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf")); return TRUE; @@ -1021,39 +1051,55 @@ document_interface_redo (DocumentInterface *object, GError **error) Need to make sure it plays well with verbs because they are used so much. ****************************************************************************/ -void document_interface_pause_updates(DocumentInterface *object, GError ** /*error*/) +void document_interface_pause_updates(DocumentInterface *object, GError ** error) { + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document pause updates requires a GUI"); + return; + } object->updates = FALSE; - object->desk->canvas->drawing_disabled = 1; - //object->desk->canvas->need_redraw = 0; - //object->desk->canvas->need_repick = 0; - //sp_desktop_document(object->desk)->root->uflags = FALSE; - //sp_desktop_document(object->desk)->root->mflags = FALSE; + desk->canvas->drawing_disabled = 1; + //desk->canvas->need_redraw = 0; + //desk->canvas->need_repick = 0; + //object->context.getDocument()->root->uflags = FALSE; + //object->context.getDocument()->root->mflags = FALSE; } -void document_interface_resume_updates(DocumentInterface *object, GError ** /*error*/) +void document_interface_resume_updates(DocumentInterface *object, GError ** error) { + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document resume updates requires a GUI"); + return; + } object->updates = TRUE; - object->desk->canvas->drawing_disabled = 0; - //object->desk->canvas->need_redraw = 1; - //object->desk->canvas->need_repick = 1; - //sp_desktop_document(object->desk)->root->uflags = TRUE; - //sp_desktop_document(object->desk)->root->mflags = TRUE; - //sp_desktop_document(object->desk)->_updateDocument(); + desk->canvas->drawing_disabled = 0; + //desk->canvas->need_redraw = 1; + //desk->canvas->need_repick = 1; + //object->context.getDocument()->root->uflags = TRUE; + //object->context.getDocument()->root->mflags = TRUE; + //object->context.getDocument()->_updateDocument(); //FIXME: use better verb than rect. - Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions"); + Inkscape::DocumentUndo::done(object->context.getDocument(), SP_VERB_CONTEXT_RECT, "Multiple actions"); } -void document_interface_update(DocumentInterface *object, GError ** /*error*/) +void document_interface_update(DocumentInterface *object, GError ** error) { - sp_desktop_document(object->desk)->getRoot()->uflags = TRUE; - sp_desktop_document(object->desk)->getRoot()->mflags = TRUE; - object->desk->enableInteraction(); - sp_desktop_document(object->desk)->_updateDocument(); - object->desk->disableInteraction(); - sp_desktop_document(object->desk)->getRoot()->uflags = FALSE; - sp_desktop_document(object->desk)->getRoot()->mflags = FALSE; - //Inkscape::DocumentUndo::done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions"); + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document update requires a GUI"); + return; + } + SPDocument *doc = object->context.getDocument(); + doc->getRoot()->uflags = TRUE; + doc->getRoot()->mflags = TRUE; + desk->enableInteraction(); + doc->_updateDocument(); + desk->disableInteraction(); + doc->getRoot()->uflags = FALSE; + doc->getRoot()->mflags = FALSE; + //Inkscape::DocumentUndo::done(doc, SP_VERB_CONTEXT_RECT, "Multiple actions"); } /**************************************************************************** @@ -1062,7 +1108,7 @@ void document_interface_update(DocumentInterface *object, GError ** /*error*/) gboolean document_interface_selection_get(DocumentInterface *object, char ***out, GError ** /*error*/) { - Inkscape::Selection * sel = sp_desktop_selection(object->desk); + Inkscape::Selection * sel = object->context.getSelection(); GSList const *oldsel = sel->list(); int size = g_slist_length((GSList *) oldsel); @@ -1082,11 +1128,11 @@ gboolean document_interface_selection_get(DocumentInterface *object, char ***out gboolean document_interface_selection_add (DocumentInterface *object, char *name, GError **error) { - SPObject * obj = get_object_by_name(object->desk, name, error); + SPObject * obj = get_object_by_name(object->context.getDocument(), name, error); if (!obj) return FALSE; - Inkscape::Selection *selection = sp_desktop_selection(object->desk); + Inkscape::Selection *selection = object->context.getSelection(); selection->add(obj); return TRUE; @@ -1105,8 +1151,8 @@ document_interface_selection_add_list (DocumentInterface *object, gboolean document_interface_selection_set(DocumentInterface *object, char *name, GError ** /*error*/) { - SPDocument * doc = sp_desktop_document(object->desk); - Inkscape::Selection *selection = sp_desktop_selection(object->desk); + SPDocument * doc = object->context.getDocument(); + Inkscape::Selection *selection = object->context.getSelection(); selection->set(doc->getObjectById(name)); return TRUE; } @@ -1115,7 +1161,7 @@ gboolean document_interface_selection_set_list (DocumentInterface *object, gchar **names, GError **error) { - sp_desktop_selection(object->desk)->clear(); + object->context.getSelection()->clear(); int i; for (i=0;names[i] != NULL;i++) { document_interface_selection_add(object, names[i], error); @@ -1125,7 +1171,7 @@ document_interface_selection_set_list (DocumentInterface *object, gboolean document_interface_selection_rotate(DocumentInterface *object, int angle, GError ** /*error*/) { - Inkscape::Selection *selection = sp_desktop_selection(object->desk); + Inkscape::Selection *selection = object->context.getSelection(); sp_selection_rotate(selection, angle); return TRUE; } @@ -1139,7 +1185,7 @@ document_interface_selection_delete (DocumentInterface *object, GError **error) gboolean document_interface_selection_clear(DocumentInterface *object, GError ** /*error*/) { - sp_desktop_selection(object->desk)->clear(); + object->context.getSelection()->clear(); return TRUE; } @@ -1205,7 +1251,12 @@ document_interface_selection_copy (DocumentInterface *object, GError **error) gboolean document_interface_selection_paste (DocumentInterface *object, GError **error) { - desktop_ensure_active (object->desk); + SPDesktop *desk = object->context.getDesktop(); + if (!desk) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document selection paste requires a GUI"); + return FALSE; + } + desktop_ensure_active (desk); if (!object->updates) document_interface_pause_updates (object, error); sp_selection_paste (object->desk, TRUE); @@ -1223,7 +1274,7 @@ document_interface_selection_paste (DocumentInterface *object, GError **error) gboolean document_interface_selection_scale(DocumentInterface *object, gdouble grow, GError ** /*error*/) { - Inkscape::Selection *selection = sp_desktop_selection(object->desk); + Inkscape::Selection *selection = object->context.getSelection(); if (!selection) { return FALSE; @@ -1234,13 +1285,13 @@ gboolean document_interface_selection_scale(DocumentInterface *object, gdouble g gboolean document_interface_selection_move(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) { - sp_selection_move(object->desk, x, 0 - y); //switching coordinate systems. + sp_selection_move(object->context.getSelection(), x, 0 - y); //switching coordinate systems. return TRUE; } gboolean document_interface_selection_move_to(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) { - Inkscape::Selection * sel = sp_desktop_selection(object->desk); + Inkscape::Selection * sel = object->context.getSelection(); Geom::OptRect sel_bbox = sel->visualBounds(); if (sel_bbox) { @@ -1257,15 +1308,19 @@ gboolean document_interface_selection_move_to_layer (DocumentInterface *object, gchar *layerstr, GError **error) { - SPDesktop * dt = object->desk; + SPDesktop *dt = object->context.getDesktop(); + if (!dt) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document selection move to layer requires a GUI"); + return FALSE; + } - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = object->context.getSelection(); // check if something is selected if (selection->isEmpty()) return FALSE; - SPObject *next = get_object_by_name(object->desk, layerstr, error); + SPObject *next = get_object_by_name(object->context.getDocument(), layerstr, error); if (!next) return FALSE; @@ -1274,7 +1329,7 @@ document_interface_selection_move_to_layer (DocumentInterface *object, sp_selection_cut(dt); - dt->setCurrentLayer(next); + object->context.getSelection()->layerModel()->setCurrentLayer(next); sp_selection_paste(dt, TRUE); } @@ -1284,7 +1339,7 @@ document_interface_selection_move_to_layer (DocumentInterface *object, GArray * document_interface_selection_get_center (DocumentInterface *object) { - Inkscape::Selection * sel = sp_desktop_selection(object->desk); + Inkscape::Selection * sel = object->context.getSelection(); if (sel) { @@ -1322,8 +1377,8 @@ document_interface_selection_combine (DocumentInterface *object, gchar *cmd, else return NULL; - if (sp_desktop_selection(object->desk)->singleRepr() != NULL) - return g_strdup((sp_desktop_selection(object->desk)->singleRepr())->attribute("id")); + if (object->context.getSelection()->singleRepr() != NULL) + return g_strdup(object->context.getSelection()->singleRepr()->attribute("id")); return NULL; } @@ -1356,9 +1411,9 @@ document_interface_selection_change_level (DocumentInterface *object, gchar *cmd gchar *document_interface_layer_new(DocumentInterface *object, GError ** /*error*/) { - SPDesktop * dt = object->desk; - SPObject *new_layer = Inkscape::create_layer(dt->currentRoot(), dt->currentLayer(), Inkscape::LPOS_BELOW); - dt->setCurrentLayer(new_layer); + Inkscape::LayerModel * layerModel = object->context.getSelection()->layerModel(); + SPObject *new_layer = Inkscape::create_layer(layerModel->currentRoot(), layerModel->currentLayer(), Inkscape::LPOS_BELOW); + layerModel->setCurrentLayer(new_layer); return g_strdup(get_name_from_object(new_layer)); } @@ -1366,12 +1421,12 @@ gboolean document_interface_layer_set (DocumentInterface *object, gchar *layerstr, GError **error) { - SPObject * obj = get_object_by_name (object->desk, layerstr, error); + SPObject * obj = get_object_by_name (object->context.getDocument(), layerstr, error); if (!obj) return FALSE; - object->desk->setCurrentLayer (obj); + object->context.getSelection()->layerModel()->setCurrentLayer (obj); return TRUE; } @@ -1427,7 +1482,7 @@ gboolean dbus_send_ping (SPDesktop* desk, SPItem *item) gboolean document_interface_get_children (DocumentInterface *object, char *name, char ***out, GError **error) { - SPItem* parent=(SPItem* )get_object_by_name(object->desk, name, error); + SPItem* parent=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); GSList const *children = parent->childList(false); @@ -1450,7 +1505,7 @@ document_interface_get_children (DocumentInterface *object, char *name, char ** gchar* document_interface_get_parent (DocumentInterface *object, char *name, GError **error) { - SPItem* node=(SPItem* )get_object_by_name(object->desk, name, error); + SPItem* node=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); SPObject* parent=node->parent; @@ -1462,7 +1517,7 @@ document_interface_get_parent (DocumentInterface *object, char *name, GError ** //just pseudo code gboolean document_interface_get_xpath (DocumentInterface *object, char *xpath_expression, char ***out, GError **error){ - SPDocument * doc = sp_desktop_document (object->desk); + SPDocument * doc = object->context.getDocument(); Inkscape::XML::Document *repr = doc->getReprDoc(); xmlXPathObjectPtr xpathObj; diff --git a/src/extension/dbus/document-interface.h b/src/extension/dbus/document-interface.h index 5fcbb919b..9b8d34dd3 100644 --- a/src/extension/dbus/document-interface.h +++ b/src/extension/dbus/document-interface.h @@ -30,8 +30,12 @@ #undef DBUS_MESSAGE_TYPE_ERROR #undef DBUS_MESSAGE_TYPE_SIGNAL -#include "desktop.h" +#include "helper/action-context.h" +class SPDesktop; +class SPItem; + +// TODO: this define doesn't seem to be used... although the path itself is also hardcoded in dbus-init.cpp #define DBUS_DOCUMENT_INTERFACE_PATH "/org/inkscape/document" #define TYPE_DOCUMENT_INTERFACE (document_interface_get_type ()) @@ -47,8 +51,8 @@ typedef struct _DocumentInterface DocumentInterface; typedef struct _DocumentInterfaceClass DocumentInterfaceClass; struct _DocumentInterface { - GObject parent; - SPDesktop *desk; + GObject parent; + Inkscape::ActionContext context; gboolean updates; }; diff --git a/src/file.cpp b/src/file.cpp index 5b4110253..5007cd901 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -68,6 +68,7 @@ #include "ui/dialog/font-substitution.h" #include +#include #include #include @@ -209,8 +210,13 @@ SPDesktop* sp_file_new_default() void sp_file_exit() { - sp_ui_close_all(); - // no need to call inkscape_exit here; last document being closed will take care of that + if (SP_ACTIVE_DESKTOP == NULL) { + // We must be in console mode + Gtk::Main::quit(); + } else { + sp_ui_close_all(); + // no need to call inkscape_exit here; last document being closed will take care of that + } } @@ -582,24 +588,25 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d /** * Remove unreferenced defs from the defs section of the document. */ -void sp_file_vacuum() +void sp_file_vacuum(SPDocument *doc) { - SPDocument *doc = SP_ACTIVE_DOCUMENT; - unsigned int diff = doc->vacuumDocument(); DocumentUndo::done(doc, SP_VERB_FILE_VACUUM, _("Clean up document")); SPDesktop *dt = SP_ACTIVE_DESKTOP; - if (diff > 0) { - dt->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, - ngettext("Removed %i unused definition in <defs>.", - "Removed %i unused definitions in <defs>.", - diff), - diff); - } else { - dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No unused definitions in <defs>.")); + if (dt != NULL) { + // Show status messages when in GUI mode + if (diff > 0) { + dt->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("Removed %i unused definition in <defs>.", + "Removed %i unused definitions in <defs>.", + diff), + diff); + } else { + dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No unused definitions in <defs>.")); + } } } diff --git a/src/file.h b/src/file.h index fe8ad9af3..eeb4c6fc5 100644 --- a/src/file.h +++ b/src/file.h @@ -200,7 +200,7 @@ void sp_file_print (Gtk::Window& parentWindow); /** * clean unused defs out of file */ -void sp_file_vacuum (); +void sp_file_vacuum (SPDocument *doc); #endif // SEEN_SP_FILE_H diff --git a/src/helper/action-context.cpp b/src/helper/action-context.cpp index c88086f7f..f211d775d 100644 --- a/src/helper/action-context.cpp +++ b/src/helper/action-context.cpp @@ -60,6 +60,16 @@ UI::View::View *ActionContext::getView() const return _view; } +SPDesktop *ActionContext::getDesktop() const +{ + // TODO: this slightly horrible storage of a UI::View::View*, and + // casting to an SPDesktop*, is only done because that's what was + // already the norm in the Inkscape codebase. This seems wrong. Surely + // we should store an SPDesktop* in the first place? Is there a case + // of actions being carried out on a View that is not an SPDesktop? + return static_cast(_view); +} + } // namespace Inkscape /* diff --git a/src/helper/action-context.h b/src/helper/action-context.h index de09f94f4..3a7a19112 100644 --- a/src/helper/action-context.h +++ b/src/helper/action-context.h @@ -12,6 +12,7 @@ #ifndef SEEN_INKSCAPE_ACTION_CONTEXT_H #define SEEN_INKSCAPE_ACTION_CONTEXT_H +class SPDesktop; class SPDocument; namespace Inkscape { @@ -30,6 +31,12 @@ class View; Inkscape::UI::View::View. Actions that do require GUI objects should check to see if the relevant pointers are NULL before attempting to use them. + + TODO: we store a UI::View::View* because that's what the actions and verbs + used to take as parameters in their methods. Why is this? They almost + always seemed to cast straight to an SPDesktop* - so shouldn't we actually + be storing an SPDesktop*? Is there a case where a non-SPDesktop + UI::View::View is used by the actions? ActionContext is designed to be copyable, so it may be used with stack storage if required. */ @@ -60,6 +67,10 @@ public: /** Get the view for the action context. May be NULL. Guaranteed to be NULL if running in console mode. */ UI::View::View *getView() const; + + /** Get the desktop for the action context. May be NULL. Guaranteed to be + NULL if running in console mode. */ + SPDesktop *getDesktop() const; }; } // namespace Inkscape diff --git a/src/helper/action.cpp b/src/helper/action.cpp index 107d0179b..28cb40334 100644 --- a/src/helper/action.cpp +++ b/src/helper/action.cpp @@ -16,6 +16,7 @@ #include "debug/simple-event.h" #include "debug/event-tracker.h" #include "ui/view/view.h" +#include "desktop.h" #include "document.h" #include "helper/action.h" @@ -188,7 +189,7 @@ sp_action_get_selection (SPAction *action) } /** - * Return View associated with the action. + * Return View associated with the action, if any. */ Inkscape::UI::View::View * sp_action_get_view (SPAction *action) @@ -197,6 +198,20 @@ sp_action_get_view (SPAction *action) return action->context.getView(); } +/** + * Return Desktop associated with the action, if any. + */ +SPDesktop * +sp_action_get_desktop (SPAction *action) +{ + // TODO: this slightly horrible storage of a UI::View::View*, and + // casting to an SPDesktop*, is only done because that's what was + // already the norm in the Inkscape codebase. This seems wrong. Surely + // we should store an SPDesktop* in the first place? Is there a case + // of actions being carried out on a View that is not an SPDesktop? + return static_cast(sp_action_get_view(action)); +} + /* Local Variables: mode:c++ diff --git a/src/helper/action.h b/src/helper/action.h index 49816e3c9..1f2de87b4 100644 --- a/src/helper/action.h +++ b/src/helper/action.h @@ -25,6 +25,7 @@ struct SPActionClass; #define SP_ACTION_CLASS(o) (G_TYPE_CHECK_CLASS_CAST((o), SP_TYPE_ACTION, SPActionClass)) #define SP_IS_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_ACTION)) +class SPDesktop; class SPDocument; namespace Inkscape { @@ -78,6 +79,7 @@ void sp_action_set_name(SPAction *action, Glib::ustring const &name); SPDocument *sp_action_get_document(SPAction *action); Inkscape::Selection *sp_action_get_selection(SPAction *action); Inkscape::UI::View::View *sp_action_get_view(SPAction *action); +SPDesktop *sp_action_get_desktop(SPAction *action); #endif diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 125a7176a..2e60ee5ea 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -58,12 +58,14 @@ #include "extension/system.h" #include "inkscape-private.h" #include "io/sys.h" +#include "layer-model.h" #include "message-stack.h" #include "preferences.h" #include "resource-manager.h" #include "selection.h" #include "ui/dialog/debug.h" #include "xml/repr.h" +#include "helper/action-context.h" #include "helper/sp-marshal.h" static Inkscape::Application *inkscape = NULL; @@ -105,10 +107,27 @@ static void inkscape_dispose (GObject *object); static void inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); static void inkscape_deactivate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); +class AppSelectionModel { + Inkscape::LayerModel _layer_model; + Inkscape::Selection *_selection; + +public: + AppSelectionModel(SPDocument *doc) { + _layer_model.setDocument(doc); + // TODO: is this really how we should manage the lifetime of the selection? + // I just copied this from the initialization of the Selection in SPDesktop. + // When and how is it actually released? + _selection = Inkscape::GC::release(new Inkscape::Selection(&_layer_model, NULL)); + } + + Inkscape::Selection *getSelection() const { return _selection; } +}; + struct Inkscape::Application { GObject object; Inkscape::XML::Document *menus; std::map document_set; + std::map selection_models; GSList *desktops; gchar *argv0; gboolean dialogs_toggle; @@ -481,6 +500,7 @@ inkscape_init (SPObject * object) } new (&inkscape->document_set) std::map(); + new (&inkscape->selection_models) std::map(); inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL); inkscape->desktops = NULL; @@ -504,6 +524,7 @@ inkscape_dispose (GObject *object) inkscape->menus = NULL; } + inkscape->selection_models.~map(); inkscape->document_set.~map(); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -1234,6 +1255,14 @@ inkscape_add_document (SPDocument *document) iter->second ++; } } + } else { + // insert succeeded, this document is new. Do we need to create a + // selection model for it, i.e. are we running without a desktop? + if (!inkscape->use_gui) { + // Create layer model and selection model so we can run some verbs without a GUI + g_assert(inkscape->selection_models.find(document) == inkscape->selection_models.end()); + inkscape->selection_models[document] = new AppSelectionModel(document); + } } } @@ -1253,6 +1282,13 @@ inkscape_remove_document (SPDocument *document) if (iter->second < 1) { // this was the last one, remove the pair from list inkscape->document_set.erase (iter); + + // also remove the selection model + std::map::iterator sel_iter = inkscape->selection_models.find(document); + if (sel_iter != inkscape->selection_models.end()) { + inkscape->selection_models.erase(sel_iter); + } + return true; } else { return false; @@ -1312,6 +1348,24 @@ inkscape_active_event_context (void) return NULL; } +Inkscape::ActionContext +inkscape_active_action_context() +{ + if (SP_ACTIVE_DESKTOP) { + return Inkscape::ActionContext(SP_ACTIVE_DESKTOP); + } + + SPDocument *doc = inkscape_active_document(); + if (!doc) { + return Inkscape::ActionContext(); + } + + std::map::iterator sel_iter = inkscape->selection_models.find(doc); + if (sel_iter == inkscape->selection_models.end()) { + return Inkscape::ActionContext(); + } + return Inkscape::ActionContext(sel_iter->second->getSelection()); +} /*##################### diff --git a/src/inkscape.h b/src/inkscape.h index 368c7fa60..cb6ba6a0f 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -20,6 +20,7 @@ class SPDocument; struct SPEventContext; namespace Inkscape { + class ActionContext; struct Application; namespace XML { class Node; @@ -56,6 +57,16 @@ SPDocument * inkscape_active_document (void); #define SP_ACTIVE_DESKTOP inkscape_active_desktop () SPDesktop * inkscape_active_desktop (void); +// More horrible static cling... sorry about this. Should really replace all of +// the static stuff with a single instance of some kind of engine class holding +// all the document / non-GUI stuff, and an optional GUI class that behaves a +// bit like SPDesktop does currently. Then it will be easier to write good code +// that doesn't just expect a GUI all the time (like lots of the app currently +// does). +// Also, while the "active" document / desktop concepts are convenient, they +// appear to have been abused somewhat, further increasing static cling. +Inkscape::ActionContext inkscape_active_action_context(); + bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop); gchar *homedir_path(const char *filename); diff --git a/src/main.cpp b/src/main.cpp index 49ef33fc9..630411dde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -169,6 +169,9 @@ enum { SP_ARG_SHELL, SP_ARG_VERSION, SP_ARG_VACUUM_DEFS, +#ifdef WITH_DBUS + SP_ARG_DBUS_LISTEN, +#endif // WITH_DBUS SP_ARG_VERB_LIST, SP_ARG_VERB, SP_ARG_SELECT, @@ -222,7 +225,9 @@ static gboolean sp_query_all = FALSE; static gchar *sp_query_id = NULL; static gboolean sp_shell = FALSE; static gboolean sp_vacuum_defs = FALSE; - +#ifdef WITH_DBUS +static gboolean sp_dbus_listen = FALSE; +#endif // WITH_DBUS static gchar *sp_export_png_utf8 = NULL; static gchar *sp_export_svg_utf8 = NULL; static gchar *sp_global_printer_utf8 = NULL; @@ -267,6 +272,9 @@ static void resetCommandlineGlobals() { sp_query_all = FALSE; sp_query_id = NULL; sp_vacuum_defs = FALSE; +#ifdef WITH_DBUS + sp_dbus_listen = FALSE; +#endif // WITH_DBUS sp_export_png_utf8 = NULL; sp_export_svg_utf8 = NULL; @@ -473,6 +481,13 @@ struct poptOption options[] = { POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS, N_("Remove unused definitions from the defs section(s) of the document"), NULL}, + +#ifdef WITH_DBUS + {"dbus-listen", 0, + POPT_ARG_NONE, &sp_dbus_listen, SP_ARG_DBUS_LISTEN, + N_("Enter a listening loop for D-Bus messages in console mode"), + NULL}, +#endif // WITH_DBUS {"verb-list", 0, POPT_ARG_NONE, NULL, SP_ARG_VERB_LIST, @@ -731,6 +746,9 @@ main(int argc, char **argv) || !strcmp(argv[i], "-Y") || !strncmp(argv[i], "--query-y", 9) || !strcmp(argv[i], "--vacuum-defs") +#ifdef WITH_DBUS + || !strcmp(argv[i], "--dbus-listen") +#endif // WITH_DBUS || !strcmp(argv[i], "--shell") ) { @@ -1038,6 +1056,17 @@ sp_main_gui(int argc, char const **argv) static int sp_process_file_list(GSList *fl) { int retVal = 0; +#ifdef WITH_DBUS + if (!fl) { + // If we've been asked to listen for D-Bus messages, enter a main loop here + // The main loop may be exited by calling "exit" on the D-Bus application interface. + if (sp_dbus_listen) { + Gtk::Main main_dbus_loop(0, NULL); + main_dbus_loop.run(); + } + } +#endif // WITH_DBUS + while (fl) { const gchar *filename = (gchar *)fl->data; @@ -1070,17 +1099,17 @@ static int sp_process_file_list(GSList *fl) doc->vacuumDocument(); } - bool has_performed_actions = false; - { - // Create layer model and selection model so we can run some verbs without a GUI - Inkscape::LayerModel layer_model; - layer_model.setDocument(doc); - Inkscape::Selection *selection = Inkscape::GC::release(new Inkscape::Selection(&layer_model, NULL)); - - // Execute command-line actions (selections and verbs) using our local models - Inkscape::ActionContext context(selection); - has_performed_actions = Inkscape::CmdLineAction::doList(context); + // Execute command-line actions (selections and verbs) using our local models + bool has_performed_actions = Inkscape::CmdLineAction::doList(inkscape_active_action_context()); + +#ifdef WITH_DBUS + // If we've been asked to listen for D-Bus messages, enter a main loop here + // The main loop may be exited by calling "exit" on the D-Bus application interface. + if (sp_dbus_listen) { + Gtk::Main main_dbus_loop(0, NULL); + main_dbus_loop.run(); } +#endif // WITH_DBUS if (!sp_export_svg && (sp_vacuum_defs || has_performed_actions)) { // save under the name given in the command line @@ -1248,7 +1277,7 @@ int sp_main_console(int argc, char const **argv) int retVal = sp_common_main( argc, argv, &fl ); g_return_val_if_fail(retVal == 0, 1); - if (fl == NULL && !sp_shell) { + if (fl == NULL && !sp_shell && !sp_dbus_listen) { g_print("Nothing to do!\n"); exit(0); } diff --git a/src/select-context.cpp b/src/select-context.cpp index 1dd3b08d7..3df047368 100644 --- a/src/select-context.cpp +++ b/src/select-context.cpp @@ -921,12 +921,12 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) gint mul = 1 + gobble_key_events( get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT(event)) { // alt - if (MOD__SHIFT(event)) sp_selection_move_screen(desktop, mul*-10, 0); // shift - else sp_selection_move_screen(desktop, mul*-1, 0); // no shift + if (MOD__SHIFT(event)) sp_selection_move_screen(sp_desktop_selection(desktop), mul*-10, 0); // shift + else sp_selection_move_screen(sp_desktop_selection(desktop), mul*-1, 0); // no shift } else { // no alt - if (MOD__SHIFT(event)) sp_selection_move(desktop, mul*-10*nudge, 0); // shift - else sp_selection_move(desktop, mul*-nudge, 0); // no shift + if (MOD__SHIFT(event)) sp_selection_move(sp_desktop_selection(desktop), mul*-10*nudge, 0); // shift + else sp_selection_move(sp_desktop_selection(desktop), mul*-nudge, 0); // no shift } ret = TRUE; } @@ -937,12 +937,12 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) gint mul = 1 + gobble_key_events( get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT(event)) { // alt - if (MOD__SHIFT(event)) sp_selection_move_screen(desktop, 0, mul*10); // shift - else sp_selection_move_screen(desktop, 0, mul*1); // no shift + if (MOD__SHIFT(event)) sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*10); // shift + else sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*1); // no shift } else { // no alt - if (MOD__SHIFT(event)) sp_selection_move(desktop, 0, mul*10*nudge); // shift - else sp_selection_move(desktop, 0, mul*nudge); // no shift + if (MOD__SHIFT(event)) sp_selection_move(sp_desktop_selection(desktop), 0, mul*10*nudge); // shift + else sp_selection_move(sp_desktop_selection(desktop), 0, mul*nudge); // no shift } ret = TRUE; } @@ -953,12 +953,12 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) gint mul = 1 + gobble_key_events( get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT(event)) { // alt - if (MOD__SHIFT(event)) sp_selection_move_screen(desktop, mul*10, 0); // shift - else sp_selection_move_screen(desktop, mul*1, 0); // no shift + if (MOD__SHIFT(event)) sp_selection_move_screen(sp_desktop_selection(desktop), mul*10, 0); // shift + else sp_selection_move_screen(sp_desktop_selection(desktop), mul*1, 0); // no shift } else { // no alt - if (MOD__SHIFT(event)) sp_selection_move(desktop, mul*10*nudge, 0); // shift - else sp_selection_move(desktop, mul*nudge, 0); // no shift + if (MOD__SHIFT(event)) sp_selection_move(sp_desktop_selection(desktop), mul*10*nudge, 0); // shift + else sp_selection_move(sp_desktop_selection(desktop), mul*nudge, 0); // no shift } ret = TRUE; } @@ -969,12 +969,12 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) gint mul = 1 + gobble_key_events( get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT(event)) { // alt - if (MOD__SHIFT(event)) sp_selection_move_screen(desktop, 0, mul*-10); // shift - else sp_selection_move_screen(desktop, 0, mul*-1); // no shift + if (MOD__SHIFT(event)) sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-10); // shift + else sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-1); // no shift } else { // no alt - if (MOD__SHIFT(event)) sp_selection_move(desktop, 0, mul*-10*nudge); // shift - else sp_selection_move(desktop, 0, mul*-nudge); // no shift + if (MOD__SHIFT(event)) sp_selection_move(sp_desktop_selection(desktop), 0, mul*-10*nudge); // shift + else sp_selection_move(sp_desktop_selection(desktop), 0, mul*-nudge); // no shift } ret = TRUE; } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 56923859b..591f9d68d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -35,6 +35,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "desktop.h" #include "desktop-style.h" #include "dir-util.h" +#include "layer-model.h" #include "selection.h" #include "tools-switch.h" #include "desktop-handles.h" @@ -521,16 +522,16 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) g_slist_free(newsel); } -void sp_edit_clear_all(SPDesktop *dt) +void sp_edit_clear_all(Inkscape::Selection *selection) { - if (!dt) + if (!selection) return; - SPDocument *doc = sp_desktop_document(dt); - sp_desktop_selection(dt)->clear(); + SPDocument *doc = selection->layerModel()->getDocument(); + selection->clear(); - g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); - GSList *items = sp_item_group_item_list(SP_GROUP(dt->currentLayer())); + g_return_if_fail(SP_IS_GROUP(selection->layerModel()->currentLayer())); + GSList *items = sp_item_group_item_list(SP_GROUP(selection->layerModel()->currentLayer())); while (items) { reinterpret_cast(items->data)->deleteObject(); @@ -2157,49 +2158,49 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) } void -sp_selection_move(SPDesktop *desktop, gdouble dx, gdouble dy) +sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { return; } sp_selection_move_relative(selection, dx, dy); + SPDocument *doc = selection->layerModel()->getDocument(); if (dx == 0) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, + DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically")); } else if (dy == 0) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, + DocumentUndo::maybeDone(doc, "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, _("Move horizontally")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(doc, SP_VERB_CONTEXT_SELECT, _("Move")); } } void -sp_selection_move_screen(SPDesktop *desktop, gdouble dx, gdouble dy) +sp_selection_move_screen(Inkscape::Selection *selection, gdouble dx, gdouble dy) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - if (selection->isEmpty()) { + if (selection->isEmpty() || !selection->desktop()) { return; } // same as sp_selection_move but divide deltas by zoom factor - gdouble const zoom = desktop->current_zoom(); + gdouble const zoom = selection->desktop()->current_zoom(); gdouble const zdx = dx / zoom; gdouble const zdy = dy / zoom; sp_selection_move_relative(selection, zdx, zdy); + SPDocument *doc = selection->layerModel()->getDocument(); if (dx == 0) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, + DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically by pixels")); } else if (dy == 0) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, + DocumentUndo::maybeDone(doc, "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, _("Move horizontally by pixels")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(doc, SP_VERB_CONTEXT_SELECT, _("Move")); } } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 8711a6cdf..f58ede21a 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -53,7 +53,7 @@ namespace Inkscape { void sp_selection_delete(SPDesktop *desktop); void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone = false); -void sp_edit_clear_all(SPDesktop *desktop); +void sp_edit_clear_all(Inkscape::Selection *selection); void sp_edit_select_all(SPDesktop *desktop); void sp_edit_select_all_in_all_layers (SPDesktop *desktop); @@ -122,8 +122,8 @@ void sp_selection_scale (Inkscape::Selection *selection, gdouble grow); void sp_selection_scale_screen (Inkscape::Selection *selection, gdouble grow_pixels); void sp_selection_scale_times (Inkscape::Selection *selection, gdouble times); -void sp_selection_move (SPDesktop *desktop, gdouble dx, gdouble dy); -void sp_selection_move_screen (SPDesktop *desktop, gdouble dx, gdouble dy); +void sp_selection_move (Inkscape::Selection *selection, gdouble dx, gdouble dy); +void sp_selection_move_screen (Inkscape::Selection *selection, gdouble dx, gdouble dy); void sp_selection_item_next (SPDesktop *desktop); void sp_selection_item_prev (SPDesktop *desktop); diff --git a/src/verbs.cpp b/src/verbs.cpp index 979267215..6187cfb4c 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -806,13 +806,28 @@ Verb *Verb::getbyid(gchar const *id) */ void FileVerb::perform(SPAction *action, void *data) { -#if 0 - // These aren't used, but are here to remind people not to use - // the CURRENT_DOCUMENT macros unless they really have to. - SPDocument *current_document = sp_action_get_document(action); -#endif + // Convert verb impls to use this where possible, to reduce static cling + // to macros like SP_ACTIVE_DOCUMENT, which end up enforcing GUI-mode operation + SPDocument *doc = sp_action_get_document(action); + + // We can vacuum defs, or exit, without needing a desktop! + bool handled = true; + switch (reinterpret_cast(data)) { + case SP_VERB_FILE_VACUUM: + sp_file_vacuum(doc); + break; + case SP_VERB_FILE_QUIT: + sp_file_exit(); + break; + default: + handled = false; + break; + } + if (handled) { + return; + } - SPDesktop *desktop = dynamic_cast(sp_action_get_view(action)); + SPDesktop *desktop = sp_action_get_desktop(action); if (desktop == NULL) { show_gui_required_message(action); return; @@ -843,9 +858,6 @@ void FileVerb::perform(SPAction *action, void *data) case SP_VERB_FILE_PRINT: sp_file_print(*parent); break; - case SP_VERB_FILE_VACUUM: - sp_file_vacuum(); - break; case SP_VERB_FILE_IMPORT: sp_file_import(*parent); break; @@ -867,9 +879,6 @@ void FileVerb::perform(SPAction *action, void *data) case SP_VERB_FILE_CLOSE_VIEW: sp_ui_close_view(NULL); break; - case SP_VERB_FILE_QUIT: - sp_file_exit(); - break; default: break; } @@ -882,7 +891,21 @@ void FileVerb::perform(SPAction *action, void *data) */ void EditVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + // We can clear all without a desktop + bool handled = true; + switch (reinterpret_cast(data)) { + case SP_VERB_EDIT_CLEAR_ALL: + sp_edit_clear_all(sp_action_get_selection(action)); + break; + default: + handled = false; + break; + } + if (handled) { + return; + } + + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -976,9 +999,6 @@ void EditVerb::perform(SPAction *action, void *data) case SP_VERB_EDIT_UNSYMBOL: sp_selection_unsymbol(dt); break; - case SP_VERB_EDIT_CLEAR_ALL: - sp_edit_clear_all(dt); - break; case SP_VERB_EDIT_SELECT_ALL: SelectionHelper::selectAll(dt); break; @@ -1041,7 +1061,7 @@ void EditVerb::perform(SPAction *action, void *data) void SelectionVerb::perform(SPAction *action, void *data) { Inkscape::Selection *selection = sp_action_get_selection(action); - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); // Some of these operations have been modified so they work in command-line mode! // In this case, all we need is a selection @@ -1180,7 +1200,7 @@ void SelectionVerb::perform(SPAction *action, void *data) */ void LayerVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); size_t verb = reinterpret_cast(data); if (dt == NULL) { @@ -1435,7 +1455,7 @@ void LayerVerb::perform(SPAction *action, void *data) */ void ObjectVerb::perform( SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -1525,7 +1545,7 @@ void ContextVerb::perform(SPAction *action, void *data) sp_verb_t verb; int vidx; - dt = static_cast(sp_action_get_view(action)); + dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); @@ -1728,7 +1748,7 @@ void ContextVerb::perform(SPAction *action, void *data) */ void TextVerb::perform(SPAction *action, void */*data*/) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -1745,7 +1765,7 @@ void TextVerb::perform(SPAction *action, void */*data*/) */ void ZoomVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -1937,7 +1957,7 @@ void DialogVerb::perform(SPAction *action, void *data) inkscape_dialogs_unhide(); } - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -2053,7 +2073,7 @@ void DialogVerb::perform(SPAction *action, void *data) */ void HelpVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -2092,7 +2112,7 @@ void HelpVerb::perform(SPAction *action, void *data) */ void TutorialVerb::perform(SPAction *action, void *data) { - if (sp_action_get_view(action) == NULL) { + if (sp_action_get_desktop(action) == NULL) { show_gui_required_message(action); return; } @@ -2246,7 +2266,7 @@ SPAction *FitCanvasVerb::make_action(Inkscape::ActionContext const & context) */ void FitCanvasVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; @@ -2316,7 +2336,7 @@ SPAction *LockAndHideVerb::make_action(Inkscape::ActionContext const & context) */ void LockAndHideVerb::perform(SPAction *action, void *data) { - SPDesktop *dt = static_cast(sp_action_get_view(action)); + SPDesktop *dt = sp_action_get_desktop(action); if (dt == NULL) { show_gui_required_message(action); return; -- cgit v1.2.3 From 1c75594f5c37e86dec195ec1975254315ef180e9 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Wed, 3 Jul 2013 23:00:06 +0100 Subject: Changed dbus interface to treat 'division' like other boolops, with a new return type for selection_combine to support this (array of string). This also fixes a bug with not setting the error flag when returning NULL from this method. Refactored some more selection verbs to allow use in no-GUI mode. (bzr r12387.1.5) --- src/extension/dbus/application-interface.cpp | 6 +- src/extension/dbus/document-interface.cpp | 26 +++--- src/extension/dbus/document-interface.h | 9 +-- src/extension/dbus/document-interface.xml | 32 ++------ src/extension/dbus/wrapper/inkscape-dbus-wrapper.c | 18 +---- src/extension/dbus/wrapper/inkscape-dbus-wrapper.h | 6 +- src/interface.cpp | 2 +- src/selection-chemistry.cpp | 94 +++++++++------------- src/selection-chemistry.h | 12 +-- src/verbs.cpp | 37 +++++---- 10 files changed, 94 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/src/extension/dbus/application-interface.cpp b/src/extension/dbus/application-interface.cpp index 399e1b244..1b1dbf0f5 100644 --- a/src/extension/dbus/application-interface.cpp +++ b/src/extension/dbus/application-interface.cpp @@ -150,7 +150,11 @@ gchar* application_interface_get_active_document(ApplicationInterface *object, GError **error) { - return (gchar*)Inkscape::Extension::Dbus::init_active_document(); + gchar *result = (gchar*)Inkscape::Extension::Dbus::init_active_document(); + if (!result) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "No active document"); + } + return result; } gchar** diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index f0cc71de1..87b769e26 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -1222,13 +1222,11 @@ document_interface_selection_invert (DocumentInterface *object, GError **error) gboolean document_interface_selection_group (DocumentInterface *object, GError **error) { - //sp_selection_group (object->desk); return dbus_call_verb (object, SP_VERB_SELECTION_GROUP, error); } gboolean document_interface_selection_ungroup (DocumentInterface *object, GError **error) { - //sp_selection_ungroup (object->desk); return dbus_call_verb (object, SP_VERB_SELECTION_UNGROUP, error); } @@ -1362,8 +1360,8 @@ document_interface_selection_to_path (DocumentInterface *object, GError **error) } -gchar * -document_interface_selection_combine (DocumentInterface *object, gchar *cmd, +gboolean +document_interface_selection_combine (DocumentInterface *object, gchar *cmd, char ***newpaths, GError **error) { if (strcmp(cmd, "union") == 0) @@ -1374,20 +1372,14 @@ document_interface_selection_combine (DocumentInterface *object, gchar *cmd, dbus_call_verb (object, SP_VERB_SELECTION_DIFF, error); else if (strcmp(cmd, "exclusion") == 0) dbus_call_verb (object, SP_VERB_SELECTION_SYMDIFF, error); - else - return NULL; - - if (object->context.getSelection()->singleRepr() != NULL) - return g_strdup(object->context.getSelection()->singleRepr()->attribute("id")); - return NULL; -} - -gboolean -document_interface_selection_divide (DocumentInterface *object, char ***out, GError **error) -{ - dbus_call_verb (object, SP_VERB_SELECTION_CUT, error); + else if (strcmp(cmd, "division") == 0) + dbus_call_verb (object, SP_VERB_SELECTION_CUT, error); + else { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Operation command not recognised"); + return FALSE; + } - return document_interface_selection_get (object, out, error); + return document_interface_selection_get (object, newpaths, error); } gboolean diff --git a/src/extension/dbus/document-interface.h b/src/extension/dbus/document-interface.h index 9b8d34dd3..5eef3d0c0 100644 --- a/src/extension/dbus/document-interface.h +++ b/src/extension/dbus/document-interface.h @@ -363,14 +363,9 @@ document_interface_selection_get_center (DocumentInterface *object); gboolean document_interface_selection_to_path (DocumentInterface *object, GError **error); -gchar * -document_interface_selection_combine (DocumentInterface *object, gchar *cmd, - GError **error); - gboolean -document_interface_selection_divide (DocumentInterface *object, - char ***out, GError **error); - +document_interface_selection_combine (DocumentInterface *object, gchar *cmd, char ***newpaths, + GError **error); gboolean document_interface_selection_change_level (DocumentInterface *object, gchar *cmd, diff --git a/src/extension/dbus/document-interface.xml b/src/extension/dbus/document-interface.xml index aeacfae44..7481c0893 100644 --- a/src/extension/dbus/document-interface.xml +++ b/src/extension/dbus/document-interface.xml @@ -21,7 +21,7 @@ - +c @@ -1348,36 +1348,20 @@ Type of combination. - - + - The new path created, if there is one. NULL otherwise. + List of the ids of resulting paths after applying the operation. Will erase all objects in the selection and replace with a single aggregate path. There are 5 types that can be passed in: - Union: The new shape is all of the other shapes put together, even if they don't overlap (paths can have multiple non-contiguous areas.) - Intersection: The new shape is composed of the area where ALL the objects in the selection overlap. If there is no area where all shapes overlap the new shape will be empty. - Difference: The area of the second shape is subtracted from the first, only works with two objects. - Exclusion: The new shape is the area(s) where none of the objects in the selection overlaped. Only works with two objects. - Division: the first object is split into multiple segments by the second object. Only works with two objects and if multiple paths result they are grouped and the group id is returned. - - - - - - - - - List of the ids of resulting paths. - - - - - Returns the result of cutting the bottom object by all other intersecting paths. - This may make many seperate layers. + 'union': The new shape is all of the other shapes put together, even if they don't overlap (paths can have multiple non-contiguous areas.) + 'intersection': The new shape is composed of the area where ALL the objects in the selection overlap. If there is no area where all shapes overlap the new shape will be empty. + 'difference': The area of the second shape is subtracted from the first, only works with two objects. + 'exclusion': The new shape is the area(s) where none of the objects in the selection overlaped. Only works with two objects. + 'division': the first object is split into multiple segments by the second object. Only works with two objects. diff --git a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.c b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.c index 0be1be42e..c7e453593 100644 --- a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.c +++ b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.c @@ -687,24 +687,14 @@ inkscape_selection_to_path (DocumentInterface *doc, GError **error) return org_inkscape_document_selection_to_path (proxy, error); } -//static -char * -inkscape_selection_combine (DocumentInterface *doc, const char * IN_type, GError **error) -{ - char * OUT_newpath; - DBusGProxy *proxy = doc->proxy; - org_inkscape_document_selection_combine (proxy, IN_type, &OUT_newpath, error); - return OUT_newpath; -} - //static char ** -inkscape_selection_divide (DocumentInterface *doc, GError **error) +inkscape_selection_combine (DocumentInterface *doc, const char * IN_type, GError **error) { - char ** OUT_pieces; + char ** OUT_newpaths; DBusGProxy *proxy = doc->proxy; - org_inkscape_document_selection_divide (proxy, &OUT_pieces, error); - return OUT_pieces; + org_inkscape_document_selection_combine (proxy, IN_type, &OUT_newpaths, error); + return OUT_newpaths; } //static diff --git a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h index 684f1b142..79f8188d4 100644 --- a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h +++ b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h @@ -303,13 +303,9 @@ inkscape_selection_get_center (DocumentInterface *doc, GError **error); gboolean inkscape_selection_to_path (DocumentInterface *doc, GError **error); -//static -char * -inkscape_selection_combine (DocumentInterface *doc, const char * IN_type, GError **error); - //static char ** -inkscape_selection_divide (DocumentInterface *doc, GError **error); +inkscape_selection_combine (DocumentInterface *doc, const char * IN_type, GError **error); //static gboolean diff --git a/src/interface.cpp b/src/interface.cpp index e3036afdd..98c30bf3c 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1987,7 +1987,7 @@ void ContextMenu::MakeGroupMenu(void) void ContextMenu::ActivateGroup(void) { - sp_selection_group(_desktop); + sp_selection_group(_desktop->selection, _desktop); } void ContextMenu::ActivateUngroup(void) diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 591f9d68d..9f8dd984a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -125,6 +125,21 @@ because the layer manipulation code uses them. It should be rewritten specifical for that purpose. */ +// helper for printing error messages, regardless of whether we have a GUI or not +// If desktop == NULL, errors will be shown on stderr +static void +selection_display_message(SPDesktop *desktop, Inkscape::MessageType msgType, Glib::ustring const &msg) +{ + if (desktop) { + desktop->messageStack()->flash(msgType, msg); + } else { + if (msgType == Inkscape::IMMEDIATE_MESSAGE || + msgType == Inkscape::WARNING_MESSAGE || + msgType == Inkscape::ERROR_MESSAGE) { + g_printerr("%s\n", msg.c_str()); + } + } +} namespace Inkscape { @@ -722,20 +737,14 @@ static void sp_selection_group_impl(GSList *p, Inkscape::XML::Node *group, Inksc group->setPosition(topmost + 1); } -void sp_selection_group(SPDesktop *desktop) +void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) { - if (desktop == NULL) { - return; - } - - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = selection->layerModel()->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - // Check if something is selected. if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); return; } @@ -749,22 +758,17 @@ void sp_selection_group(SPDesktop *desktop) sp_selection_group_impl(p, group, xml_doc, doc); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_GROUP, + DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, _("Group")); selection->set(group); Inkscape::GC::release(group); } -void sp_selection_ungroup(SPDesktop *desktop) +void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) { - if (desktop == NULL) - return; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); return; } @@ -807,12 +811,12 @@ void sp_selection_ungroup(SPDesktop *desktop) g_slist_free(new_select); } if (!ungrouped) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); } g_slist_free(items); - - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_UNGROUP, + + DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); } @@ -890,22 +894,17 @@ static SPObject *prev_sibling(SPObject *child) } void -sp_selection_raise(SPDesktop *desktop) +sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) { - if (!desktop) - return; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = const_cast(selection->itemList()); if (!items) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); return; } SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } @@ -943,21 +942,17 @@ sp_selection_raise(SPDesktop *desktop) g_slist_free(rev); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_RAISE, + DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_RAISE, //TRANSLATORS: "Raise" means "to raise an object" in the undo history C_("Undo action", "Raise")); } -void sp_selection_raise_to_top(SPDesktop *desktop) +void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) { - if (desktop == NULL) - return; - - SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = selection->layerModel()->getDocument(); if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); return; } @@ -965,7 +960,7 @@ void sp_selection_raise_to_top(SPDesktop *desktop) SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } @@ -983,22 +978,17 @@ void sp_selection_raise_to_top(SPDesktop *desktop) _("Raise to top")); } -void sp_selection_lower(SPDesktop *desktop) +void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) { - if (desktop == NULL) - return; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = const_cast(selection->itemList()); if (!items) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); return; } SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } @@ -1041,20 +1031,16 @@ void sp_selection_lower(SPDesktop *desktop) g_slist_free(rev); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_LOWER, + DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_LOWER, _("Lower")); } -void sp_selection_lower_to_bottom(SPDesktop *desktop) +void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) { - if (desktop == NULL) - return; - - SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = selection->layerModel()->getDocument(); if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); return; } @@ -1062,7 +1048,7 @@ void sp_selection_lower_to_bottom(SPDesktop *desktop) SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index f58ede21a..f7a4f928c 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -77,13 +77,13 @@ void sp_selection_tile(SPDesktop *desktop, bool apply = true); void sp_selection_untile(SPDesktop *desktop); //void sp_selection_group_impl(GSList const *reprs_to_group, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc); -void sp_selection_group(SPDesktop *desktop); -void sp_selection_ungroup(SPDesktop *desktop); +void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop); -void sp_selection_raise(SPDesktop *desktop); -void sp_selection_raise_to_top(SPDesktop *desktop); -void sp_selection_lower(SPDesktop *desktop); -void sp_selection_lower_to_bottom(SPDesktop *desktop); +void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop); SPCSSAttr *take_style_from_item (SPItem *item); diff --git a/src/verbs.cpp b/src/verbs.cpp index 6187cfb4c..fed9622fb 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1089,6 +1089,24 @@ void SelectionVerb::perform(SPAction *action, void *data) case SP_VERB_SELECTION_SLICE: sp_selected_path_slice(selection, dt); break; + case SP_VERB_SELECTION_TO_FRONT: + sp_selection_raise_to_top(selection, dt); + break; + case SP_VERB_SELECTION_TO_BACK: + sp_selection_lower_to_bottom(selection, dt); + break; + case SP_VERB_SELECTION_RAISE: + sp_selection_raise(selection, dt); + break; + case SP_VERB_SELECTION_LOWER: + sp_selection_lower(selection, dt); + break; + case SP_VERB_SELECTION_GROUP: + sp_selection_group(selection, dt); + break; + case SP_VERB_SELECTION_UNGROUP: + sp_selection_ungroup(selection, dt); + break; default: handled = false; break; @@ -1107,25 +1125,6 @@ void SelectionVerb::perform(SPAction *action, void *data) g_assert(dt->_dlg_mgr != NULL); switch (reinterpret_cast(data)) { - case SP_VERB_SELECTION_TO_FRONT: - sp_selection_raise_to_top(dt); - break; - case SP_VERB_SELECTION_TO_BACK: - sp_selection_lower_to_bottom(dt); - break; - case SP_VERB_SELECTION_RAISE: - sp_selection_raise(dt); - break; - case SP_VERB_SELECTION_LOWER: - sp_selection_lower(dt); - break; - case SP_VERB_SELECTION_GROUP: - sp_selection_group(dt); - break; - case SP_VERB_SELECTION_UNGROUP: - sp_selection_ungroup(dt); - break; - case SP_VERB_SELECTION_TEXTTOPATH: text_put_on_path(); break; -- cgit v1.2.3 From 104efe4e3ecadc975ab76748c66f041abf8ee7b1 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Thu, 4 Jul 2013 15:01:44 +0100 Subject: Code readability improvements and licence changes for action-context.* based on merge request code review and feedback (bzr r12387.1.7) --- src/desktop.cpp | 50 ++--- src/desktop.h | 4 +- src/extension/dbus/dbus-init.cpp | 4 +- src/extension/dbus/document-interface.cpp | 299 +++++++++++++----------------- src/extension/dbus/document-interface.h | 2 +- src/extension/effect.cpp | 7 +- src/helper/action-context.cpp | 4 +- src/helper/action-context.h | 2 +- src/selection-chemistry.cpp | 22 +-- src/selection-describer.cpp | 4 +- src/selection.cpp | 14 +- src/selection.h | 8 +- src/splivarot.cpp | 2 +- src/verbs.cpp | 91 +++------ src/verbs.h | 2 +- 15 files changed, 210 insertions(+), 305 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 485fcfcc4..ce740f76f 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -96,7 +96,7 @@ SPDesktop::SPDesktop() : _dlg_mgr( 0 ), namedview( 0 ), canvas( 0 ), - layer_model( 0 ), + layers( 0 ), selection( 0 ), event_context( 0 ), layer_manager( 0 ), @@ -142,11 +142,11 @@ SPDesktop::SPDesktop() : _d2w.setIdentity(); _w2d.setIdentity(); - layer_model = new Inkscape::LayerModel(); - layer_model->_layer_activated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_activated), this)); - layer_model->_layer_deactivated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); - layer_model->_layer_changed_signal.connect(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); - selection = Inkscape::GC::release( new Inkscape::Selection(layer_model, this) ); + layers = new Inkscape::LayerModel(); + layers->_layer_activated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_activated), this)); + layers->_layer_deactivated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); + layers->_layer_changed_signal.connect(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); + selection = Inkscape::GC::release( new Inkscape::Selection(layers, this) ); } void @@ -176,7 +176,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid dkey = SPItem::display_key_new(1); /* Connect display key to layer model */ - layer_model->setDisplayKey(dkey); + layers->setDisplayKey(dkey); /* Connect document */ setDocument (document); @@ -367,7 +367,7 @@ void SPDesktop::destroy() g_object_unref (G_OBJECT (ec)); } - delete layer_model; + delete layers; if (layer_manager) { delete layer_manager; @@ -491,42 +491,42 @@ void SPDesktop::displayColorModeToggle() { // Pass-through LayerModel functions SPObject *SPDesktop::currentRoot() const { - return layer_model->currentRoot(); + return layers->currentRoot(); } SPObject *SPDesktop::currentLayer() const { - return layer_model->currentLayer(); + return layers->currentLayer(); } void SPDesktop::setCurrentLayer(SPObject *object) { - layer_model->setCurrentLayer(object); + layers->setCurrentLayer(object); } void SPDesktop::toggleLayerSolo(SPObject *object) { - layer_model->toggleLayerSolo(object); + layers->toggleLayerSolo(object); } void SPDesktop::toggleHideAllLayers(bool hide) { - layer_model->toggleHideAllLayers(hide); + layers->toggleHideAllLayers(hide); } void SPDesktop::toggleLockAllLayers(bool lock) { - layer_model->toggleLockAllLayers(lock); + layers->toggleLockAllLayers(lock); } void SPDesktop::toggleLockOtherLayers(SPObject *object) { - layer_model->toggleLockOtherLayers(object); + layers->toggleLockOtherLayers(object); } bool SPDesktop::isLayer(SPObject *object) const { - return layer_model->isLayer(object); + return layers->isLayer(object); } /** @@ -1491,7 +1491,7 @@ SPDesktop::setDocument (SPDocument *doc) this->doc()->getRoot()->invoke_hide(dkey); } - layer_model->setDocument(doc); + layers->setDocument(doc); // remove old EventLog if it exists (see also: bug #1071082) if (event_log) { @@ -1599,9 +1599,9 @@ _onSelectionChanged */ SPItem *item=selection->singleItem(); if (item) { - SPObject *layer=desktop->layer_model->layerForObject(item); + SPObject *layer=desktop->layers->layerForObject(item); if ( layer && layer != desktop->currentLayer() ) { - desktop->layer_model->setCurrentLayer(layer); + desktop->layers->setCurrentLayer(layer); } } } @@ -1646,9 +1646,9 @@ _layer_hierarchy_changed(SPObject */*top*/, SPObject *bottom, /// Called when document is starting to be rebuilt. static void _reconstruction_start(SPDesktop * desktop) { - // printf("Desktop, starting reconstruction\n"); + g_debug("Desktop, starting reconstruction\n"); desktop->_reconstruction_old_layer_id = desktop->currentLayer()->getId() ? desktop->currentLayer()->getId() : ""; - desktop->layer_model->reset(); + desktop->layers->reset(); /* GSList const * selection_objs = desktop->selection->list(); @@ -1658,22 +1658,22 @@ static void _reconstruction_start(SPDesktop * desktop) */ desktop->selection->clear(); - // printf("Desktop, starting reconstruction end\n"); + g_debug("Desktop, starting reconstruction end\n"); } /// Called when document rebuild is finished. static void _reconstruction_finish(SPDesktop * desktop) { - // printf("Desktop, finishing reconstruction\n"); + g_debug("Desktop, finishing reconstruction\n"); if ( !desktop->_reconstruction_old_layer_id.empty() ) { SPObject * newLayer = desktop->namedview->document->getObjectById(desktop->_reconstruction_old_layer_id); if (newLayer != NULL) { - desktop->layer_model->setCurrentLayer(newLayer); + desktop->layers->setCurrentLayer(newLayer); } desktop->_reconstruction_old_layer_id.clear(); - // printf("Desktop, finishing reconstruction end\n"); } + g_debug("Desktop, finishing reconstruction end\n"); } /** diff --git a/src/desktop.h b/src/desktop.h index 661470ded..9a3c609d0 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -125,7 +125,7 @@ public: Inkscape::UI::Dialog::DialogManager *_dlg_mgr; SPNamedView *namedview; SPCanvas *canvas; - Inkscape::LayerModel *layer_model; + Inkscape::LayerModel *layers; /// current selection; will never generally be NULL Inkscape::Selection *selection; SPEventContext *event_context; @@ -263,7 +263,7 @@ public: void set_active (bool new_active); - // Could make all callers use layer_model instead of passing calls through? + // Could make all callers use this->layers instead of passing calls through? SPObject *currentRoot() const; SPObject *currentLayer() const; void setCurrentLayer(SPObject *object); diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index 96d72c0f6..fe59fc154 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -153,7 +153,7 @@ init_active_document() name.c_str()); // Set the document info for this interface - obj->context = inkscape_active_action_context(); + obj->doc_context = inkscape_active_action_context(); } return strdup(name.c_str()); } @@ -178,7 +178,7 @@ dbus_init_desktop_interface (SPDesktop * dt) obj = (DocumentInterface*) dbus_register_object (connection, proxy, TYPE_DOCUMENT_INTERFACE, &dbus_glib_document_interface_object_info, name.c_str()); - obj->context = Inkscape::ActionContext(dt); + obj->doc_context = Inkscape::ActionContext(dt); obj->updates = TRUE; dt->dbus_document_interface=obj; return strdup(name.c_str()); diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index 87b769e26..6d6f983c5 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -190,7 +190,7 @@ selection_swap(Inkscape::Selection *sel, gchar *name, GError **error) { const GSList *oldsel = g_slist_copy((GSList *)sel->list()); - sel->set(get_object_by_name(sel->layerModel()->getDocument(), name, error)); + sel->set(get_object_by_name(sel->layers()->getDocument(), name, error)); return oldsel; } @@ -224,8 +224,8 @@ dbus_create_node (SPDocument *doc, const gchar *type) gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inkscape::XML::Node *newNode, gchar *desc) { SPCSSAttr *style = NULL; - if (object->context.getDesktop()) { - style = sp_desktop_get_style(object->context.getDesktop(), TRUE); + if (object->doc_context.getDesktop()) { + style = sp_desktop_get_style(object->doc_context.getDesktop(), TRUE); } if (style) { Glib::ustring str; @@ -236,13 +236,11 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks newNode->setAttribute("style", "fill:#0000ff;fill-opacity:1;stroke:#c900b9;stroke-width:0;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none", TRUE); } - object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); - object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); + object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); if (object->updates) { - Inkscape::DocumentUndo::done(object->context.getDocument(), 0, (gchar *)desc); - //} else { - //document_interface_pause_updates(object, error); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), 0, (gchar *)desc); } return strdup(newNode->attribute("id")); @@ -259,21 +257,17 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks gboolean dbus_call_verb (DocumentInterface *object, int verbid, GError **error) { - SPDesktop *desk = object->context.getDesktop(); + SPDesktop *desk = object->doc_context.getDesktop(); if ( desk ) { desktop_ensure_active (desk); } Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); if ( verb ) { - SPAction *action = verb->get_action(object->context); + SPAction *action = verb->get_action(object->doc_context); if ( action ) { - //if (!object->updates) - //document_interface_pause_updates (object, error); sp_action_perform( action, NULL ); if (object->updates) - Inkscape::DocumentUndo::done(object->context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); - //if (!object->updates) - //document_interface_pause_updates (object, error); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); return TRUE; } } @@ -281,6 +275,20 @@ dbus_call_verb (DocumentInterface *object, int verbid, GError **error) return FALSE; } +/* + * Check that the desktop is not NULL. If it is NULL, set the error to a useful message. + */ +bool +ensure_desktop_valid(SPDesktop* desk, GError **error) +{ + if (desk) { + return true; + } + + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document interface action requires a GUI"); + return false; +} + /**************************************************************************** DOCUMENT INTERFACE CLASS STUFF ****************************************************************************/ @@ -313,7 +321,7 @@ document_interface_class_init (DocumentInterfaceClass *klass) static void document_interface_init (DocumentInterface *object) { - object->context = Inkscape::ActionContext(); + object->doc_context = Inkscape::ActionContext(); } @@ -331,24 +339,24 @@ document_interface_new (void) gboolean document_interface_delete_all(DocumentInterface *object, GError ** /*error*/) { - sp_edit_clear_all(object->context.getSelection()); + sp_edit_clear_all(object->doc_context.getSelection()); return TRUE; } gboolean document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error) { - SPDesktop *desk = object->context.getDesktop(); + SPDesktop *desk = object->doc_context.getDesktop(); if ( desk ) { desktop_ensure_active (desk); } Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid ); if ( verb ) { - SPAction *action = verb->get_action(object->context); + SPAction *action = verb->get_action(object->doc_context); if ( action ) { sp_action_perform( action, NULL ); if (object->updates) { - Inkscape::DocumentUndo::done(object->context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); } return TRUE; } @@ -368,7 +376,7 @@ document_interface_rectangle (DocumentInterface *object, int x, int y, { - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:rect"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:rect"); sp_repr_set_int(newNode, "x", x); //could also use newNode->setAttribute() sp_repr_set_int(newNode, "y", y); sp_repr_set_int(newNode, "width", width); @@ -380,7 +388,7 @@ gchar* document_interface_ellipse_center (DocumentInterface *object, int cx, int cy, int rx, int ry, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "arc"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); @@ -395,7 +403,7 @@ document_interface_polygon (DocumentInterface *object, int cx, int cy, GError **error) { gdouble rot = ((rotation / 180.0) * 3.14159265) - ( 3.14159265 / 2.0); - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "true"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -416,7 +424,7 @@ document_interface_star (DocumentInterface *object, int cx, int cy, int r1, int r2, int sides, gdouble rounded, gdouble arg1, gdouble arg2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "false"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -445,7 +453,7 @@ gchar* document_interface_line (DocumentInterface *object, int x, int y, int x2, int y2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); std::stringstream out; // Not sure why this works. out << "m " << x << "," << y << " " << x2 - x << "," << y2 - y; @@ -457,7 +465,7 @@ gchar* document_interface_spiral (DocumentInterface *object, int cx, int cy, int r, int revolutions, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "spiral"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); @@ -478,13 +486,13 @@ gchar* document_interface_text (DocumentInterface *object, int x, int y, gchar *text, GError **error) { - Inkscape::XML::Node *text_node = dbus_create_node(object->context.getDocument(), "svg:text"); + Inkscape::XML::Node *text_node = dbus_create_node(object->doc_context.getDocument(), "svg:text"); sp_repr_set_int(text_node, "x", x); sp_repr_set_int(text_node, "y", y); //just a workaround so i can get an spitem from the name gchar *name = finish_create_shape (object, error, text_node, (gchar *)"create text"); - SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); sp_te_set_repr_text_multiline(text_obj, text); return name; @@ -497,16 +505,16 @@ document_interface_image (DocumentInterface *object, int x, int y, gchar *filena if (!uri) return FALSE; - Inkscape::XML::Node *newNode = dbus_create_node(object->context.getDocument(), "svg:image"); + Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:image"); sp_repr_set_int(newNode, "x", x); sp_repr_set_int(newNode, "y", y); newNode->setAttribute("xlink:href", uri); - object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); - object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); + object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); if (object->updates) - Inkscape::DocumentUndo::done(object->context.getDocument(), 0, "Imported bitmap."); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), 0, "Imported bitmap."); //g_free(uri); return strdup(newNode->attribute("id")); @@ -514,18 +522,16 @@ document_interface_image (DocumentInterface *object, int x, int y, gchar *filena gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** /*error*/) { - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *newNode = xml_doc->createElement(type); - object->context.getSelection()->layerModel()->currentLayer()->appendChildRepr(newNode); - object->context.getSelection()->layerModel()->currentLayer()->updateRepr(); + object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); if (object->updates) { Inkscape::DocumentUndo::done(doc, 0, (gchar *)"created empty node"); - //} else { - //document_interface_pause_updates(object, error); } return strdup(newNode->attribute("id")); @@ -537,22 +543,19 @@ gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** gdouble document_interface_document_get_width (DocumentInterface *object) { - return object->context.getDocument()->getWidth(); + return object->doc_context.getDocument()->getWidth(); } gdouble document_interface_document_get_height (DocumentInterface *object) { - return object->context.getDocument()->getHeight(); + return object->doc_context.getDocument()->getHeight(); } gchar *document_interface_document_get_css(DocumentInterface *object, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document get CSS requires a GUI"); - return NULL; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), NULL); SPCSSAttr *current = desk->current; Glib::ustring str; sp_repr_css_write_string(current, str); @@ -562,11 +565,8 @@ gchar *document_interface_document_get_css(DocumentInterface *object, GError ** gboolean document_interface_document_merge_css(DocumentInterface *object, gchar *stylestring, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document merge CSS requires a GUI"); - return FALSE; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(style, stylestring); sp_desktop_set_style(desk, style); @@ -576,11 +576,8 @@ gboolean document_interface_document_merge_css(DocumentInterface *object, gboolean document_interface_document_set_css(DocumentInterface *object, gchar *stylestring, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document set CSS requires a GUI"); - return FALSE; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string (style, stylestring); //Memory leak? @@ -604,11 +601,8 @@ document_interface_document_set_display_area (DocumentInterface *object, double border, GError **error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document set display area requires a GUI"); - return FALSE; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); desk->set_display_area (x0, y0, x1, @@ -621,7 +615,7 @@ document_interface_document_set_display_area (DocumentInterface *object, GArray * document_interface_document_get_display_area (DocumentInterface *object) { - SPDesktop *desk = object->context.getDesktop(); + SPDesktop *desk = object->doc_context.getDesktop(); if (!desk) { return NULL; } @@ -650,7 +644,7 @@ gboolean document_interface_set_attribute (DocumentInterface *object, char *shape, char *attribute, char *newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(object->doc_context.getDocument(), shape, error); /* ALTERNATIVE (is this faster?) Inkscape::XML::Node *newnode = sp_repr_lookup_name((doc->root)->repr, name); @@ -670,7 +664,7 @@ document_interface_set_int_attribute (DocumentInterface *object, char *shape, char *attribute, int newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (object->doc_context.getDocument(), shape, error); if (!newNode) return FALSE; @@ -684,7 +678,7 @@ document_interface_set_double_attribute (DocumentInterface *object, char *shape, char *attribute, double newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (object->doc_context.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "New value string was empty.")) return FALSE; @@ -699,7 +693,7 @@ gchar * document_interface_get_attribute (DocumentInterface *object, char *shape, char *attribute, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(object->doc_context.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "Attribute name empty.")) return NULL; @@ -713,11 +707,11 @@ gboolean document_interface_move (DocumentInterface *object, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->context.getSelection(), name, error); + const GSList *oldsel = selection_swap(object->doc_context.getSelection(), name, error); if (!oldsel) return FALSE; - sp_selection_move (object->context.getSelection(), x, 0 - y); - selection_restore(object->context.getSelection(), oldsel); + sp_selection_move (object->doc_context.getSelection(), x, 0 - y); + selection_restore(object->doc_context.getSelection(), oldsel); return TRUE; } @@ -725,13 +719,13 @@ gboolean document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->context.getSelection(), name, error); + const GSList *oldsel = selection_swap(object->doc_context.getSelection(), name, error); if (!oldsel) return FALSE; - Inkscape::Selection * sel = object->context.getSelection(); - sp_selection_move (object->context.getSelection(), x - selection_get_center_x(sel), + Inkscape::Selection * sel = object->doc_context.getSelection(); + sp_selection_move (object->doc_context.getSelection(), x - selection_get_center_x(sel), 0 - (y - selection_get_center_y(sel))); - selection_restore(object->context.getSelection(), oldsel); + selection_restore(object->doc_context.getSelection(), oldsel); return TRUE; } @@ -739,18 +733,18 @@ gboolean document_interface_object_to_path (DocumentInterface *object, char *shape, GError **error) { - const GSList *oldsel = selection_swap(object->context.getSelection(), shape, error); + const GSList *oldsel = selection_swap(object->doc_context.getSelection(), shape, error); if (!oldsel) return FALSE; dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); - selection_restore(object->context.getSelection(), oldsel); + selection_restore(object->doc_context.getSelection(), oldsel); return TRUE; } gchar * document_interface_get_path (DocumentInterface *object, char *pathname, GError **error) { - Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), pathname, error); + Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), pathname, error); if (!node) return NULL; @@ -787,7 +781,7 @@ document_interface_modify_css (DocumentInterface *object, gchar *shape, { // Doesn't like non-variable strings for some reason. gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), shape, error); + Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), shape, error); if (!dbus_check_string (cssattrb, error, "Attribute string empty.")) return FALSE; @@ -808,7 +802,7 @@ document_interface_merge_css (DocumentInterface *object, gchar *shape, { gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->context.getDocument(), shape, error); + Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), shape, error); if (!dbus_check_string (stylestring, error, "Style string empty.")) return FALSE; @@ -854,12 +848,12 @@ gboolean document_interface_move_to_layer (DocumentInterface *object, gchar *shape, gchar *layerstr, GError **error) { - const GSList *oldsel = selection_swap(object->context.getSelection(), shape, error); + const GSList *oldsel = selection_swap(object->doc_context.getSelection(), shape, error); if (!oldsel) return FALSE; document_interface_selection_move_to_layer(object, layerstr, error); - selection_restore(object->context.getSelection(), oldsel); + selection_restore(object->doc_context.getSelection(), oldsel); return TRUE; } @@ -867,7 +861,7 @@ GArray *document_interface_get_node_coordinates(DocumentInterface * /*object*/, { //FIXME: Needs lot's of work. /* - Inkscape::XML::Node *shapenode = get_repr_by_name (object->context.getDocument(), shape, error); + Inkscape::XML::Node *shapenode = get_repr_by_name (object->doc_context.getDocument(), shape, error); if (shapenode == NULL || shapenode->attribute("d") == NULL) { return FALSE; } @@ -885,7 +879,7 @@ gboolean document_interface_set_text (DocumentInterface *object, gchar *name, gchar *text, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); //TODO verify object type if (!text_obj) return FALSE; @@ -902,7 +896,7 @@ document_interface_text_apply_style (DocumentInterface *object, gchar *name, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); //void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPCSSAttr const *css) //TODO verify object type @@ -931,7 +925,7 @@ document_interface_text_apply_style (DocumentInterface *object, gchar *name, gboolean document_interface_save (DocumentInterface *object, GError **error) { - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); printf("1: %s\n2: %s\n3: %s\n", doc->getURI(), doc->getBase(), doc->getName()); if (doc->getURI()) return document_interface_save_as (object, doc->getURI(), error); @@ -941,14 +935,14 @@ document_interface_save (DocumentInterface *object, GError **error) gboolean document_interface_load(DocumentInterface *object, gchar *filename, GError ** /*error*/) { - SPDesktop *desk = object->context.getDesktop(); + SPDesktop *desk = object->doc_context.getDesktop(); if (desk) { desktop_ensure_active(desk); } const Glib::ustring file(filename); sp_file_open(file, NULL, TRUE, TRUE); if (object->updates) { - Inkscape::DocumentUndo::done(object->context.getDocument(), SP_VERB_FILE_OPEN, "Opened File"); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), SP_VERB_FILE_OPEN, "Opened File"); } return TRUE; } @@ -957,12 +951,12 @@ gchar * document_interface_import (DocumentInterface *object, gchar *filename, GError **error) { - SPDesktop *desk = object->context.getDesktop(); + SPDesktop *desk = object->doc_context.getDesktop(); if (desk) { desktop_ensure_active(desk); } const Glib::ustring file(filename); - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); SPObject *new_obj = NULL; new_obj = file_import(doc, file, NULL); @@ -973,7 +967,8 @@ gboolean document_interface_save_as (DocumentInterface *object, const gchar *filename, GError **error) { - SPDocument * doc = object->context.getDocument(); + // FIXME: Isn't there a verb we can use for this instead? + SPDocument * doc = object->doc_context.getDocument(); #ifdef WITH_GNOME_VFS const Glib::ustring file(filename); return file_save_remote(doc, file, NULL, TRUE, TRUE); @@ -986,18 +981,16 @@ document_interface_save_as (DocumentInterface *object, Inkscape::Extension::save(NULL, doc, filename, false, false, true, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS); } catch (...) { - //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + // FIXME: catch ... is not usually a great idea, why is it needed here? return false; } - //SP_ACTIVE_DESKTOP->event_log->rememberFileSave(); - //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, "Document saved."); return true; } gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError ** /*error*/) { - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); if (doc) { doc->modified_since_save = FALSE; } @@ -1008,7 +1001,7 @@ gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError gboolean document_interface_print_to_file (DocumentInterface *object, GError **error) { - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf")); return TRUE; @@ -1053,45 +1046,27 @@ document_interface_redo (DocumentInterface *object, GError **error) void document_interface_pause_updates(DocumentInterface *object, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document pause updates requires a GUI"); - return; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_if_fail(ensure_desktop_valid(desk, error)); object->updates = FALSE; desk->canvas->drawing_disabled = 1; - //desk->canvas->need_redraw = 0; - //desk->canvas->need_repick = 0; - //object->context.getDocument()->root->uflags = FALSE; - //object->context.getDocument()->root->mflags = FALSE; } void document_interface_resume_updates(DocumentInterface *object, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document resume updates requires a GUI"); - return; - } + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_if_fail(ensure_desktop_valid(desk, error)); object->updates = TRUE; desk->canvas->drawing_disabled = 0; - //desk->canvas->need_redraw = 1; - //desk->canvas->need_repick = 1; - //object->context.getDocument()->root->uflags = TRUE; - //object->context.getDocument()->root->mflags = TRUE; - //object->context.getDocument()->_updateDocument(); //FIXME: use better verb than rect. - Inkscape::DocumentUndo::done(object->context.getDocument(), SP_VERB_CONTEXT_RECT, "Multiple actions"); + Inkscape::DocumentUndo::done(object->doc_context.getDocument(), SP_VERB_CONTEXT_RECT, "Multiple actions"); } void document_interface_update(DocumentInterface *object, GError ** error) { - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document update requires a GUI"); - return; - } - SPDocument *doc = object->context.getDocument(); + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_if_fail(ensure_desktop_valid(desk, error)); + SPDocument *doc = object->doc_context.getDocument(); doc->getRoot()->uflags = TRUE; doc->getRoot()->mflags = TRUE; desk->enableInteraction(); @@ -1108,7 +1083,7 @@ void document_interface_update(DocumentInterface *object, GError ** error) gboolean document_interface_selection_get(DocumentInterface *object, char ***out, GError ** /*error*/) { - Inkscape::Selection * sel = object->context.getSelection(); + Inkscape::Selection * sel = object->doc_context.getSelection(); GSList const *oldsel = sel->list(); int size = g_slist_length((GSList *) oldsel); @@ -1128,11 +1103,11 @@ gboolean document_interface_selection_get(DocumentInterface *object, char ***out gboolean document_interface_selection_add (DocumentInterface *object, char *name, GError **error) { - SPObject * obj = get_object_by_name(object->context.getDocument(), name, error); + SPObject * obj = get_object_by_name(object->doc_context.getDocument(), name, error); if (!obj) return FALSE; - Inkscape::Selection *selection = object->context.getSelection(); + Inkscape::Selection *selection = object->doc_context.getSelection(); selection->add(obj); return TRUE; @@ -1151,8 +1126,8 @@ document_interface_selection_add_list (DocumentInterface *object, gboolean document_interface_selection_set(DocumentInterface *object, char *name, GError ** /*error*/) { - SPDocument * doc = object->context.getDocument(); - Inkscape::Selection *selection = object->context.getSelection(); + SPDocument * doc = object->doc_context.getDocument(); + Inkscape::Selection *selection = object->doc_context.getSelection(); selection->set(doc->getObjectById(name)); return TRUE; } @@ -1161,7 +1136,7 @@ gboolean document_interface_selection_set_list (DocumentInterface *object, gchar **names, GError **error) { - object->context.getSelection()->clear(); + object->doc_context.getSelection()->clear(); int i; for (i=0;names[i] != NULL;i++) { document_interface_selection_add(object, names[i], error); @@ -1171,7 +1146,7 @@ document_interface_selection_set_list (DocumentInterface *object, gboolean document_interface_selection_rotate(DocumentInterface *object, int angle, GError ** /*error*/) { - Inkscape::Selection *selection = object->context.getSelection(); + Inkscape::Selection *selection = object->doc_context.getSelection(); sp_selection_rotate(selection, angle); return TRUE; } @@ -1179,20 +1154,18 @@ gboolean document_interface_selection_rotate(DocumentInterface *object, int angl gboolean document_interface_selection_delete (DocumentInterface *object, GError **error) { - //sp_selection_delete (object->desk); return dbus_call_verb (object, SP_VERB_EDIT_DELETE, error); } gboolean document_interface_selection_clear(DocumentInterface *object, GError ** /*error*/) { - object->context.getSelection()->clear(); + object->doc_context.getSelection()->clear(); return TRUE; } gboolean document_interface_select_all (DocumentInterface *object, GError **error) { - //sp_edit_select_all (object->desk); return dbus_call_verb (object, SP_VERB_EDIT_SELECT_ALL, error); } @@ -1200,7 +1173,6 @@ gboolean document_interface_select_all_in_all_layers(DocumentInterface *object, GError **error) { - //sp_edit_select_all_in_all_layers (object->desk); return dbus_call_verb (object, SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS, error); } @@ -1215,7 +1187,6 @@ gboolean document_interface_selection_box(DocumentInterface * /*object*/, int /* gboolean document_interface_selection_invert (DocumentInterface *object, GError **error) { - //sp_edit_invert (object->desk); return dbus_call_verb (object, SP_VERB_EDIT_INVERT, error); } @@ -1233,46 +1204,30 @@ document_interface_selection_ungroup (DocumentInterface *object, GError **error) gboolean document_interface_selection_cut (DocumentInterface *object, GError **error) { - //desktop_ensure_active (object->desk); - //sp_selection_cut (object->desk); + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); return dbus_call_verb (object, SP_VERB_EDIT_CUT, error); } gboolean document_interface_selection_copy (DocumentInterface *object, GError **error) { - //desktop_ensure_active (object->desk); - //sp_selection_copy (); + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); return dbus_call_verb (object, SP_VERB_EDIT_COPY, error); } -/* -gboolean -document_interface_selection_paste (DocumentInterface *object, GError **error) -{ - SPDesktop *desk = object->context.getDesktop(); - if (!desk) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document selection paste requires a GUI"); - return FALSE; - } - desktop_ensure_active (desk); - if (!object->updates) - document_interface_pause_updates (object, error); - sp_selection_paste (object->desk, TRUE); - if (!object->updates) - document_interface_pause_updates (object, error); - return TRUE; - //return dbus_call_verb (object, SP_VERB_EDIT_PASTE, error); -} -*/ + gboolean document_interface_selection_paste (DocumentInterface *object, GError **error) { + SPDesktop *desk = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); return dbus_call_verb (object, SP_VERB_EDIT_PASTE, error); } gboolean document_interface_selection_scale(DocumentInterface *object, gdouble grow, GError ** /*error*/) { - Inkscape::Selection *selection = object->context.getSelection(); + Inkscape::Selection *selection = object->doc_context.getSelection(); if (!selection) { return FALSE; @@ -1283,13 +1238,13 @@ gboolean document_interface_selection_scale(DocumentInterface *object, gdouble g gboolean document_interface_selection_move(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) { - sp_selection_move(object->context.getSelection(), x, 0 - y); //switching coordinate systems. + sp_selection_move(object->doc_context.getSelection(), x, 0 - y); //switching coordinate systems. return TRUE; } gboolean document_interface_selection_move_to(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) { - Inkscape::Selection * sel = object->context.getSelection(); + Inkscape::Selection * sel = object->doc_context.getSelection(); Geom::OptRect sel_bbox = sel->visualBounds(); if (sel_bbox) { @@ -1306,19 +1261,16 @@ gboolean document_interface_selection_move_to_layer (DocumentInterface *object, gchar *layerstr, GError **error) { - SPDesktop *dt = object->context.getDesktop(); - if (!dt) { - g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Document selection move to layer requires a GUI"); - return FALSE; - } + SPDesktop *dt = object->doc_context.getDesktop(); + g_return_val_if_fail(ensure_desktop_valid(dt, error), FALSE); - Inkscape::Selection *selection = object->context.getSelection(); + Inkscape::Selection *selection = object->doc_context.getSelection(); // check if something is selected if (selection->isEmpty()) return FALSE; - SPObject *next = get_object_by_name(object->context.getDocument(), layerstr, error); + SPObject *next = get_object_by_name(object->doc_context.getDocument(), layerstr, error); if (!next) return FALSE; @@ -1327,7 +1279,7 @@ document_interface_selection_move_to_layer (DocumentInterface *object, sp_selection_cut(dt); - object->context.getSelection()->layerModel()->setCurrentLayer(next); + object->doc_context.getSelection()->layers()->setCurrentLayer(next); sp_selection_paste(dt, TRUE); } @@ -1337,7 +1289,7 @@ document_interface_selection_move_to_layer (DocumentInterface *object, GArray * document_interface_selection_get_center (DocumentInterface *object) { - Inkscape::Selection * sel = object->context.getSelection(); + Inkscape::Selection * sel = object->doc_context.getSelection(); if (sel) { @@ -1403,9 +1355,9 @@ document_interface_selection_change_level (DocumentInterface *object, gchar *cmd gchar *document_interface_layer_new(DocumentInterface *object, GError ** /*error*/) { - Inkscape::LayerModel * layerModel = object->context.getSelection()->layerModel(); - SPObject *new_layer = Inkscape::create_layer(layerModel->currentRoot(), layerModel->currentLayer(), Inkscape::LPOS_BELOW); - layerModel->setCurrentLayer(new_layer); + Inkscape::LayerModel * layers = object->doc_context.getSelection()->layers(); + SPObject *new_layer = Inkscape::create_layer(layers->currentRoot(), layers->currentLayer(), Inkscape::LPOS_BELOW); + layers->setCurrentLayer(new_layer); return g_strdup(get_name_from_object(new_layer)); } @@ -1413,12 +1365,12 @@ gboolean document_interface_layer_set (DocumentInterface *object, gchar *layerstr, GError **error) { - SPObject * obj = get_object_by_name (object->context.getDocument(), layerstr, error); + SPObject * obj = get_object_by_name (object->doc_context.getDocument(), layerstr, error); if (!obj) return FALSE; - object->context.getSelection()->layerModel()->setCurrentLayer (obj); + object->doc_context.getSelection()->layers()->setCurrentLayer (obj); return TRUE; } @@ -1462,7 +1414,6 @@ document_interface_layer_previous (DocumentInterface *object, GError **error) DocumentInterface *fugly; gboolean dbus_send_ping (SPDesktop* desk, SPItem *item) { - //DocumentInterface *obj; if (!item) return TRUE; g_signal_emit (desk->dbus_document_interface, signals[OBJECT_MOVED_SIGNAL], 0, item->getId()); return TRUE; @@ -1474,7 +1425,7 @@ gboolean dbus_send_ping (SPDesktop* desk, SPItem *item) gboolean document_interface_get_children (DocumentInterface *object, char *name, char ***out, GError **error) { - SPItem* parent=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); + SPItem* parent=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); GSList const *children = parent->childList(false); @@ -1497,7 +1448,7 @@ document_interface_get_children (DocumentInterface *object, char *name, char ** gchar* document_interface_get_parent (DocumentInterface *object, char *name, GError **error) { - SPItem* node=(SPItem* )get_object_by_name(object->context.getDocument(), name, error); + SPItem* node=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); SPObject* parent=node->parent; @@ -1509,7 +1460,7 @@ document_interface_get_parent (DocumentInterface *object, char *name, GError ** //just pseudo code gboolean document_interface_get_xpath (DocumentInterface *object, char *xpath_expression, char ***out, GError **error){ - SPDocument * doc = object->context.getDocument(); + SPDocument * doc = object->doc_context.getDocument(); Inkscape::XML::Document *repr = doc->getReprDoc(); xmlXPathObjectPtr xpathObj; diff --git a/src/extension/dbus/document-interface.h b/src/extension/dbus/document-interface.h index 5eef3d0c0..f90fe7c80 100644 --- a/src/extension/dbus/document-interface.h +++ b/src/extension/dbus/document-interface.h @@ -52,7 +52,7 @@ typedef struct _DocumentInterfaceClass DocumentInterfaceClass; struct _DocumentInterface { GObject parent; - Inkscape::ActionContext context; + Inkscape::ActionContext doc_context; ///< stores information about which document, selection, desktop etc this interface is linked to gboolean updates; }; diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 93b1bb91d..dcccf3d7d 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -368,12 +368,9 @@ Effect::EffectVerb::make_action (Inkscape::ActionContext const & context) void Effect::EffectVerb::perform( SPAction *action, void * data ) { + g_return_if_fail(ensure_desktop_valid(action)); Inkscape::UI::View::View * current_view = sp_action_get_view(action); - if (current_view == NULL) { - show_gui_required_message(action); - return; - } -// SPDocument * current_document = current_view->doc; + Effect::EffectVerb * ev = reinterpret_cast(data); Effect * effect = ev->_effect; diff --git a/src/helper/action-context.cpp b/src/helper/action-context.cpp index f211d775d..d52e43d96 100644 --- a/src/helper/action-context.cpp +++ b/src/helper/action-context.cpp @@ -6,7 +6,7 @@ * * Copyright (C) 2013 Eric Greveson * - * This code is in public domain + * Released under GNU GPL, read the file 'COPYING' for more information */ #include "desktop.h" @@ -47,7 +47,7 @@ SPDocument *ActionContext::getDocument() const } // Should be the same as the view's document, if view is non-NULL - return _selection->layerModel()->getDocument(); + return _selection->layers()->getDocument(); } Selection *ActionContext::getSelection() const diff --git a/src/helper/action-context.h b/src/helper/action-context.h index 3a7a19112..bb538f413 100644 --- a/src/helper/action-context.h +++ b/src/helper/action-context.h @@ -6,7 +6,7 @@ * * Copyright (C) 2013 Eric Greveson * - * This code is in public domain + * Released under GNU GPL, read the file 'COPYING' for more information */ #ifndef SEEN_INKSCAPE_ACTION_CONTEXT_H diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 9f8dd984a..29cb208d9 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -542,11 +542,11 @@ void sp_edit_clear_all(Inkscape::Selection *selection) if (!selection) return; - SPDocument *doc = selection->layerModel()->getDocument(); + SPDocument *doc = selection->layers()->getDocument(); selection->clear(); - g_return_if_fail(SP_IS_GROUP(selection->layerModel()->currentLayer())); - GSList *items = sp_item_group_item_list(SP_GROUP(selection->layerModel()->currentLayer())); + g_return_if_fail(SP_IS_GROUP(selection->layers()->currentLayer())); + GSList *items = sp_item_group_item_list(SP_GROUP(selection->layers()->currentLayer())); while (items) { reinterpret_cast(items->data)->deleteObject(); @@ -739,7 +739,7 @@ static void sp_selection_group_impl(GSList *p, Inkscape::XML::Node *group, Inksc void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *doc = selection->layerModel()->getDocument(); + SPDocument *doc = selection->layers()->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); // Check if something is selected. @@ -816,7 +816,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) g_slist_free(items); - DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_UNGROUP, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); } @@ -942,14 +942,14 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) g_slist_free(rev); } - DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_RAISE, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, //TRANSLATORS: "Raise" means "to raise an object" in the undo history C_("Undo action", "Raise")); } void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layerModel()->getDocument(); + SPDocument *document = selection->layers()->getDocument(); if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); @@ -1031,13 +1031,13 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) g_slist_free(rev); } - DocumentUndo::done(selection->layerModel()->getDocument(), SP_VERB_SELECTION_LOWER, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, _("Lower")); } void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layerModel()->getDocument(); + SPDocument *document = selection->layers()->getDocument(); if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); @@ -2152,7 +2152,7 @@ sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) sp_selection_move_relative(selection, dx, dy); - SPDocument *doc = selection->layerModel()->getDocument(); + SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically")); @@ -2178,7 +2178,7 @@ sp_selection_move_screen(Inkscape::Selection *selection, gdouble dx, gdouble dy) gdouble const zdy = dy / zoom; sp_selection_move_relative(selection, zdx, zdy); - SPDocument *doc = selection->layerModel()->getDocument(); + SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically by pixels")); diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index ce2d1c90b..6ed8ca584 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -145,8 +145,8 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select _context.set(Inkscape::NORMAL_MESSAGE, _when_nothing); } else { SPItem *item = SP_ITEM(items->data); - SPObject *layer = selection->layerModel()->layerForObject(item); - SPObject *root = selection->layerModel()->currentRoot(); + SPObject *layer = selection->layers()->layerForObject(item); + SPObject *root = selection->layers()->currentRoot(); // Layer name gchar *layer_name; diff --git a/src/selection.cpp b/src/selection.cpp index 76f49f544..d018aba0c 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -41,11 +41,11 @@ namespace Inkscape { -Selection::Selection(LayerModel *layer_model, SPDesktop *desktop) : +Selection::Selection(LayerModel *layers, SPDesktop *desktop) : _objs(NULL), _reprs(NULL), _items(NULL), - _layer_model(layer_model), + _layers(layers), _desktop(desktop), _selection_context(NULL), _flags(0), @@ -55,7 +55,7 @@ Selection::Selection(LayerModel *layer_model, SPDesktop *desktop) : Selection::~Selection() { _clear(); - _layer_model = NULL; + _layers = NULL; if (_idle) { g_source_remove(_idle); _idle = 0; @@ -96,7 +96,7 @@ void Selection::_emitModified(guint flags) { void Selection::_emitChanged(bool persist_selection_context/* = false */) { if (persist_selection_context) { if (NULL == _selection_context) { - _selection_context = _layer_model->currentLayer(); + _selection_context = _layers->currentLayer(); sp_object_ref(_selection_context, NULL); _context_release_connection = _selection_context->connectRelease(sigc::mem_fun(*this, &Selection::_releaseContext)); } @@ -139,7 +139,7 @@ void Selection::_clear() { SPObject *Selection::activeContext() { if (NULL != _selection_context) return _selection_context; - return _layer_model->currentLayer(); + return _layers->currentLayer(); } bool Selection::includes(SPObject *obj) const { @@ -487,7 +487,7 @@ SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { g_return_val_if_fail(repr != NULL, NULL); gchar const *id = repr->attribute("id"); g_return_val_if_fail(id != NULL, NULL); - SPObject *object=_layer_model->getDocument()->getObjectById(id); + SPObject *object=_layers->getDocument()->getObjectById(id); g_return_val_if_fail(object != NULL, NULL); return object; } @@ -496,7 +496,7 @@ guint Selection::numberOfLayers() { GSList const *items = const_cast(this)->itemList(); GSList *layers = NULL; for (GSList const *iter = items; iter != NULL; iter = iter->next) { - SPObject *layer = _layer_model->layerForObject(SP_OBJECT(iter->data)); + SPObject *layer = _layers->layerForObject(SP_OBJECT(iter->data)); if (g_slist_find (layers, layer) == NULL) { layers = g_slist_prepend (layers, layer); } diff --git a/src/selection.h b/src/selection.h index 65a6c5140..f076cf7aa 100644 --- a/src/selection.h +++ b/src/selection.h @@ -67,10 +67,10 @@ public: * Constructs an selection object, bound to a particular * layer model * - * @param layer_model the layer model (for the SPDesktop, if GUI) + * @param layers the layer model (for the SPDesktop, if GUI) * @param desktop the desktop associated with the layer model, or NULL if in console mode */ - Selection(LayerModel *layer_model, SPDesktop *desktop); + Selection(LayerModel *layers, SPDesktop *desktop); ~Selection(); /** @@ -79,7 +79,7 @@ public: * @return the layer model the selection is bound to, which is the same as the desktop * layer model for GUI mode */ - LayerModel *layerModel() { return _layer_model; } + LayerModel *layers() { return _layers; } /** * Returns the desktop the selection is bound to @@ -352,7 +352,7 @@ private: std::list _3dboxes; - LayerModel *_layer_model; + LayerModel *_layers; GC::soft_ptr _desktop; SPObject* _selection_context; guint _flags; diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 0ec9da2a7..356cf0161 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -126,7 +126,7 @@ boolop_display_error_message(SPDesktop *desktop, Glib::ustring const &msg) void sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description) { - SPDocument *doc = selection->layerModel()->getDocument(); + SPDocument *doc = selection->layers()->getDocument(); GSList *il = (GSList *) selection->itemList(); // allow union on a single object for the purpose of removing self overlapse (svn log, revision 13334) diff --git a/src/verbs.cpp b/src/verbs.cpp index 2e6417ce1..1dae8bcf0 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -628,9 +628,13 @@ SPAction *Verb::get_action(Inkscape::ActionContext const & context) } /* static */ -void Verb::show_gui_required_message(SPAction *action) +bool Verb::ensure_desktop_valid(SPAction *action) { + if (sp_action_get_desktop(action) != NULL) { + return true; + } g_printerr("WARNING: ignoring verb %s - GUI required for this verb.\n", action->id); + return false; } void Verb::sensitive(SPDocument *in_doc, bool in_sensitive) @@ -827,12 +831,9 @@ void FileVerb::perform(SPAction *action, void *data) if (handled) { return; } - + + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *desktop = sp_action_get_desktop(action); - if (desktop == NULL) { - show_gui_required_message(action); - return; - } Gtk::Window *parent = desktop->getToplevel(); g_assert(parent != NULL); @@ -905,12 +906,9 @@ void EditVerb::perform(SPAction *action, void *data) if (handled) { return; } - + + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } switch (reinterpret_cast(data)) { case SP_VERB_EDIT_UNDO: @@ -1118,10 +1116,7 @@ void SelectionVerb::perform(SPAction *action, void *data) } // The remaining operations require a desktop - if (dt == NULL) { - show_gui_required_message(action); - return; - } + g_return_if_fail(ensure_desktop_valid(action)); g_assert(dt->_dlg_mgr != NULL); @@ -1200,13 +1195,10 @@ void SelectionVerb::perform(SPAction *action, void *data) */ void LayerVerb::perform(SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); size_t verb = reinterpret_cast(data); - if (dt == NULL) { - show_gui_required_message(action); - return; - } if ( !dt->currentLayer() ) { return; } @@ -1455,11 +1447,8 @@ void LayerVerb::perform(SPAction *action, void *data) */ void ObjectVerb::perform( SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } SPEventContext *ec = dt->event_context; @@ -1544,13 +1533,9 @@ void ContextVerb::perform(SPAction *action, void *data) SPDesktop *dt; sp_verb_t verb; int vidx; - - dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } + g_return_if_fail(ensure_desktop_valid(action)); + dt = sp_action_get_desktop(action); verb = (sp_verb_t)GPOINTER_TO_INT((gpointer)data); @@ -1748,11 +1733,8 @@ void ContextVerb::perform(SPAction *action, void *data) */ void TextVerb::perform(SPAction *action, void */*data*/) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } SPDocument *doc = sp_desktop_document(dt); (void)doc; @@ -1765,11 +1747,8 @@ void TextVerb::perform(SPAction *action, void */*data*/) */ void ZoomVerb::perform(SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } SPEventContext *ec = dt->event_context; SPDocument *doc = sp_desktop_document(dt); @@ -1956,12 +1935,9 @@ void DialogVerb::perform(SPAction *action, void *data) // unhide all when opening a new dialog inkscape_dialogs_unhide(); } - + + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } g_assert(dt->_dlg_mgr != NULL); switch (reinterpret_cast(data)) { @@ -2073,11 +2049,8 @@ void DialogVerb::perform(SPAction *action, void *data) */ void HelpVerb::perform(SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } g_assert(dt->_dlg_mgr != NULL); switch (reinterpret_cast(data)) { @@ -2112,10 +2085,7 @@ void HelpVerb::perform(SPAction *action, void *data) */ void TutorialVerb::perform(SPAction *action, void *data) { - if (sp_action_get_desktop(action) == NULL) { - show_gui_required_message(action); - return; - } + g_return_if_fail(ensure_desktop_valid(action)); switch (reinterpret_cast(data)) { case SP_VERB_TUTORIAL_BASIC: // TRANSLATORS: If you have translated the tutorial-basic.en.svgz file to your language, @@ -2197,14 +2167,9 @@ SPAction *EffectLastVerb::make_action(Inkscape::ActionContext const & context) */ void EffectLastVerb::perform(SPAction *action, void *data) { - // These aren't used, but are here to remind people not to use - // the CURRENT_DOCUMENT macros unless they really have to. + g_return_if_fail(ensure_desktop_valid(action)); Inkscape::UI::View::View *current_view = sp_action_get_view(action); - if (current_view == NULL) { - show_gui_required_message(action); - return; - } - // SPDocument *current_document = SP_VIEW_DOCUMENT(current_view); + Inkscape::Extension::Effect *effect = Inkscape::Extension::Effect::get_last_effect(); if (effect == NULL) return; @@ -2266,12 +2231,8 @@ SPAction *FitCanvasVerb::make_action(Inkscape::ActionContext const & context) */ void FitCanvasVerb::perform(SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } - SPDocument *doc = sp_desktop_document(dt); if (!doc) return; @@ -2336,12 +2297,8 @@ SPAction *LockAndHideVerb::make_action(Inkscape::ActionContext const & context) */ void LockAndHideVerb::perform(SPAction *action, void *data) { + g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - if (dt == NULL) { - show_gui_required_message(action); - return; - } - SPDocument *doc = sp_desktop_document(dt); if (!doc) return; diff --git a/src/verbs.h b/src/verbs.h index dd58134dd..053441b89 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -554,7 +554,7 @@ public: /** * Print a message to stderr indicating that this verb needs a GUI to run */ - static void show_gui_required_message(SPAction *action); + static bool ensure_desktop_valid(SPAction *action); static void delete_all_view (Inkscape::UI::View::View * view); void delete_view (Inkscape::UI::View::View * view); -- cgit v1.2.3 From 036013caefc09f34ef9b418e1ca148a821c777d6 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Thu, 4 Jul 2013 23:51:56 +0100 Subject: Further renaming of DBus variables (object -> app_interface/doc_interface and doc_context -> target) Fixes to application interface for document_new (now only works in console mode, and behaves as expected) (bzr r12387.1.8) --- src/extension/dbus/application-interface.cpp | 48 ++- src/extension/dbus/application-interface.h | 20 +- src/extension/dbus/application-interface.xml | 9 +- src/extension/dbus/dbus-init.cpp | 107 +++--- src/extension/dbus/document-interface.cpp | 474 +++++++++++++-------------- src/extension/dbus/document-interface.h | 166 +++++----- src/inkscape-private.h | 2 - src/inkscape.cpp | 17 +- src/inkscape.h | 10 + 9 files changed, 450 insertions(+), 403 deletions(-) (limited to 'src') diff --git a/src/extension/dbus/application-interface.cpp b/src/extension/dbus/application-interface.cpp index 1b1dbf0f5..c0bc19d90 100644 --- a/src/extension/dbus/application-interface.cpp +++ b/src/extension/dbus/application-interface.cpp @@ -19,6 +19,7 @@ #include #include "dbus-init.h" #include "file.h" +#include "inkscape.h" G_DEFINE_TYPE(ApplicationInterface, application_interface, G_TYPE_OBJECT) @@ -38,13 +39,32 @@ application_interface_class_init (ApplicationInterfaceClass *klass) } static void -application_interface_init (ApplicationInterface *object) +application_interface_init (ApplicationInterface *app_interface) { dbus_g_error_domain_register (INKSCAPE_ERROR, NULL, INKSCAPE_TYPE_ERROR); } +static bool +ensure_desktop_valid(GError **error) +{ + if (!inkscape_use_gui()) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires a GUI"); + return false; + } + return true; +} + +static bool +ensure_desktop_not_present(GError **error) +{ + if (inkscape_use_gui()) { + g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires non-GUI (command line) mode"); + return false; + } + return true; +} ApplicationInterface * application_interface_new (void) @@ -95,27 +115,28 @@ GType inkscape_error_get_type(void) ****************************************************************************/ gchar* -application_interface_desktop_new (ApplicationInterface *object, +application_interface_desktop_new (ApplicationInterface *app_interface, GError **error) { - return (gchar*)Inkscape::Extension::Dbus::init_desktop(); + g_return_val_if_fail(ensure_desktop_valid(error), NULL); + return (gchar*)Inkscape::Extension::Dbus::init_desktop(); } gchar** -application_interface_get_desktop_list (ApplicationInterface *object) +application_interface_get_desktop_list (ApplicationInterface *app_interface) { return NULL; } gchar* -application_interface_get_active_desktop (ApplicationInterface *object, +application_interface_get_active_desktop (ApplicationInterface *app_interface, GError **error) { return NULL; } gboolean -application_interface_set_active_desktop (ApplicationInterface *object, +application_interface_set_active_desktop (ApplicationInterface *app_interface, gchar* document_name, GError **error) { @@ -123,14 +144,14 @@ application_interface_set_active_desktop (ApplicationInterface *object, } gboolean -application_interface_desktop_close_all (ApplicationInterface *object, +application_interface_desktop_close_all (ApplicationInterface *app_interface, GError **error) { return TRUE; } gboolean -application_interface_exit (ApplicationInterface *object, GError **error) +application_interface_exit (ApplicationInterface *app_interface, GError **error) { sp_file_exit(); return TRUE; @@ -140,14 +161,15 @@ application_interface_exit (ApplicationInterface *object, GError **error) DOCUMENT FUNCTIONS ****************************************************************************/ -gchar* application_interface_document_new (ApplicationInterface *object, +gchar* application_interface_document_new (ApplicationInterface *app_interface, GError **error) { - return (gchar*)Inkscape::Extension::Dbus::init_document(); + g_return_val_if_fail(ensure_desktop_not_present(error), NULL); + return (gchar*)Inkscape::Extension::Dbus::init_document(); } gchar* -application_interface_get_active_document(ApplicationInterface *object, +application_interface_get_active_document(ApplicationInterface *app_interface, GError **error) { gchar *result = (gchar*)Inkscape::Extension::Dbus::init_active_document(); @@ -158,13 +180,13 @@ application_interface_get_active_document(ApplicationInterface *object, } gchar** -application_interface_get_document_list (ApplicationInterface *object) +application_interface_get_document_list (ApplicationInterface *app_interface) { return NULL; } gboolean -application_interface_document_close_all (ApplicationInterface *object, +application_interface_document_close_all (ApplicationInterface *app_interface, GError **error) { return TRUE; diff --git a/src/extension/dbus/application-interface.h b/src/extension/dbus/application-interface.h index b01fee912..c108402cb 100644 --- a/src/extension/dbus/application-interface.h +++ b/src/extension/dbus/application-interface.h @@ -67,45 +67,45 @@ GType inkscape_error_get_type (void); ****************************************************************************/ gchar* -application_interface_desktop_new (ApplicationInterface *object, +application_interface_desktop_new (ApplicationInterface *app_interface, GError **error); gchar** -application_interface_get_desktop_list (ApplicationInterface *object); +application_interface_get_desktop_list (ApplicationInterface *app_interface); gchar* -application_interface_get_active_desktop (ApplicationInterface *object, +application_interface_get_active_desktop (ApplicationInterface *app_interface, GError **error); gboolean -application_interface_set_active_desktop (ApplicationInterface *object, +application_interface_set_active_desktop (ApplicationInterface *app_interface, gchar* document_name, GError **error); gboolean -application_interface_desktop_close_all (ApplicationInterface *object, +application_interface_desktop_close_all (ApplicationInterface *app_interface, GError **error); gboolean -application_interface_exit (ApplicationInterface *object, GError **error); +application_interface_exit (ApplicationInterface *app_interface, GError **error); /**************************************************************************** DOCUMENT FUNCTIONS ****************************************************************************/ gchar* -application_interface_document_new (ApplicationInterface *object, +application_interface_document_new (ApplicationInterface *app_interface, GError **error); gchar* -application_interface_get_active_document(ApplicationInterface *object, +application_interface_get_active_document(ApplicationInterface *app_interface, GError **error); gchar** -application_interface_get_document_list (ApplicationInterface *object); +application_interface_get_document_list (ApplicationInterface *app_interface); gboolean -application_interface_document_close_all (ApplicationInterface *object, +application_interface_document_close_all (ApplicationInterface *app_interface, GError **error); diff --git a/src/extension/dbus/application-interface.xml b/src/extension/dbus/application-interface.xml index 4185c7e53..1553971cc 100644 --- a/src/extension/dbus/application-interface.xml +++ b/src/extension/dbus/application-interface.xml @@ -32,7 +32,7 @@ - Create a new document interface and return its location. + Create a new document interface and return its location. Only call this when Inkscape is running in GUI mode. @@ -45,21 +45,21 @@ - List all the interfaces that it is possible to connect to. + List all the interfaces that it is possible to connect to. TODO: not implemented. - Close all document interfaces without saving. + Close all document interfaces without saving. TODO: not implemented. - Exit Inkscape without saving (in GUI mode). Fairly straightforward. + Exit Inkscape without saving. Fairly straightforward. @@ -77,6 +77,7 @@ Originally, there were going to be two interfaces. A desktop and a document. Desktops would be used when the user wanted to see the result of their code and documents would be used when less overhead was desired. Unfortunately as more and more of the code can to rely on the desktop and it's associated support code (including selections and verbs) the document interface was looking more and more limited. Ultimately I decided to just go with the desktop interface since I didn't have a compelling reason for keeping the other one and having two similar interfaces could be very confusing. The desktop interface inherited the document name because I believe it's more familiar to people. Perhaps it would be best to have an option as to whether or not to create a window and fail with a good error message when they call a function that requires one. Or have a second interface for different use cases but have it be completely different, rather than a subset of the first if there are use cases that support it. UPDATE: 3rd July 2013, Eric Greveson: After having done some initial work to attempt to decouple Inkscape "verbs" from desktops, it is now possible to run a limited subset of actions in command-line mode (with a selection model and document, but no desktop). I believe that the "single document interface" approach, with some functions that may require a GUI, is the better path, and so document interfaces without a desktop are now possible. Most functions still require the desktop to work, though, with the notable exception of selection methods and Boolean operations. + As a result, this function should ONLY be called when using Inkscape in command-line mode. Use "desktop_new" instead if running in GUI mode. diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index fe59fc154..eb62f4b3a 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -78,6 +78,44 @@ dbus_register_object (DBusGConnection *connection, return object; } +/* + * PRIVATE register a document interface for the document in the given ActionContext, if none exists. + * Return the DBus path to the interface (something like /org/inkscape/document_0). + * Note that while a DocumentInterface could be used either for a document with no desktop, or a + * document with a desktop, this function is only used for creating interfaces in the former case. + * Desktop-associated DocumentInterfaces are named /org/inkscape/desktop_0, etc. + * FIXME: This state of affairs probably needs tidying up at some point in the future. + */ +static gchar * +dbus_register_document(Inkscape::ActionContext const & target) +{ + SPDocument *doc = target.getDocument(); + g_assert(doc != NULL); + + // Document name is not suitable for DBus name, as it might contain invalid chars + std::string name("/org/inkscape/document_"); + std::stringstream ss; + ss << doc->serial(); + name.append(ss.str()); + + DBusGConnection *connection = dbus_get_connection(); + DBusGProxy *proxy = dbus_get_proxy(connection); + + // Has the document already been registered? + if (!dbus_g_connection_lookup_g_object(connection, name.c_str())) { + // No - register it + DocumentInterface *doc_interface = (DocumentInterface*) dbus_register_object (connection, + proxy, + TYPE_DOCUMENT_INTERFACE, + &dbus_glib_document_interface_object_info, + name.c_str()); + + // Set the document info for this interface + doc_interface->target = target; + } + return strdup(name.c_str()); +} + /* Initialize a Dbus service */ void init (void) @@ -97,34 +135,19 @@ init (void) TYPE_APPLICATION_INTERFACE, &dbus_glib_application_interface_object_info, DBUS_APPLICATION_INTERFACE_PATH); -} //init +} gchar * -init_document (void) { - DBusGConnection *connection; - DBusGProxy *proxy; - SPDocument *doc; - - doc = SPDocument::createNewDoc(NULL, 1, TRUE); - - std::string name("/org/inkscape/"); - // This only works because a new document's name happens to contain - // only valid DBus characters [A-Z][a-z][0-9]_ - // TODO: use the document->serial() instead, like below, and similar to - // how desktops work? - name.append(doc->getName()); - std::replace(name.begin(), name.end(), ' ', '_'); - - connection = dbus_get_connection(); - proxy = dbus_get_proxy(connection); +init_document (void) +{ + // This is for command-line use only + g_assert(!inkscape_use_gui()); - dbus_register_object (connection, - proxy, - TYPE_DOCUMENT_INTERFACE, - &dbus_glib_document_interface_object_info, - name.c_str()); - return strdup(name.c_str()); -} //init_document + // Create a blank document and get its selection model etc in an ActionContext + SPDocument *doc = SPDocument::createNewDoc(NULL, 1, TRUE); + inkscape_add_document(doc); + return dbus_register_document(inkscape_action_context_for_document(doc)); +} gchar * init_active_document() @@ -134,28 +157,7 @@ init_active_document() return NULL; } - // Document name is not suitable for DBus name, as it might contain invalid chars - std::string name("/org/inkscape/document_"); - std::stringstream ss; - ss << doc->serial(); - name.append(ss.str()); - - DBusGConnection *connection = dbus_get_connection(); - DBusGProxy *proxy = dbus_get_proxy(connection); - - // Has the active document already been registered? - if (!dbus_g_connection_lookup_g_object(connection, name.c_str())) { - // No - register it - DocumentInterface *obj = (DocumentInterface*) dbus_register_object (connection, - proxy, - TYPE_DOCUMENT_INTERFACE, - &dbus_glib_document_interface_object_info, - name.c_str()); - - // Set the document info for this interface - obj->doc_context = inkscape_active_action_context(); - } - return strdup(name.c_str()); + return dbus_register_document(inkscape_active_action_context()); } gchar * @@ -163,7 +165,6 @@ dbus_init_desktop_interface (SPDesktop * dt) { DBusGConnection *connection; DBusGProxy *proxy; - DocumentInterface *obj; std::string name("/org/inkscape/desktop_"); std::stringstream out; @@ -175,12 +176,12 @@ dbus_init_desktop_interface (SPDesktop * dt) connection = dbus_get_connection(); proxy = dbus_get_proxy(connection); - obj = (DocumentInterface*) dbus_register_object (connection, + DocumentInterface *doc_interface = (DocumentInterface*) dbus_register_object (connection, proxy, TYPE_DOCUMENT_INTERFACE, &dbus_glib_document_interface_object_info, name.c_str()); - obj->doc_context = Inkscape::ActionContext(dt); - obj->updates = TRUE; - dt->dbus_document_interface=obj; + doc_interface->target = Inkscape::ActionContext(dt); + doc_interface->updates = TRUE; + dt->dbus_document_interface=doc_interface; return strdup(name.c_str()); } @@ -195,7 +196,7 @@ init_desktop (void) { out << dt->dkey; name.append(out.str()); return strdup(name.c_str()); -} //init_desktop +} diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index 6d6f983c5..3cb03646a 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -221,11 +221,11 @@ dbus_create_node (SPDocument *doc, const gchar *type) * There is probably a better way to do this (use the shape tools default styles) * but I'm not sure how. */ -gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inkscape::XML::Node *newNode, gchar *desc) +gchar *finish_create_shape (DocumentInterface *doc_interface, GError ** /*error*/, Inkscape::XML::Node *newNode, gchar *desc) { SPCSSAttr *style = NULL; - if (object->doc_context.getDesktop()) { - style = sp_desktop_get_style(object->doc_context.getDesktop(), TRUE); + if (doc_interface->target.getDesktop()) { + style = sp_desktop_get_style(doc_interface->target.getDesktop(), TRUE); } if (style) { Glib::ustring str; @@ -236,11 +236,11 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks newNode->setAttribute("style", "fill:#0000ff;fill-opacity:1;stroke:#c900b9;stroke-width:0;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none", TRUE); } - object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); - object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); + doc_interface->target.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + doc_interface->target.getSelection()->layers()->currentLayer()->updateRepr(); - if (object->updates) { - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), 0, (gchar *)desc); + if (doc_interface->updates) { + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), 0, (gchar *)desc); } return strdup(newNode->attribute("id")); @@ -255,19 +255,19 @@ gchar *finish_create_shape (DocumentInterface *object, GError ** /*error*/, Inks * document_interface_call_verb is similar but is called by the user. */ gboolean -dbus_call_verb (DocumentInterface *object, int verbid, GError **error) +dbus_call_verb (DocumentInterface *doc_interface, int verbid, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); if ( desk ) { desktop_ensure_active (desk); } Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); if ( verb ) { - SPAction *action = verb->get_action(object->doc_context); + SPAction *action = verb->get_action(doc_interface->target); if ( action ) { sp_action_perform( action, NULL ); - if (object->updates) - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + if (doc_interface->updates) + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); return TRUE; } } @@ -319,9 +319,9 @@ document_interface_class_init (DocumentInterfaceClass *klass) } static void -document_interface_init (DocumentInterface *object) +document_interface_init (DocumentInterface *doc_interface) { - object->doc_context = Inkscape::ActionContext(); + doc_interface->target = Inkscape::ActionContext(); } @@ -337,26 +337,26 @@ document_interface_new (void) MISC FUNCTIONS ****************************************************************************/ -gboolean document_interface_delete_all(DocumentInterface *object, GError ** /*error*/) +gboolean document_interface_delete_all(DocumentInterface *doc_interface, GError ** /*error*/) { - sp_edit_clear_all(object->doc_context.getSelection()); + sp_edit_clear_all(doc_interface->target.getSelection()); return TRUE; } gboolean -document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error) +document_interface_call_verb (DocumentInterface *doc_interface, gchar *verbid, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); if ( desk ) { desktop_ensure_active (desk); } Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid ); if ( verb ) { - SPAction *action = verb->get_action(object->doc_context); + SPAction *action = verb->get_action(doc_interface->target); if ( action ) { sp_action_perform( action, NULL ); - if (object->updates) { - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + if (doc_interface->updates) { + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); } return TRUE; } @@ -371,39 +371,39 @@ document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError * ****************************************************************************/ gchar* -document_interface_rectangle (DocumentInterface *object, int x, int y, +document_interface_rectangle (DocumentInterface *doc_interface, int x, int y, int width, int height, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:rect"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:rect"); sp_repr_set_int(newNode, "x", x); //could also use newNode->setAttribute() sp_repr_set_int(newNode, "y", y); sp_repr_set_int(newNode, "width", width); sp_repr_set_int(newNode, "height", height); - return finish_create_shape (object, error, newNode, (gchar *)"create rectangle"); + return finish_create_shape (doc_interface, error, newNode, (gchar *)"create rectangle"); } gchar* -document_interface_ellipse_center (DocumentInterface *object, int cx, int cy, +document_interface_ellipse_center (DocumentInterface *doc_interface, int cx, int cy, int rx, int ry, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "arc"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); sp_repr_set_int(newNode, "sodipodi:rx", rx); sp_repr_set_int(newNode, "sodipodi:ry", ry); - return finish_create_shape (object, error, newNode, (gchar *)"create circle"); + return finish_create_shape (doc_interface, error, newNode, (gchar *)"create circle"); } gchar* -document_interface_polygon (DocumentInterface *object, int cx, int cy, +document_interface_polygon (DocumentInterface *doc_interface, int cx, int cy, int radius, int rotation, int sides, GError **error) { gdouble rot = ((rotation / 180.0) * 3.14159265) - ( 3.14159265 / 2.0); - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "true"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -416,15 +416,15 @@ document_interface_polygon (DocumentInterface *object, int cx, int cy, sp_repr_set_svg_double(newNode, "sodipodi:arg2", rot); sp_repr_set_svg_double(newNode, "inkscape:rounded", 0); - return finish_create_shape (object, error, newNode, (gchar *)"create polygon"); + return finish_create_shape (doc_interface, error, newNode, (gchar *)"create polygon"); } gchar* -document_interface_star (DocumentInterface *object, int cx, int cy, +document_interface_star (DocumentInterface *doc_interface, int cx, int cy, int r1, int r2, int sides, gdouble rounded, gdouble arg1, gdouble arg2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:path"); newNode->setAttribute("inkscape:flatsided", "false"); newNode->setAttribute("sodipodi:type", "star"); sp_repr_set_int(newNode, "sodipodi:cx", cx); @@ -437,35 +437,35 @@ document_interface_star (DocumentInterface *object, int cx, int cy, sp_repr_set_svg_double(newNode, "sodipodi:arg2", arg2); sp_repr_set_svg_double(newNode, "inkscape:rounded", rounded); - return finish_create_shape (object, error, newNode, (gchar *)"create star"); + return finish_create_shape (doc_interface, error, newNode, (gchar *)"create star"); } gchar* -document_interface_ellipse (DocumentInterface *object, int x, int y, +document_interface_ellipse (DocumentInterface *doc_interface, int x, int y, int width, int height, GError **error) { int rx = width/2; int ry = height/2; - return document_interface_ellipse_center (object, x+rx, y+ry, rx, ry, error); + return document_interface_ellipse_center (doc_interface, x+rx, y+ry, rx, ry, error); } gchar* -document_interface_line (DocumentInterface *object, int x, int y, +document_interface_line (DocumentInterface *doc_interface, int x, int y, int x2, int y2, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:path"); std::stringstream out; // Not sure why this works. out << "m " << x << "," << y << " " << x2 - x << "," << y2 - y; newNode->setAttribute("d", out.str().c_str()); - return finish_create_shape (object, error, newNode, (gchar *)"create line"); + return finish_create_shape (doc_interface, error, newNode, (gchar *)"create line"); } gchar* -document_interface_spiral (DocumentInterface *object, int cx, int cy, +document_interface_spiral (DocumentInterface *doc_interface, int cx, int cy, int r, int revolutions, GError **error) { - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:path"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:path"); newNode->setAttribute("sodipodi:type", "spiral"); sp_repr_set_int(newNode, "sodipodi:cx", cx); sp_repr_set_int(newNode, "sodipodi:cy", cy); @@ -474,7 +474,7 @@ document_interface_spiral (DocumentInterface *object, int cx, int cy, sp_repr_set_int(newNode, "sodipodi:t0", 0); sp_repr_set_int(newNode, "sodipodi:argument", 0); sp_repr_set_int(newNode, "sodipodi:expansion", 1); - gchar * retval = finish_create_shape (object, error, newNode, (gchar *)"create spiral"); + gchar * retval = finish_create_shape (doc_interface, error, newNode, (gchar *)"create spiral"); //Makes sure there is no fill for spirals by default. gchar* newString = g_strconcat(newNode->attribute("style"), ";fill:none", NULL); newNode->setAttribute("style", newString); @@ -483,54 +483,54 @@ document_interface_spiral (DocumentInterface *object, int cx, int cy, } gchar* -document_interface_text (DocumentInterface *object, int x, int y, gchar *text, GError **error) +document_interface_text (DocumentInterface *doc_interface, int x, int y, gchar *text, GError **error) { - Inkscape::XML::Node *text_node = dbus_create_node(object->doc_context.getDocument(), "svg:text"); + Inkscape::XML::Node *text_node = dbus_create_node(doc_interface->target.getDocument(), "svg:text"); sp_repr_set_int(text_node, "x", x); sp_repr_set_int(text_node, "y", y); //just a workaround so i can get an spitem from the name - gchar *name = finish_create_shape (object, error, text_node, (gchar *)"create text"); + gchar *name = finish_create_shape (doc_interface, error, text_node, (gchar *)"create text"); - SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(doc_interface->target.getDocument(), name, error); sp_te_set_repr_text_multiline(text_obj, text); return name; } gchar * -document_interface_image (DocumentInterface *object, int x, int y, gchar *filename, GError **error) +document_interface_image (DocumentInterface *doc_interface, int x, int y, gchar *filename, GError **error) { gchar * uri = g_filename_to_uri (filename, FALSE, error); if (!uri) return FALSE; - Inkscape::XML::Node *newNode = dbus_create_node(object->doc_context.getDocument(), "svg:image"); + Inkscape::XML::Node *newNode = dbus_create_node(doc_interface->target.getDocument(), "svg:image"); sp_repr_set_int(newNode, "x", x); sp_repr_set_int(newNode, "y", y); newNode->setAttribute("xlink:href", uri); - object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); - object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); + doc_interface->target.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + doc_interface->target.getSelection()->layers()->currentLayer()->updateRepr(); - if (object->updates) - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), 0, "Imported bitmap."); + if (doc_interface->updates) + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), 0, "Imported bitmap."); //g_free(uri); return strdup(newNode->attribute("id")); } -gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** /*error*/) +gchar *document_interface_node(DocumentInterface *doc_interface, gchar *type, GError ** /*error*/) { - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *newNode = xml_doc->createElement(type); - object->doc_context.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); - object->doc_context.getSelection()->layers()->currentLayer()->updateRepr(); + doc_interface->target.getSelection()->layers()->currentLayer()->appendChildRepr(newNode); + doc_interface->target.getSelection()->layers()->currentLayer()->updateRepr(); - if (object->updates) { + if (doc_interface->updates) { Inkscape::DocumentUndo::done(doc, 0, (gchar *)"created empty node"); } @@ -541,20 +541,20 @@ gchar *document_interface_node(DocumentInterface *object, gchar *type, GError ** ENVIRONMENT FUNCTIONS ****************************************************************************/ gdouble -document_interface_document_get_width (DocumentInterface *object) +document_interface_document_get_width (DocumentInterface *doc_interface) { - return object->doc_context.getDocument()->getWidth(); + return doc_interface->target.getDocument()->getWidth(); } gdouble -document_interface_document_get_height (DocumentInterface *object) +document_interface_document_get_height (DocumentInterface *doc_interface) { - return object->doc_context.getDocument()->getHeight(); + return doc_interface->target.getDocument()->getHeight(); } -gchar *document_interface_document_get_css(DocumentInterface *object, GError ** error) +gchar *document_interface_document_get_css(DocumentInterface *doc_interface, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), NULL); SPCSSAttr *current = desk->current; Glib::ustring str; @@ -562,10 +562,10 @@ gchar *document_interface_document_get_css(DocumentInterface *object, GError ** return (str.empty() ? NULL : g_strdup (str.c_str())); } -gboolean document_interface_document_merge_css(DocumentInterface *object, +gboolean document_interface_document_merge_css(DocumentInterface *doc_interface, gchar *stylestring, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(style, stylestring); @@ -573,10 +573,10 @@ gboolean document_interface_document_merge_css(DocumentInterface *object, return TRUE; } -gboolean document_interface_document_set_css(DocumentInterface *object, +gboolean document_interface_document_set_css(DocumentInterface *doc_interface, gchar *stylestring, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); SPCSSAttr * style = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string (style, stylestring); @@ -586,14 +586,14 @@ gboolean document_interface_document_set_css(DocumentInterface *object, } gboolean -document_interface_document_resize_to_fit_selection (DocumentInterface *object, +document_interface_document_resize_to_fit_selection (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_FIT_CANVAS_TO_SELECTION, error); + return dbus_call_verb (doc_interface, SP_VERB_FIT_CANVAS_TO_SELECTION, error); } gboolean -document_interface_document_set_display_area (DocumentInterface *object, +document_interface_document_set_display_area (DocumentInterface *doc_interface, double x0, double y0, double x1, @@ -601,7 +601,7 @@ document_interface_document_set_display_area (DocumentInterface *object, double border, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); desk->set_display_area (x0, y0, @@ -613,9 +613,9 @@ document_interface_document_set_display_area (DocumentInterface *object, GArray * -document_interface_document_get_display_area (DocumentInterface *object) +document_interface_document_get_display_area (DocumentInterface *doc_interface) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); if (!desk) { return NULL; } @@ -641,10 +641,10 @@ document_interface_document_get_display_area (DocumentInterface *object) ****************************************************************************/ gboolean -document_interface_set_attribute (DocumentInterface *object, char *shape, +document_interface_set_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, char *newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(doc_interface->target.getDocument(), shape, error); /* ALTERNATIVE (is this faster?) Inkscape::XML::Node *newnode = sp_repr_lookup_name((doc->root)->repr, name); @@ -660,11 +660,11 @@ document_interface_set_attribute (DocumentInterface *object, char *shape, } gboolean -document_interface_set_int_attribute (DocumentInterface *object, +document_interface_set_int_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, int newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (doc_interface->target.getDocument(), shape, error); if (!newNode) return FALSE; @@ -674,11 +674,11 @@ document_interface_set_int_attribute (DocumentInterface *object, gboolean -document_interface_set_double_attribute (DocumentInterface *object, +document_interface_set_double_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, double newval, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name (object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name (doc_interface->target.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "New value string was empty.")) return FALSE; @@ -690,10 +690,10 @@ document_interface_set_double_attribute (DocumentInterface *object, } gchar * -document_interface_get_attribute (DocumentInterface *object, char *shape, +document_interface_get_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, GError **error) { - Inkscape::XML::Node *newNode = get_repr_by_name(object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *newNode = get_repr_by_name(doc_interface->target.getDocument(), shape, error); if (!dbus_check_string (attribute, error, "Attribute name empty.")) return NULL; @@ -704,47 +704,47 @@ document_interface_get_attribute (DocumentInterface *object, char *shape, } gboolean -document_interface_move (DocumentInterface *object, gchar *name, gdouble x, +document_interface_move (DocumentInterface *doc_interface, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->doc_context.getSelection(), name, error); + const GSList *oldsel = selection_swap(doc_interface->target.getSelection(), name, error); if (!oldsel) return FALSE; - sp_selection_move (object->doc_context.getSelection(), x, 0 - y); - selection_restore(object->doc_context.getSelection(), oldsel); + sp_selection_move (doc_interface->target.getSelection(), x, 0 - y); + selection_restore(doc_interface->target.getSelection(), oldsel); return TRUE; } gboolean -document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x, +document_interface_move_to (DocumentInterface *doc_interface, gchar *name, gdouble x, gdouble y, GError **error) { - const GSList *oldsel = selection_swap(object->doc_context.getSelection(), name, error); + const GSList *oldsel = selection_swap(doc_interface->target.getSelection(), name, error); if (!oldsel) return FALSE; - Inkscape::Selection * sel = object->doc_context.getSelection(); - sp_selection_move (object->doc_context.getSelection(), x - selection_get_center_x(sel), + Inkscape::Selection * sel = doc_interface->target.getSelection(); + sp_selection_move (doc_interface->target.getSelection(), x - selection_get_center_x(sel), 0 - (y - selection_get_center_y(sel))); - selection_restore(object->doc_context.getSelection(), oldsel); + selection_restore(doc_interface->target.getSelection(), oldsel); return TRUE; } gboolean -document_interface_object_to_path (DocumentInterface *object, +document_interface_object_to_path (DocumentInterface *doc_interface, char *shape, GError **error) { - const GSList *oldsel = selection_swap(object->doc_context.getSelection(), shape, error); + const GSList *oldsel = selection_swap(doc_interface->target.getSelection(), shape, error); if (!oldsel) return FALSE; - dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); - selection_restore(object->doc_context.getSelection(), oldsel); + dbus_call_verb (doc_interface, SP_VERB_OBJECT_TO_CURVE, error); + selection_restore(doc_interface->target.getSelection(), oldsel); return TRUE; } gchar * -document_interface_get_path (DocumentInterface *object, char *pathname, GError **error) +document_interface_get_path (DocumentInterface *doc_interface, char *pathname, GError **error) { - Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), pathname, error); + Inkscape::XML::Node *node = get_repr_by_name(doc_interface->target.getDocument(), pathname, error); if (!node) return NULL; @@ -758,30 +758,30 @@ document_interface_get_path (DocumentInterface *object, char *pathname, GError * } gboolean -document_interface_transform (DocumentInterface *object, gchar *shape, +document_interface_transform (DocumentInterface *doc_interface, gchar *shape, gchar *transformstr, GError **error) { //FIXME: This should merge transformations. gchar trans[] = "transform"; - document_interface_set_attribute (object, shape, trans, transformstr, error); + document_interface_set_attribute (doc_interface, shape, trans, transformstr, error); return TRUE; } gchar * -document_interface_get_css (DocumentInterface *object, gchar *shape, +document_interface_get_css (DocumentInterface *doc_interface, gchar *shape, GError **error) { gchar style[] = "style"; - return document_interface_get_attribute (object, shape, style, error); + return document_interface_get_attribute (doc_interface, shape, style, error); } gboolean -document_interface_modify_css (DocumentInterface *object, gchar *shape, +document_interface_modify_css (DocumentInterface *doc_interface, gchar *shape, gchar *cssattrb, gchar *newval, GError **error) { // Doesn't like non-variable strings for some reason. gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *node = get_repr_by_name(doc_interface->target.getDocument(), shape, error); if (!dbus_check_string (cssattrb, error, "Attribute string empty.")) return FALSE; @@ -797,12 +797,12 @@ document_interface_modify_css (DocumentInterface *object, gchar *shape, } gboolean -document_interface_merge_css (DocumentInterface *object, gchar *shape, +document_interface_merge_css (DocumentInterface *doc_interface, gchar *shape, gchar *stylestring, GError **error) { gchar style[] = "style"; - Inkscape::XML::Node *node = get_repr_by_name(object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *node = get_repr_by_name(doc_interface->target.getDocument(), shape, error); if (!dbus_check_string (stylestring, error, "Style string empty.")) return FALSE; @@ -823,7 +823,7 @@ document_interface_merge_css (DocumentInterface *object, gchar *shape, } gboolean -document_interface_set_color (DocumentInterface *object, gchar *shape, +document_interface_set_color (DocumentInterface *doc_interface, gchar *shape, int r, int g, int b, gboolean fill, GError **error) { gchar style[15]; @@ -839,29 +839,29 @@ document_interface_set_color (DocumentInterface *object, gchar *shape, snprintf(style, 15, "stroke:#%.2x%.2x%.2x", r, g, b); if (strcmp(shape, "document") == 0) - return document_interface_document_merge_css (object, style, error); + return document_interface_document_merge_css (doc_interface, style, error); - return document_interface_merge_css (object, shape, style, error); + return document_interface_merge_css (doc_interface, shape, style, error); } gboolean -document_interface_move_to_layer (DocumentInterface *object, gchar *shape, +document_interface_move_to_layer (DocumentInterface *doc_interface, gchar *shape, gchar *layerstr, GError **error) { - const GSList *oldsel = selection_swap(object->doc_context.getSelection(), shape, error); + const GSList *oldsel = selection_swap(doc_interface->target.getSelection(), shape, error); if (!oldsel) return FALSE; - document_interface_selection_move_to_layer(object, layerstr, error); - selection_restore(object->doc_context.getSelection(), oldsel); + document_interface_selection_move_to_layer(doc_interface, layerstr, error); + selection_restore(doc_interface->target.getSelection(), oldsel); return TRUE; } -GArray *document_interface_get_node_coordinates(DocumentInterface * /*object*/, gchar * /*shape*/) +GArray *document_interface_get_node_coordinates(DocumentInterface * /*doc_interface*/, gchar * /*shape*/) { //FIXME: Needs lot's of work. /* - Inkscape::XML::Node *shapenode = get_repr_by_name (object->doc_context.getDocument(), shape, error); + Inkscape::XML::Node *shapenode = get_repr_by_name (doc_interface->target.getDocument(), shape, error); if (shapenode == NULL || shapenode->attribute("d") == NULL) { return FALSE; } @@ -876,10 +876,10 @@ GArray *document_interface_get_node_coordinates(DocumentInterface * /*object*/, gboolean -document_interface_set_text (DocumentInterface *object, gchar *name, gchar *text, GError **error) +document_interface_set_text (DocumentInterface *doc_interface, gchar *name, gchar *text, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(doc_interface->target.getDocument(), name, error); //TODO verify object type if (!text_obj) return FALSE; @@ -891,12 +891,12 @@ document_interface_set_text (DocumentInterface *object, gchar *name, gchar *text gboolean -document_interface_text_apply_style (DocumentInterface *object, gchar *name, +document_interface_text_apply_style (DocumentInterface *doc_interface, gchar *name, int start_pos, int end_pos, gchar *style, gchar *styleval, GError **error) { - SPItem* text_obj=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); + SPItem* text_obj=(SPItem* )get_object_by_name(doc_interface->target.getDocument(), name, error); //void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPCSSAttr const *css) //TODO verify object type @@ -923,40 +923,40 @@ document_interface_text_apply_style (DocumentInterface *object, gchar *name, ****************************************************************************/ gboolean -document_interface_save (DocumentInterface *object, GError **error) +document_interface_save (DocumentInterface *doc_interface, GError **error) { - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); printf("1: %s\n2: %s\n3: %s\n", doc->getURI(), doc->getBase(), doc->getName()); if (doc->getURI()) - return document_interface_save_as (object, doc->getURI(), error); + return document_interface_save_as (doc_interface, doc->getURI(), error); return FALSE; } -gboolean document_interface_load(DocumentInterface *object, +gboolean document_interface_load(DocumentInterface *doc_interface, gchar *filename, GError ** /*error*/) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); if (desk) { desktop_ensure_active(desk); } const Glib::ustring file(filename); sp_file_open(file, NULL, TRUE, TRUE); - if (object->updates) { - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), SP_VERB_FILE_OPEN, "Opened File"); + if (doc_interface->updates) { + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), SP_VERB_FILE_OPEN, "Opened File"); } return TRUE; } gchar * -document_interface_import (DocumentInterface *object, +document_interface_import (DocumentInterface *doc_interface, gchar *filename, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); if (desk) { desktop_ensure_active(desk); } const Glib::ustring file(filename); - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); SPObject *new_obj = NULL; new_obj = file_import(doc, file, NULL); @@ -964,11 +964,11 @@ document_interface_import (DocumentInterface *object, } gboolean -document_interface_save_as (DocumentInterface *object, +document_interface_save_as (DocumentInterface *doc_interface, const gchar *filename, GError **error) { // FIXME: Isn't there a verb we can use for this instead? - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); #ifdef WITH_GNOME_VFS const Glib::ustring file(filename); return file_save_remote(doc, file, NULL, TRUE, TRUE); @@ -988,9 +988,9 @@ document_interface_save_as (DocumentInterface *object, return true; } -gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError ** /*error*/) +gboolean document_interface_mark_as_unmodified(DocumentInterface *doc_interface, GError ** /*error*/) { - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); if (doc) { doc->modified_since_save = FALSE; } @@ -999,9 +999,9 @@ gboolean document_interface_mark_as_unmodified(DocumentInterface *object, GError /* gboolean -document_interface_print_to_file (DocumentInterface *object, GError **error) +document_interface_print_to_file (DocumentInterface *doc_interface, GError **error) { - SPDocument * doc = object->doc_context.getDocument(); + SPDocument * doc = doc_interface->target.getDocument(); sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf")); return TRUE; @@ -1012,27 +1012,27 @@ document_interface_print_to_file (DocumentInterface *object, GError **error) ****************************************************************************/ gboolean -document_interface_close (DocumentInterface *object, GError **error) +document_interface_close (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error); + return dbus_call_verb (doc_interface, SP_VERB_FILE_CLOSE_VIEW, error); } gboolean -document_interface_exit (DocumentInterface *object, GError **error) +document_interface_exit (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_FILE_QUIT, error); + return dbus_call_verb (doc_interface, SP_VERB_FILE_QUIT, error); } gboolean -document_interface_undo (DocumentInterface *object, GError **error) +document_interface_undo (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_UNDO, error); } gboolean -document_interface_redo (DocumentInterface *object, GError **error) +document_interface_redo (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_REDO, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_REDO, error); } @@ -1044,29 +1044,29 @@ document_interface_redo (DocumentInterface *object, GError **error) Need to make sure it plays well with verbs because they are used so much. ****************************************************************************/ -void document_interface_pause_updates(DocumentInterface *object, GError ** error) +void document_interface_pause_updates(DocumentInterface *doc_interface, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_if_fail(ensure_desktop_valid(desk, error)); - object->updates = FALSE; + doc_interface->updates = FALSE; desk->canvas->drawing_disabled = 1; } -void document_interface_resume_updates(DocumentInterface *object, GError ** error) +void document_interface_resume_updates(DocumentInterface *doc_interface, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_if_fail(ensure_desktop_valid(desk, error)); - object->updates = TRUE; + doc_interface->updates = TRUE; desk->canvas->drawing_disabled = 0; //FIXME: use better verb than rect. - Inkscape::DocumentUndo::done(object->doc_context.getDocument(), SP_VERB_CONTEXT_RECT, "Multiple actions"); + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), SP_VERB_CONTEXT_RECT, "Multiple actions"); } -void document_interface_update(DocumentInterface *object, GError ** error) +void document_interface_update(DocumentInterface *doc_interface, GError ** error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_if_fail(ensure_desktop_valid(desk, error)); - SPDocument *doc = object->doc_context.getDocument(); + SPDocument *doc = doc_interface->target.getDocument(); doc->getRoot()->uflags = TRUE; doc->getRoot()->mflags = TRUE; desk->enableInteraction(); @@ -1081,9 +1081,9 @@ void document_interface_update(DocumentInterface *object, GError ** error) SELECTION FUNCTIONS FIXME: use call_verb where appropriate (once update system is tested.) ****************************************************************************/ -gboolean document_interface_selection_get(DocumentInterface *object, char ***out, GError ** /*error*/) +gboolean document_interface_selection_get(DocumentInterface *doc_interface, char ***out, GError ** /*error*/) { - Inkscape::Selection * sel = object->doc_context.getSelection(); + Inkscape::Selection * sel = doc_interface->target.getSelection(); GSList const *oldsel = sel->list(); int size = g_slist_length((GSList *) oldsel); @@ -1101,82 +1101,82 @@ gboolean document_interface_selection_get(DocumentInterface *object, char ***out } gboolean -document_interface_selection_add (DocumentInterface *object, char *name, GError **error) +document_interface_selection_add (DocumentInterface *doc_interface, char *name, GError **error) { - SPObject * obj = get_object_by_name(object->doc_context.getDocument(), name, error); + SPObject * obj = get_object_by_name(doc_interface->target.getDocument(), name, error); if (!obj) return FALSE; - Inkscape::Selection *selection = object->doc_context.getSelection(); + Inkscape::Selection *selection = doc_interface->target.getSelection(); selection->add(obj); return TRUE; } gboolean -document_interface_selection_add_list (DocumentInterface *object, +document_interface_selection_add_list (DocumentInterface *doc_interface, char **names, GError **error) { int i; for (i=0;names[i] != NULL;i++) { - document_interface_selection_add(object, names[i], error); + document_interface_selection_add(doc_interface, names[i], error); } return TRUE; } -gboolean document_interface_selection_set(DocumentInterface *object, char *name, GError ** /*error*/) +gboolean document_interface_selection_set(DocumentInterface *doc_interface, char *name, GError ** /*error*/) { - SPDocument * doc = object->doc_context.getDocument(); - Inkscape::Selection *selection = object->doc_context.getSelection(); + SPDocument * doc = doc_interface->target.getDocument(); + Inkscape::Selection *selection = doc_interface->target.getSelection(); selection->set(doc->getObjectById(name)); return TRUE; } gboolean -document_interface_selection_set_list (DocumentInterface *object, +document_interface_selection_set_list (DocumentInterface *doc_interface, gchar **names, GError **error) { - object->doc_context.getSelection()->clear(); + doc_interface->target.getSelection()->clear(); int i; for (i=0;names[i] != NULL;i++) { - document_interface_selection_add(object, names[i], error); + document_interface_selection_add(doc_interface, names[i], error); } return TRUE; } -gboolean document_interface_selection_rotate(DocumentInterface *object, int angle, GError ** /*error*/) +gboolean document_interface_selection_rotate(DocumentInterface *doc_interface, int angle, GError ** /*error*/) { - Inkscape::Selection *selection = object->doc_context.getSelection(); + Inkscape::Selection *selection = doc_interface->target.getSelection(); sp_selection_rotate(selection, angle); return TRUE; } gboolean -document_interface_selection_delete (DocumentInterface *object, GError **error) +document_interface_selection_delete (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_DELETE, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_DELETE, error); } -gboolean document_interface_selection_clear(DocumentInterface *object, GError ** /*error*/) +gboolean document_interface_selection_clear(DocumentInterface *doc_interface, GError ** /*error*/) { - object->doc_context.getSelection()->clear(); + doc_interface->target.getSelection()->clear(); return TRUE; } gboolean -document_interface_select_all (DocumentInterface *object, GError **error) +document_interface_select_all (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_SELECT_ALL, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_SELECT_ALL, error); } gboolean -document_interface_select_all_in_all_layers(DocumentInterface *object, +document_interface_select_all_in_all_layers(DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS, error); } -gboolean document_interface_selection_box(DocumentInterface * /*object*/, int /*x*/, int /*y*/, +gboolean document_interface_selection_box(DocumentInterface * /*doc_interface*/, int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, gboolean /*replace*/, GError ** /*error*/) { @@ -1185,49 +1185,49 @@ gboolean document_interface_selection_box(DocumentInterface * /*object*/, int /* } gboolean -document_interface_selection_invert (DocumentInterface *object, GError **error) +document_interface_selection_invert (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_EDIT_INVERT, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_INVERT, error); } gboolean -document_interface_selection_group (DocumentInterface *object, GError **error) +document_interface_selection_group (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_SELECTION_GROUP, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_GROUP, error); } gboolean -document_interface_selection_ungroup (DocumentInterface *object, GError **error) +document_interface_selection_ungroup (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_SELECTION_UNGROUP, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_UNGROUP, error); } gboolean -document_interface_selection_cut (DocumentInterface *object, GError **error) +document_interface_selection_cut (DocumentInterface *doc_interface, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); - return dbus_call_verb (object, SP_VERB_EDIT_CUT, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_CUT, error); } gboolean -document_interface_selection_copy (DocumentInterface *object, GError **error) +document_interface_selection_copy (DocumentInterface *doc_interface, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); - return dbus_call_verb (object, SP_VERB_EDIT_COPY, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_COPY, error); } gboolean -document_interface_selection_paste (DocumentInterface *object, GError **error) +document_interface_selection_paste (DocumentInterface *doc_interface, GError **error) { - SPDesktop *desk = object->doc_context.getDesktop(); + SPDesktop *desk = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(desk, error), FALSE); - return dbus_call_verb (object, SP_VERB_EDIT_PASTE, error); + return dbus_call_verb (doc_interface, SP_VERB_EDIT_PASTE, error); } -gboolean document_interface_selection_scale(DocumentInterface *object, gdouble grow, GError ** /*error*/) +gboolean document_interface_selection_scale(DocumentInterface *doc_interface, gdouble grow, GError ** /*error*/) { - Inkscape::Selection *selection = object->doc_context.getSelection(); + Inkscape::Selection *selection = doc_interface->target.getSelection(); if (!selection) { return FALSE; @@ -1236,15 +1236,15 @@ gboolean document_interface_selection_scale(DocumentInterface *object, gdouble g return TRUE; } -gboolean document_interface_selection_move(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) +gboolean document_interface_selection_move(DocumentInterface *doc_interface, gdouble x, gdouble y, GError ** /*error*/) { - sp_selection_move(object->doc_context.getSelection(), x, 0 - y); //switching coordinate systems. + sp_selection_move(doc_interface->target.getSelection(), x, 0 - y); //switching coordinate systems. return TRUE; } -gboolean document_interface_selection_move_to(DocumentInterface *object, gdouble x, gdouble y, GError ** /*error*/) +gboolean document_interface_selection_move_to(DocumentInterface *doc_interface, gdouble x, gdouble y, GError ** /*error*/) { - Inkscape::Selection * sel = object->doc_context.getSelection(); + Inkscape::Selection * sel = doc_interface->target.getSelection(); Geom::OptRect sel_bbox = sel->visualBounds(); if (sel_bbox) { @@ -1258,19 +1258,19 @@ gboolean document_interface_selection_move_to(DocumentInterface *object, gdouble // This needs to use lower level cut_impl and paste_impl (messy) // See the built-in sp_selection_to_next_layer and duplicate. gboolean -document_interface_selection_move_to_layer (DocumentInterface *object, +document_interface_selection_move_to_layer (DocumentInterface *doc_interface, gchar *layerstr, GError **error) { - SPDesktop *dt = object->doc_context.getDesktop(); + SPDesktop *dt = doc_interface->target.getDesktop(); g_return_val_if_fail(ensure_desktop_valid(dt, error), FALSE); - Inkscape::Selection *selection = object->doc_context.getSelection(); + Inkscape::Selection *selection = doc_interface->target.getSelection(); // check if something is selected if (selection->isEmpty()) return FALSE; - SPObject *next = get_object_by_name(object->doc_context.getDocument(), layerstr, error); + SPObject *next = get_object_by_name(doc_interface->target.getDocument(), layerstr, error); if (!next) return FALSE; @@ -1279,7 +1279,7 @@ document_interface_selection_move_to_layer (DocumentInterface *object, sp_selection_cut(dt); - object->doc_context.getSelection()->layers()->setCurrentLayer(next); + doc_interface->target.getSelection()->layers()->setCurrentLayer(next); sp_selection_paste(dt, TRUE); } @@ -1287,9 +1287,9 @@ document_interface_selection_move_to_layer (DocumentInterface *object, } GArray * -document_interface_selection_get_center (DocumentInterface *object) +document_interface_selection_get_center (DocumentInterface *doc_interface) { - Inkscape::Selection * sel = object->doc_context.getSelection(); + Inkscape::Selection * sel = doc_interface->target.getSelection(); if (sel) { @@ -1306,46 +1306,46 @@ document_interface_selection_get_center (DocumentInterface *object) } gboolean -document_interface_selection_to_path (DocumentInterface *object, GError **error) +document_interface_selection_to_path (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); + return dbus_call_verb (doc_interface, SP_VERB_OBJECT_TO_CURVE, error); } gboolean -document_interface_selection_combine (DocumentInterface *object, gchar *cmd, char ***newpaths, +document_interface_selection_combine (DocumentInterface *doc_interface, gchar *cmd, char ***newpaths, GError **error) { if (strcmp(cmd, "union") == 0) - dbus_call_verb (object, SP_VERB_SELECTION_UNION, error); + dbus_call_verb (doc_interface, SP_VERB_SELECTION_UNION, error); else if (strcmp(cmd, "intersection") == 0) - dbus_call_verb (object, SP_VERB_SELECTION_INTERSECT, error); + dbus_call_verb (doc_interface, SP_VERB_SELECTION_INTERSECT, error); else if (strcmp(cmd, "difference") == 0) - dbus_call_verb (object, SP_VERB_SELECTION_DIFF, error); + dbus_call_verb (doc_interface, SP_VERB_SELECTION_DIFF, error); else if (strcmp(cmd, "exclusion") == 0) - dbus_call_verb (object, SP_VERB_SELECTION_SYMDIFF, error); + dbus_call_verb (doc_interface, SP_VERB_SELECTION_SYMDIFF, error); else if (strcmp(cmd, "division") == 0) - dbus_call_verb (object, SP_VERB_SELECTION_CUT, error); + dbus_call_verb (doc_interface, SP_VERB_SELECTION_CUT, error); else { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Operation command not recognised"); return FALSE; } - return document_interface_selection_get (object, newpaths, error); + return document_interface_selection_get (doc_interface, newpaths, error); } gboolean -document_interface_selection_change_level (DocumentInterface *object, gchar *cmd, +document_interface_selection_change_level (DocumentInterface *doc_interface, gchar *cmd, GError **error) { if (strcmp(cmd, "raise") == 0) - return dbus_call_verb (object, SP_VERB_SELECTION_RAISE, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_RAISE, error); if (strcmp(cmd, "lower") == 0) - return dbus_call_verb (object, SP_VERB_SELECTION_LOWER, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_LOWER, error); if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0)) - return dbus_call_verb (object, SP_VERB_SELECTION_TO_FRONT, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_TO_FRONT, error); if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0)) - return dbus_call_verb (object, SP_VERB_SELECTION_TO_BACK, error); + return dbus_call_verb (doc_interface, SP_VERB_SELECTION_TO_BACK, error); return TRUE; } @@ -1353,58 +1353,58 @@ document_interface_selection_change_level (DocumentInterface *object, gchar *cmd LAYER FUNCTIONS ****************************************************************************/ -gchar *document_interface_layer_new(DocumentInterface *object, GError ** /*error*/) +gchar *document_interface_layer_new(DocumentInterface *doc_interface, GError ** /*error*/) { - Inkscape::LayerModel * layers = object->doc_context.getSelection()->layers(); + Inkscape::LayerModel * layers = doc_interface->target.getSelection()->layers(); SPObject *new_layer = Inkscape::create_layer(layers->currentRoot(), layers->currentLayer(), Inkscape::LPOS_BELOW); layers->setCurrentLayer(new_layer); return g_strdup(get_name_from_object(new_layer)); } gboolean -document_interface_layer_set (DocumentInterface *object, +document_interface_layer_set (DocumentInterface *doc_interface, gchar *layerstr, GError **error) { - SPObject * obj = get_object_by_name (object->doc_context.getDocument(), layerstr, error); + SPObject * obj = get_object_by_name (doc_interface->target.getDocument(), layerstr, error); if (!obj) return FALSE; - object->doc_context.getSelection()->layers()->setCurrentLayer (obj); + doc_interface->target.getSelection()->layers()->setCurrentLayer (obj); return TRUE; } -gchar **document_interface_layer_get_all(DocumentInterface * /*object*/) +gchar **document_interface_layer_get_all(DocumentInterface * /*doc_interface*/) { //FIXME: implement. return NULL; } gboolean -document_interface_layer_change_level (DocumentInterface *object, +document_interface_layer_change_level (DocumentInterface *doc_interface, gchar *cmd, GError **error) { if (strcmp(cmd, "raise") == 0) - return dbus_call_verb (object, SP_VERB_LAYER_RAISE, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_RAISE, error); if (strcmp(cmd, "lower") == 0) - return dbus_call_verb (object, SP_VERB_LAYER_LOWER, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_LOWER, error); if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0)) - return dbus_call_verb (object, SP_VERB_LAYER_TO_TOP, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_TO_TOP, error); if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0)) - return dbus_call_verb (object, SP_VERB_LAYER_TO_BOTTOM, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_TO_BOTTOM, error); return TRUE; } gboolean -document_interface_layer_next (DocumentInterface *object, GError **error) +document_interface_layer_next (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_NEXT, error); } gboolean -document_interface_layer_previous (DocumentInterface *object, GError **error) +document_interface_layer_previous (DocumentInterface *doc_interface, GError **error) { - return dbus_call_verb (object, SP_VERB_LAYER_PREV, error); + return dbus_call_verb (doc_interface, SP_VERB_LAYER_PREV, error); } @@ -1423,9 +1423,9 @@ gboolean dbus_send_ping (SPDesktop* desk, SPItem *item) gboolean -document_interface_get_children (DocumentInterface *object, char *name, char ***out, GError **error) +document_interface_get_children (DocumentInterface *doc_interface, char *name, char ***out, GError **error) { - SPItem* parent=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); + SPItem* parent=(SPItem* )get_object_by_name(doc_interface->target.getDocument(), name, error); GSList const *children = parent->childList(false); @@ -1446,9 +1446,9 @@ document_interface_get_children (DocumentInterface *object, char *name, char ** gchar* -document_interface_get_parent (DocumentInterface *object, char *name, GError **error) +document_interface_get_parent (DocumentInterface *doc_interface, char *name, GError **error) { - SPItem* node=(SPItem* )get_object_by_name(object->doc_context.getDocument(), name, error); + SPItem* node=(SPItem* )get_object_by_name(doc_interface->target.getDocument(), name, error); SPObject* parent=node->parent; @@ -1459,8 +1459,8 @@ document_interface_get_parent (DocumentInterface *object, char *name, GError ** #if 0 //just pseudo code gboolean -document_interface_get_xpath (DocumentInterface *object, char *xpath_expression, char ***out, GError **error){ - SPDocument * doc = object->doc_context.getDocument(); +document_interface_get_xpath (DocumentInterface *doc_interface, char *xpath_expression, char ***out, GError **error){ + SPDocument * doc = doc_interface->target.getDocument(); Inkscape::XML::Document *repr = doc->getReprDoc(); xmlXPathObjectPtr xpathObj; diff --git a/src/extension/dbus/document-interface.h b/src/extension/dbus/document-interface.h index f90fe7c80..00d964f36 100644 --- a/src/extension/dbus/document-interface.h +++ b/src/extension/dbus/document-interface.h @@ -52,7 +52,7 @@ typedef struct _DocumentInterfaceClass DocumentInterfaceClass; struct _DocumentInterface { GObject parent; - Inkscape::ActionContext doc_context; ///< stores information about which document, selection, desktop etc this interface is linked to + Inkscape::ActionContext target; ///< stores information about which document, selection, desktop etc this interface is linked to gboolean updates; }; @@ -71,10 +71,10 @@ struct DBUSPoint { ****************************************************************************/ gboolean -document_interface_delete_all (DocumentInterface *object, GError **error); +document_interface_delete_all (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_call_verb (DocumentInterface *object, +document_interface_call_verb (DocumentInterface *doc_interface, gchar *verbid, GError **error); /**************************************************************************** @@ -82,48 +82,48 @@ document_interface_call_verb (DocumentInterface *object, ****************************************************************************/ gchar* -document_interface_rectangle (DocumentInterface *object, int x, int y, +document_interface_rectangle (DocumentInterface *doc_interface, int x, int y, int width, int height, GError **error); gchar* -document_interface_ellipse (DocumentInterface *object, int x, int y, +document_interface_ellipse (DocumentInterface *doc_interface, int x, int y, int width, int height, GError **error); gchar* -document_interface_polygon (DocumentInterface *object, int cx, int cy, +document_interface_polygon (DocumentInterface *doc_interface, int cx, int cy, int radius, int rotation, int sides, GError **error); gchar* -document_interface_star (DocumentInterface *object, int cx, int cy, +document_interface_star (DocumentInterface *doc_interface, int cx, int cy, int r1, int r2, int sides, gdouble rounded, gdouble arg1, gdouble arg2, GError **error); gchar* -document_interface_spiral (DocumentInterface *object, int cx, int cy, +document_interface_spiral (DocumentInterface *doc_interface, int cx, int cy, int r, int revolutions, GError **error); gchar* -document_interface_line (DocumentInterface *object, int x, int y, +document_interface_line (DocumentInterface *doc_interface, int x, int y, int x2, int y2, GError **error); gchar* -document_interface_text (DocumentInterface *object, int x, int y, +document_interface_text (DocumentInterface *doc_interface, int x, int y, gchar *text, GError **error); gboolean -document_interface_set_text (DocumentInterface *object, gchar *name, +document_interface_set_text (DocumentInterface *doc_interface, gchar *name, gchar *text, GError **error); gboolean -document_interface_text_apply_style (DocumentInterface *object, gchar *name, +document_interface_text_apply_style (DocumentInterface *doc_interface, gchar *name, int start_pos, int end_pos, gchar *style, gchar *styleval, GError **error); gchar * -document_interface_image (DocumentInterface *object, int x, int y, +document_interface_image (DocumentInterface *doc_interface, int x, int y, gchar *filename, GError **error); gchar* -document_interface_node (DocumentInterface *object, gchar *svgtype, +document_interface_node (DocumentInterface *doc_interface, gchar *svgtype, GError **error); @@ -131,27 +131,27 @@ document_interface_node (DocumentInterface *object, gchar *svgtype, ENVIORNMENT FUNCTIONS ****************************************************************************/ gdouble -document_interface_document_get_width (DocumentInterface *object); +document_interface_document_get_width (DocumentInterface *doc_interface); gdouble -document_interface_document_get_height (DocumentInterface *object); +document_interface_document_get_height (DocumentInterface *doc_interface); gchar * -document_interface_document_get_css (DocumentInterface *object, GError **error); +document_interface_document_get_css (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_document_merge_css (DocumentInterface *object, +document_interface_document_merge_css (DocumentInterface *doc_interface, gchar *stylestring, GError **error); gboolean -document_interface_document_set_css (DocumentInterface *object, +document_interface_document_set_css (DocumentInterface *doc_interface, gchar *stylestring, GError **error); gboolean -document_interface_document_resize_to_fit_selection (DocumentInterface *object, +document_interface_document_resize_to_fit_selection (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_document_set_display_area (DocumentInterface *object, +document_interface_document_set_display_area (DocumentInterface *doc_interface, double x0, double y0, double x1, @@ -159,95 +159,95 @@ document_interface_document_set_display_area (DocumentInterface *object, double border, GError **error); GArray * -document_interface_document_get_display_area (DocumentInterface *object); +document_interface_document_get_display_area (DocumentInterface *doc_interface); /**************************************************************************** OBJECT FUNCTIONS ****************************************************************************/ gboolean -document_interface_set_attribute (DocumentInterface *object, +document_interface_set_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, char *newval, GError **error); gboolean -document_interface_set_int_attribute (DocumentInterface *object, +document_interface_set_int_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, int newval, GError **error); gboolean -document_interface_set_double_attribute (DocumentInterface *object, +document_interface_set_double_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, double newval, GError **error); gchar * -document_interface_get_attribute (DocumentInterface *object, +document_interface_get_attribute (DocumentInterface *doc_interface, char *shape, char *attribute, GError **error); gboolean -document_interface_move (DocumentInterface *object, gchar *name, +document_interface_move (DocumentInterface *doc_interface, gchar *name, gdouble x, gdouble y, GError **error); gboolean -document_interface_move_to (DocumentInterface *object, gchar *name, +document_interface_move_to (DocumentInterface *doc_interface, gchar *name, gdouble x, gdouble y, GError **error); gboolean -document_interface_object_to_path (DocumentInterface *object, +document_interface_object_to_path (DocumentInterface *doc_interface, char *shape, GError **error); gchar * -document_interface_get_path (DocumentInterface *object, +document_interface_get_path (DocumentInterface *doc_interface, char *pathname, GError **error); gboolean -document_interface_transform (DocumentInterface *object, gchar *shape, +document_interface_transform (DocumentInterface *doc_interface, gchar *shape, gchar *transformstr, GError **error); gchar * -document_interface_get_css (DocumentInterface *object, gchar *shape, +document_interface_get_css (DocumentInterface *doc_interface, gchar *shape, GError **error); gboolean -document_interface_modify_css (DocumentInterface *object, gchar *shape, +document_interface_modify_css (DocumentInterface *doc_interface, gchar *shape, gchar *cssattrb, gchar *newval, GError **error); gboolean -document_interface_merge_css (DocumentInterface *object, gchar *shape, +document_interface_merge_css (DocumentInterface *doc_interface, gchar *shape, gchar *stylestring, GError **error); gboolean -document_interface_set_color (DocumentInterface *object, gchar *shape, +document_interface_set_color (DocumentInterface *doc_interface, gchar *shape, int r, int g, int b, gboolean fill, GError **error); gboolean -document_interface_move_to_layer (DocumentInterface *object, gchar *shape, +document_interface_move_to_layer (DocumentInterface *doc_interface, gchar *shape, gchar *layerstr, GError **error); GArray * -document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape); +document_interface_get_node_coordinates (DocumentInterface *doc_interface, gchar *shape); /**************************************************************************** FILE I/O FUNCTIONS ****************************************************************************/ gboolean -document_interface_save (DocumentInterface *object, GError **error); +document_interface_save (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_load (DocumentInterface *object, +document_interface_load (DocumentInterface *doc_interface, gchar *filename, GError **error); gboolean -document_interface_save_as (DocumentInterface *object, +document_interface_save_as (DocumentInterface *doc_interface, const gchar *filename, GError **error); gboolean -document_interface_mark_as_unmodified (DocumentInterface *object, GError **error); +document_interface_mark_as_unmodified (DocumentInterface *doc_interface, GError **error); /* gboolean -document_interface_print_to_file (DocumentInterface *object, GError **error); +document_interface_print_to_file (DocumentInterface *doc_interface, GError **error); */ /**************************************************************************** @@ -255,120 +255,120 @@ document_interface_print_to_file (DocumentInterface *object, GError **error); ****************************************************************************/ gboolean -document_interface_close (DocumentInterface *object, GError **error); +document_interface_close (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_exit (DocumentInterface *object, GError **error); +document_interface_exit (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_undo (DocumentInterface *object, GError **error); +document_interface_undo (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_redo (DocumentInterface *object, GError **error); +document_interface_redo (DocumentInterface *doc_interface, GError **error); /**************************************************************************** UPDATE FUNCTIONS ****************************************************************************/ void -document_interface_pause_updates (DocumentInterface *object, GError **error); +document_interface_pause_updates (DocumentInterface *doc_interface, GError **error); void -document_interface_resume_updates (DocumentInterface *object, GError **error); +document_interface_resume_updates (DocumentInterface *doc_interface, GError **error); void -document_interface_update (DocumentInterface *object, GError **error); +document_interface_update (DocumentInterface *doc_interface, GError **error); /**************************************************************************** SELECTION FUNCTIONS ****************************************************************************/ gboolean -document_interface_selection_get (DocumentInterface *object, char ***out, GError **error); +document_interface_selection_get (DocumentInterface *doc_interface, char ***out, GError **error); gboolean -document_interface_selection_add (DocumentInterface *object, +document_interface_selection_add (DocumentInterface *doc_interface, char *name, GError **error); gboolean -document_interface_selection_add_list (DocumentInterface *object, +document_interface_selection_add_list (DocumentInterface *doc_interface, char **names, GError **error); gboolean -document_interface_selection_set (DocumentInterface *object, +document_interface_selection_set (DocumentInterface *doc_interface, char *name, GError **error); gboolean -document_interface_selection_set_list (DocumentInterface *object, +document_interface_selection_set_list (DocumentInterface *doc_interface, gchar **names, GError **error); gboolean -document_interface_selection_rotate (DocumentInterface *object, +document_interface_selection_rotate (DocumentInterface *doc_interface, int angle, GError **error); gboolean -document_interface_selection_delete(DocumentInterface *object, GError **error); +document_interface_selection_delete(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_clear(DocumentInterface *object, GError **error); +document_interface_selection_clear(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_select_all(DocumentInterface *object, GError **error); +document_interface_select_all(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_select_all_in_all_layers(DocumentInterface *object, +document_interface_select_all_in_all_layers(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_box (DocumentInterface *object, int x, int y, +document_interface_selection_box (DocumentInterface *doc_interface, int x, int y, int x2, int y2, gboolean replace, GError **error); gboolean -document_interface_selection_invert (DocumentInterface *object, GError **error); +document_interface_selection_invert (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_group(DocumentInterface *object, GError **error); +document_interface_selection_group(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_ungroup(DocumentInterface *object, GError **error); +document_interface_selection_ungroup(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_cut(DocumentInterface *object, GError **error); +document_interface_selection_cut(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_copy(DocumentInterface *object, GError **error); +document_interface_selection_copy(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_paste(DocumentInterface *object, GError **error); +document_interface_selection_paste(DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_scale (DocumentInterface *object, +document_interface_selection_scale (DocumentInterface *doc_interface, gdouble grow, GError **error); gboolean -document_interface_selection_move (DocumentInterface *object, gdouble x, +document_interface_selection_move (DocumentInterface *doc_interface, gdouble x, gdouble y, GError **error); gboolean -document_interface_selection_move_to (DocumentInterface *object, gdouble x, +document_interface_selection_move_to (DocumentInterface *doc_interface, gdouble x, gdouble y, GError **error); gboolean -document_interface_selection_move_to_layer (DocumentInterface *object, +document_interface_selection_move_to_layer (DocumentInterface *doc_interface, gchar *layerstr, GError **error); GArray * -document_interface_selection_get_center (DocumentInterface *object); +document_interface_selection_get_center (DocumentInterface *doc_interface); gboolean -document_interface_selection_to_path (DocumentInterface *object, GError **error); +document_interface_selection_to_path (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_selection_combine (DocumentInterface *object, gchar *cmd, char ***newpaths, +document_interface_selection_combine (DocumentInterface *doc_interface, gchar *cmd, char ***newpaths, GError **error); gboolean -document_interface_selection_change_level (DocumentInterface *object, gchar *cmd, +document_interface_selection_change_level (DocumentInterface *doc_interface, gchar *cmd, GError **error); /**************************************************************************** @@ -376,24 +376,24 @@ document_interface_selection_change_level (DocumentInterface *object, gchar *cmd ****************************************************************************/ gchar * -document_interface_layer_new (DocumentInterface *object, GError **error); +document_interface_layer_new (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_layer_set (DocumentInterface *object, +document_interface_layer_set (DocumentInterface *doc_interface, gchar *layerstr, GError **error); gchar ** -document_interface_layer_get_all (DocumentInterface *object); +document_interface_layer_get_all (DocumentInterface *doc_interface); gboolean -document_interface_layer_change_level (DocumentInterface *object, +document_interface_layer_change_level (DocumentInterface *doc_interface, gchar *cmd, GError **error); gboolean -document_interface_layer_next (DocumentInterface *object, GError **error); +document_interface_layer_next (DocumentInterface *doc_interface, GError **error); gboolean -document_interface_layer_previous (DocumentInterface *object, GError **error); +document_interface_layer_previous (DocumentInterface *doc_interface, GError **error); @@ -409,13 +409,13 @@ extern DocumentInterface *fugly; gboolean dbus_send_ping (SPDesktop* desk, SPItem *item); gboolean -document_interface_get_children (DocumentInterface *object, char *name, char ***out, GError **error); +document_interface_get_children (DocumentInterface *doc_interface, char *name, char ***out, GError **error); gchar* -document_interface_get_parent (DocumentInterface *object, char *name, GError **error); +document_interface_get_parent (DocumentInterface *doc_interface, char *name, GError **error); gchar* -document_interface_import (DocumentInterface *object, +document_interface_import (DocumentInterface *doc_interface, gchar *filename, GError **error); G_END_DECLS diff --git a/src/inkscape-private.h b/src/inkscape-private.h index 09bcef12b..364e3dab6 100644 --- a/src/inkscape-private.h +++ b/src/inkscape-private.h @@ -48,8 +48,6 @@ void inkscape_add_desktop (SPDesktop * desktop); void inkscape_remove_desktop (SPDesktop * desktop); void inkscape_activate_desktop (SPDesktop * desktop); void inkscape_reactivate_desktop (SPDesktop * desktop); -void inkscape_add_document (SPDocument *document); -bool inkscape_remove_document (SPDocument *document); void inkscape_set_color (SPColor *color, float opacity); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 2e60ee5ea..a24bd2b8a 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1359,7 +1359,22 @@ inkscape_active_action_context() if (!doc) { return Inkscape::ActionContext(); } - + + return inkscape_action_context_for_document(doc); +} + +Inkscape::ActionContext +inkscape_action_context_for_document(SPDocument *doc) +{ + // If there are desktops, check them first to see if the document is bound to one of them + for (GSList *iter = inkscape->desktops ; iter ; iter = iter->next) { + SPDesktop *desktop=static_cast(iter->data); + if (desktop->doc() == doc) { + return Inkscape::ActionContext(desktop); + } + } + + // Document is not associated with any desktops - maybe we're in command-line mode std::map::iterator sel_iter = inkscape->selection_models.find(doc); if (sel_iter == inkscape->selection_models.end()) { return Inkscape::ActionContext(); diff --git a/src/inkscape.h b/src/inkscape.h index cb6ba6a0f..234b98d2c 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -57,6 +57,11 @@ SPDocument * inkscape_active_document (void); #define SP_ACTIVE_DESKTOP inkscape_active_desktop () SPDesktop * inkscape_active_desktop (void); +// Use this function to get selection model etc for a document, if possible! +// The "active" alternative below has all the horrible static cling of a singleton. +Inkscape::ActionContext +inkscape_action_context_for_document(SPDocument *doc); + // More horrible static cling... sorry about this. Should really replace all of // the static stuff with a single instance of some kind of engine class holding // all the document / non-GUI stuff, and an optional GUI class that behaves a @@ -85,6 +90,11 @@ void inkscape_dialogs_toggle (); void inkscape_external_change (); void inkscape_subselection_changed (SPDesktop *desktop); +/* Moved document add/remove functions into public inkscape.h as they are used + (rightly or wrongly) by console-mode functions */ +void inkscape_add_document (SPDocument *document); +bool inkscape_remove_document (SPDocument *document); + /* * fixme: This has to be rethought */ -- cgit v1.2.3 From c165601973334cdb21088219a3cb9d0a20abb181 Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Thu, 4 Jul 2013 23:57:15 +0100 Subject: Fix for builds without --enable-dbusapi (missing #ifdef) (bzr r12387.1.9) --- src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 630411dde..ba51951da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1277,7 +1277,11 @@ int sp_main_console(int argc, char const **argv) int retVal = sp_common_main( argc, argv, &fl ); g_return_val_if_fail(retVal == 0, 1); - if (fl == NULL && !sp_shell && !sp_dbus_listen) { + if (fl == NULL && !sp_shell +#ifdef WITH_DBUS + && !sp_dbus_listen +#endif // WITH_DBUS + ) { g_print("Nothing to do!\n"); exit(0); } -- cgit v1.2.3 From 6c31882fb2319fcbfbc3e17ac368deac2edd2e79 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 4 Jul 2013 18:58:42 -0400 Subject: Improve handle xpm loading using rotate (bzr r12401.1.1) --- src/pixmaps/handles.xpm | 178 ++--------------------------------- src/select-context.cpp | 30 +++--- src/seltrans-handles.cpp | 14 +-- src/ui/tool/transform-handle-set.cpp | 12 +-- 4 files changed, 38 insertions(+), 196 deletions(-) (limited to 'src') diff --git a/src/pixmaps/handles.xpm b/src/pixmaps/handles.xpm index f2afa026b..b61ad377c 100644 --- a/src/pixmaps/handles.xpm +++ b/src/pixmaps/handles.xpm @@ -1,5 +1,5 @@ -/* XPM */ -static char const *handle_scale_nw_xpm[] = { +/* XPM North-West */ +static char const *handle_scale_xpm[] = { "13 13 3 1", " c None", ". c #000000", @@ -18,28 +18,8 @@ static char const *handle_scale_nw_xpm[] = { " ....... ", " "}; -/* XPM */ -static char const *handle_scale_ne_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" ", -" ....... ", -" ..+++. ", -" .++++. ", -" .+++++. ", -" . .+++++.. ", -" ...+++++... ", -" ..+++++. . ", -" .+++++. ", -" .++++. ", -" .+++.. ", -" ....... ", -" "}; - -/* XPM */ -static char const *handle_scale_h_xpm[] = { +/* XPM Vertical */ +static char const *handle_stretch_xpm[] = { "13 13 3 1", " c None", ". c #000000", @@ -58,28 +38,8 @@ static char const *handle_scale_h_xpm[] = { " ", " "}; -/* XPM */ -static char const *handle_scale_v_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" ... ", -" ..+.. ", -" ..+++.. ", -" ..+++++.. ", -" .+++. ", -" .+++. ", -" .+++. ", -" ..+++++.. ", -" ..+++.. ", -" ..+.. ", -" ... ", -" . "}; - -/* XPM */ -static char const *handle_rotate_nw_xpm[] = { +/* XPM North-West */ +static char const *handle_rotate_xpm[] = { "13 13 3 1", " c None", ". c #000000", @@ -98,8 +58,8 @@ static char const *handle_rotate_nw_xpm[] = { " ... ", " . "}; -/* XPM */ -static char const *handle_rotate_n_xpm[] = { +/* XPM North */ +static char const *handle_skew_xpm[] = { "13 13 3 1", " c None", ". c #000000", @@ -118,127 +78,6 @@ static char const *handle_rotate_n_xpm[] = { " ", " "}; -/* XPM */ -static char const *handle_rotate_ne_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" .. ", -" .... ", -" ..++... ", -"..++++++. ", -" .+++++++. ", -" .+..++++. ", -" . .+++. ", -" .+++...", -" .++++.. ", -" .++.. ", -" ... ", -" . "}; - -/* XPM */ -static char const *handle_rotate_e_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" ... ", -" ..+.. ", -" ..+++.. ", -" ...+++...", -" .+++. ", -" .+++. ", -" .+++. ", -" ...+++...", -" ..+++.. ", -" ..+.. ", -" ... ", -" . "}; - -/* XPM */ -static char const *handle_rotate_se_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" ... ", -" .++.. ", -" .++++.. ", -" .+++...", -" . .+++. ", -" .+..++++. ", -" .+++++++. ", -"..++++++. ", -" ..++... ", -" .... ", -" .. ", -" . "}; - - -/* XPM */ -static char const *handle_rotate_s_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" ", -" ", -" ", -" ", -" . . ", -" .. .. ", -" ......... ", -" ..+++++++.. ", -"..+++++++++..", -" ..+++++++.. ", -" ......... ", -" .. .. ", -" . . "}; - -/* XPM */ -static char const *handle_rotate_sw_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" ... ", -" ..++. ", -" ..++++. ", -"...+++. ", -" .+++. . ", -" .++++..+. ", -" .+++++++. ", -" .++++++..", -" ...++.. ", -" .... ", -" .. ", -" . "}; - -/* XPM */ -static char const *handle_rotate_w_xpm[] = { -"13 13 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" . ", -" ... ", -" ..+.. ", -" ..+++.. ", -"...+++... ", -" .+++. ", -" .+++. ", -" .+++. ", -"...+++. . ", -" ..+++.. ", -" ..+.. ", -" ... ", -" . "}; - /* XPM */ static char const *handle_center_xpm[] = { "13 13 3 1", @@ -258,3 +97,4 @@ static char const *handle_center_xpm[] = { " . ", " . ", " "}; + diff --git a/src/select-context.cpp b/src/select-context.cpp index 1dd3b08d7..6c130ec96 100644 --- a/src/select-context.cpp +++ b/src/select-context.cpp @@ -62,7 +62,7 @@ static void sp_select_context_reset_opacities(SPEventContext *event_context); static GdkCursor *CursorSelectMouseover = NULL; static GdkCursor *CursorSelectDragging = NULL; -GdkPixbuf *handles[13]; +GdkPixbuf *handles[18]; static gint rb_escaped = 0; // if non-zero, rubberband was canceled by esc, so the next button release should not deselect static gint drag_escaped = 0; // if non-zero, drag was canceled by esc @@ -91,6 +91,16 @@ sp_select_context_class_init(SPSelectContextClass *klass) event_context_class->item_handler = sp_select_context_item_handler; } +//Creates rotated variations for handles +static void +sp_load_handles(int start, int count, char const **xpm) { + handles[start] = gdk_pixbuf_new_from_xpm_data((gchar const **)xpm); + for(int i = start + 1; i < start + count; i++) { + // We use either the original at *start or previous loop item to rotate + handles[i] = gdk_pixbuf_rotate_simple(handles[i-1], GDK_PIXBUF_ROTATE_CLOCKWISE); + } +} + static void sp_select_context_init(SPSelectContext *sc) { @@ -111,19 +121,11 @@ sp_select_context_init(SPSelectContext *sc) CursorSelectMouseover = sp_cursor_new_from_xpm(cursor_select_m_xpm , 1, 1); CursorSelectDragging = sp_cursor_new_from_xpm(cursor_select_d_xpm , 1, 1); // selection handles - handles[0] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_nw_xpm); - handles[1] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_ne_xpm); - handles[2] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_h_xpm); - handles[3] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_v_xpm); - handles[4] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_nw_xpm); - handles[5] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_n_xpm); - handles[6] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_ne_xpm); - handles[7] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_e_xpm); - handles[8] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_se_xpm); - handles[9] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_s_xpm); - handles[10] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_sw_xpm); - handles[11] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_w_xpm); - handles[12] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_center_xpm); + sp_load_handles(0, 2, handle_scale_xpm); + sp_load_handles(2, 2, handle_stretch_xpm); + sp_load_handles(4, 4, handle_rotate_xpm); + sp_load_handles(8, 4, handle_skew_xpm); + sp_load_handles(12, 1, handle_center_xpm); } static void diff --git a/src/seltrans-handles.cpp b/src/seltrans-handles.cpp index bacb1301e..6dd94d297 100644 --- a/src/seltrans-handles.cpp +++ b/src/seltrans-handles.cpp @@ -16,7 +16,7 @@ SPSelTransTypeInfo const handtypes[] = { SPSelTransHandle const hands[] = { //center handle will be 0 so we can reference it quickly. {HANDLE_CENTER, SP_ANCHOR_CENTER, GDK_CROSSHAIR, 12, 0.5, 0.5}, -//handle-type anchor cursor control x y +//handle-type anchor-nudge cursor image x y {HANDLE_STRETCH, SP_ANCHOR_S, GDK_TOP_SIDE, 3, 0.5, 1}, {HANDLE_STRETCH, SP_ANCHOR_W, GDK_RIGHT_SIDE, 2, 1, 0.5}, {HANDLE_STRETCH, SP_ANCHOR_N, GDK_BOTTOM_SIDE, 3, 0.5, 0}, @@ -25,14 +25,14 @@ SPSelTransHandle const hands[] = { {HANDLE_SCALE, SP_ANCHOR_SW, GDK_TOP_RIGHT_CORNER, 1, 1, 1}, {HANDLE_SCALE, SP_ANCHOR_NW, GDK_BOTTOM_RIGHT_CORNER, 0, 1, 0}, {HANDLE_SCALE, SP_ANCHOR_NE, GDK_BOTTOM_LEFT_CORNER, 1, 0, 0}, - {HANDLE_SKEW, SP_ANCHOR_S, GDK_SB_H_DOUBLE_ARROW, 5, 0.5, 1}, - {HANDLE_SKEW, SP_ANCHOR_W, GDK_SB_V_DOUBLE_ARROW, 7, 1, 0.5}, - {HANDLE_SKEW, SP_ANCHOR_N, GDK_SB_H_DOUBLE_ARROW, 9, 0.5, 0}, + {HANDLE_SKEW, SP_ANCHOR_S, GDK_SB_H_DOUBLE_ARROW, 8, 0.5, 1}, + {HANDLE_SKEW, SP_ANCHOR_W, GDK_SB_V_DOUBLE_ARROW, 9, 1, 0.5}, + {HANDLE_SKEW, SP_ANCHOR_N, GDK_SB_H_DOUBLE_ARROW, 10, 0.5, 0}, {HANDLE_SKEW, SP_ANCHOR_E, GDK_SB_V_DOUBLE_ARROW, 11, 0, 0.5}, {HANDLE_ROTATE, SP_ANCHOR_SE, GDK_EXCHANGE, 4, 0, 1}, - {HANDLE_ROTATE, SP_ANCHOR_SW, GDK_EXCHANGE, 6, 1, 1}, - {HANDLE_ROTATE, SP_ANCHOR_NW, GDK_EXCHANGE, 8, 1, 0}, - {HANDLE_ROTATE, SP_ANCHOR_NE, GDK_EXCHANGE, 10, 0, 0}, + {HANDLE_ROTATE, SP_ANCHOR_SW, GDK_EXCHANGE, 5, 1, 1}, + {HANDLE_ROTATE, SP_ANCHOR_NW, GDK_EXCHANGE, 6, 1, 0}, + {HANDLE_ROTATE, SP_ANCHOR_NE, GDK_EXCHANGE, 7, 0, 0}, }; /* diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index f0bf149f4..30963cabd 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -458,9 +458,9 @@ private: static Glib::RefPtr _corner_to_pixbuf(unsigned c) { sp_select_context_get_type(); switch (c % 4) { - case 0: return Glib::wrap(handles[10], true); - case 1: return Glib::wrap(handles[8], true); - case 2: return Glib::wrap(handles[6], true); + case 0: return Glib::wrap(handles[7], true); + case 1: return Glib::wrap(handles[6], true); + case 2: return Glib::wrap(handles[5], true); default: return Glib::wrap(handles[4], true); } } @@ -605,9 +605,9 @@ private: static Glib::RefPtr _side_to_pixbuf(unsigned s) { sp_select_context_get_type(); switch (s % 4) { - case 0: return Glib::wrap(handles[9], true); - case 1: return Glib::wrap(handles[7], true); - case 2: return Glib::wrap(handles[5], true); + case 0: return Glib::wrap(handles[10], true); + case 1: return Glib::wrap(handles[9], true); + case 2: return Glib::wrap(handles[8], true); default: return Glib::wrap(handles[11], true); } } -- cgit v1.2.3 From c09c9da090325f4f639843510635b1d8f6b39494 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 5 Jul 2013 08:21:03 -0400 Subject: Adjust sizes of lists (bzr r12401.1.2) --- src/select-context.cpp | 2 +- src/seltrans.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/select-context.cpp b/src/select-context.cpp index 6c130ec96..27667d639 100644 --- a/src/select-context.cpp +++ b/src/select-context.cpp @@ -62,7 +62,7 @@ static void sp_select_context_reset_opacities(SPEventContext *event_context); static GdkCursor *CursorSelectMouseover = NULL; static GdkCursor *CursorSelectDragging = NULL; -GdkPixbuf *handles[18]; +GdkPixbuf *handles[13]; static gint rb_escaped = 0; // if non-zero, rubberband was canceled by esc, so the next button release should not deselect static gint drag_escaped = 0; // if non-zero, drag was canceled by esc diff --git a/src/seltrans.h b/src/seltrans.h index 667dedaf0..880f30c94 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -180,7 +180,7 @@ private: bool _center_is_set; ///< we've already set _center, no need to reread it from items int _center_handle; - SPKnot *knots[27]; // Only some as shown at any time + SPKnot *knots[17]; SPCanvasItem *_norm; SPCanvasItem *_grip; SPCtrlLine *_l[4]; -- cgit v1.2.3 From 4d9dc443915f588d2e3de8dbc9b61ba1cf2e6dee Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 6 Jul 2013 02:09:21 -0400 Subject: Fix verbs that were out by 5 because of missing script verbs (broken between r7137-r11611) (bzr r12406) --- src/verbs.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index 1dae8bcf0..d0396155c 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2903,7 +2903,17 @@ Verb *Verb::_base_verbs[] = { N_("Link an ICC color profile"), NULL), new EditVerb(SP_VERB_EDIT_REMOVE_COLOR_PROFILE, "RemoveColorProfile", N_("Remove Color Profile"), N_("Remove a linked ICC color profile"), NULL), - + // Scripting + new ContextVerb(SP_VERB_EDIT_ADD_EXTERNAL_SCRIPT, "AddExternalScript", + N_("Add External Script"), N_("Add an external script"), NULL), + new ContextVerb(SP_VERB_EDIT_ADD_EMBEDDED_SCRIPT, "AddEmbeddedScript", + N_("Add Embedded Script"), N_("Add an embedded script"), NULL), + new ContextVerb(SP_VERB_EDIT_EMBEDDED_SCRIPT, "EditEmbeddedScript", + N_("Edit Embedded Script"), N_("Edit an embedded script"), NULL), + new ContextVerb(SP_VERB_EDIT_REMOVE_EXTERNAL_SCRIPT, "RemoveExternalScript", + N_("Remove External Script"), N_("Remove an external script"), NULL), + new ContextVerb(SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, "RemoveEmbeddedScript", + N_("Remove Embedded Script"), N_("Remove an embedded script"), NULL), // Align new ContextVerb(SP_VERB_ALIGN_HORIZONTAL_RIGHT_TO_ANCHOR, "AlignHorizontalRightToAnchor", N_("Align right edges of objects to the left edge of the anchor"), N_("Align right edges of objects to the left edge of the anchor"), INKSCAPE_ICON("align-horizontal-right-to-anchor")), -- cgit v1.2.3 From 2a5484afeb64207849e1dcdd9336fd4b0aaab06b Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 6 Jul 2013 11:19:17 +0100 Subject: Fix build failure with GDL >= 3.6 Fixed bugs: - https://launchpad.net/bugs/1196070 (bzr r12407) --- src/ui/widget/dock.cpp | 20 ++++++++++++++++---- src/ui/widget/dock.h | 10 +++++----- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp index 2bfc7e0df..52e9ea605 100644 --- a/src/ui/widget/dock.cpp +++ b/src/ui/widget/dock.cpp @@ -48,11 +48,21 @@ const int Dock::_default_dock_bar_width = 36; Dock::Dock(Gtk::Orientation orientation) - : _gdl_dock (GDL_DOCK (gdl_dock_new())), - _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))), + : _gdl_dock(gdl_dock_new()), +#if WITH_GDL_3_6 + _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(G_OBJECT(_gdl_dock)))), +#else + _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))), +#endif _scrolled_window (Gtk::manage(new Gtk::ScrolledWindow)) { - gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast(orientation)); +#if WITH_GDL_3_6 + gtk_orientable_set_orientation(GTK_ORIENTABLE(_gdl_dock_bar), + static_cast(orientation)); +#else + gdl_dock_bar_set_orientation(_gdl_dock_bar, + static_cast(orientation)); +#endif #if WITH_GTKMM_3_0 switch(orientation) { @@ -127,7 +137,9 @@ Dock::~Dock() void Dock::addItem(DockItem& item, DockItem::Placement placement) { _dock_items.push_back(&item); - gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement); + gdl_dock_add_item(GDL_DOCK(_gdl_dock), + GDL_DOCK_ITEM(item.gobj()), + (GdlDockPlacement)placement); // FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done // initially as the paned doesn't exist. diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h index 611c10f46..33e60b836 100644 --- a/src/ui/widget/dock.h +++ b/src/ui/widget/dock.h @@ -74,11 +74,11 @@ protected: /** Interface widgets, will be packed like * _scrolled_window -> (_dock_box -> (_paned -> (_dock -> _filler) | _dock_bar)) */ - Gtk::Box *_dock_box; - Gtk::Paned* _paned; - GdlDock *_gdl_dock; - GdlDockBar *_gdl_dock_bar; - Gtk::VBox _filler; + Gtk::Box *_dock_box; + Gtk::Paned *_paned; + GtkWidget *_gdl_dock; + GdlDockBar *_gdl_dock_bar; + Gtk::VBox _filler; Gtk::ScrolledWindow *_scrolled_window; /** Internal signal handlers */ -- cgit v1.2.3 From c2476065a96485c282da32a8859ef8c5617b5b7d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 7 Jul 2013 10:12:44 -0400 Subject: Make colour a guint instead of a uint. bug 1198501 Fixed bugs: - https://launchpad.net/bugs/1198501 (bzr r12408) --- src/seltrans.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/seltrans.h b/src/seltrans.h index 880f30c94..67d581471 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -71,6 +71,7 @@ public: gboolean skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); gboolean rotateRequest(Geom::Point &pt, guint state); gboolean centerRequest(Geom::Point &pt, guint state); + void alignClick(SPSelTransHandle const &handle); gboolean handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle); @@ -130,6 +131,7 @@ private: }; SPDesktop *_desktop; + SPCanvasItem *aguide; std::vector _items; std::vector _items_const; @@ -180,7 +182,7 @@ private: bool _center_is_set; ///< we've already set _center, no need to reread it from items int _center_handle; - SPKnot *knots[17]; + SPKnot *knots[NUMHANDS]; SPCanvasItem *_norm; SPCanvasItem *_grip; SPCtrlLine *_l[4]; -- cgit v1.2.3 From a48ec17933088b745b16a0903ef00bd5a9366a71 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 8 Jul 2013 07:40:48 -0400 Subject: Revert wrong changes and apply right fixes from prev-commit (bzr r12409) --- src/seltrans-handles.h | 2 +- src/seltrans.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index 5c3fdd269..740729a6e 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -33,7 +33,7 @@ enum SPSelTransType { }; struct SPSelTransTypeInfo { - uint const *color; + guint32 const *color; gchar const *tip; }; // One per handle type in order diff --git a/src/seltrans.h b/src/seltrans.h index 67d581471..d97375520 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -71,7 +71,6 @@ public: gboolean skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); gboolean rotateRequest(Geom::Point &pt, guint state); gboolean centerRequest(Geom::Point &pt, guint state); - void alignClick(SPSelTransHandle const &handle); gboolean handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle); @@ -131,7 +130,6 @@ private: }; SPDesktop *_desktop; - SPCanvasItem *aguide; std::vector _items; std::vector _items_const; -- cgit v1.2.3 From c56584bdf7c95b528d1b8016a0b4009f8b829dab Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 9 Jul 2013 21:34:33 +0200 Subject: Fix for Bug #1185132 (colorspace.h not included in the tarball when doing a make dist) by Ryan Lerch. Fixed bugs: - https://launchpad.net/bugs/1185132 (bzr r12410) --- src/Makefile_insert | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Makefile_insert b/src/Makefile_insert index 023d640ca..88f809b52 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -21,6 +21,7 @@ ink_common_sources += \ color-profile.cpp color-profile.h \ color-profile-cms-fns.h \ color-rgba.h \ + colorspace.h \ common-context.cpp common-context.h \ composite-undo-stack-observer.cpp \ composite-undo-stack-observer.h \ -- cgit v1.2.3 From 4d232a223d1dcb7b2381615de1a64b20b2fb6165 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 9 Jul 2013 20:46:51 -0400 Subject: Small refactor of align and distribute to reduce complexity. (bzr r12411) --- src/document.cpp | 5 +++ src/document.h | 1 + src/ui/dialog/align-and-distribute.cpp | 59 ++++++++++------------------------ 3 files changed, 23 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 706710cfc..0e9c43fe4 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -611,6 +611,11 @@ Geom::Point SPDocument::getDimensions() const return Geom::Point(getWidth(), getHeight()); } +Geom::OptRect SPDocument::preferredBounds() const +{ + return Geom::OptRect( Geom::Point(0, 0), getDimensions() ); +} + /** * Given a Geom::Rect that may, for example, correspond to the bbox of an object, * this function fits the canvas to that rect by resizing the canvas diff --git a/src/document.h b/src/document.h index 606a83be8..d49067250 100644 --- a/src/document.h +++ b/src/document.h @@ -228,6 +228,7 @@ public: gdouble getWidth() const; gdouble getHeight() const; Geom::Point getDimensions() const; + Geom::OptRect preferredBounds() const; void setWidth(gdouble width, const SPUnit *unit); void setHeight(gdouble height, const SPUnit *unit); void requestModified(); diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 7f88824f7..6a1cfc0ba 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -88,23 +88,23 @@ Action::Action(const Glib::ustring &id, } -void ActionAlign::do_action(SPDesktop *desktop, int index) { - +void ActionAlign::do_action(SPDesktop *desktop, int index) +{ Inkscape::Selection *selection = sp_desktop_selection(desktop); if (!selection) return; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool sel_as_group = prefs->getBool("/dialogs/align/sel-as-groups"); - int prefs_bbox = prefs->getBool("/tools/bounding_box"); using Inkscape::Util::GSListConstIterator; std::list selected; selected.insert >(selected.end(), selection->itemList(), NULL); if (selected.empty()) return; - Geom::Point mp; //Anchor point + const Coeffs &a = _allCoeffs[index]; + Geom::OptRect b = Geom::OptRect(); AlignAndDistribute::AlignTarget target = AlignAndDistribute::getAlignTarget(); - const Coeffs &a= _allCoeffs[index]; + switch (target) { case AlignAndDistribute::LAST: @@ -132,51 +132,27 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) { /*if (!sel_as_group) { */ selected.erase(master); /*}*/ - //Compute the anchor point - Geom::OptRect b = !prefs_bbox ? thing->desktopVisualBounds() : thing->desktopGeometricBounds(); - if (b) { - mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], - a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); - } else { - return; - } + b = thing->desktopPreferredBounds(); break; } - case AlignAndDistribute::PAGE: - mp = Geom::Point(a.mx1 * sp_desktop_document(desktop)->getWidth(), - a.my1 * sp_desktop_document(desktop)->getHeight()); + b = sp_desktop_document(desktop)->preferredBounds(); break; - case AlignAndDistribute::DRAWING: - { - Geom::OptRect b = !prefs_bbox ? sp_desktop_document(desktop)->getRoot()->desktopVisualBounds() - : sp_desktop_document(desktop)->getRoot()->desktopGeometricBounds(); - if (b) { - mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], - a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); - } else { - return; - } + b = sp_desktop_document(desktop)->getRoot()->desktopPreferredBounds(); break; - } - case AlignAndDistribute::SELECTION: - { - Geom::OptRect b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds(); - if (b) { - mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], - a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); - } else { - return; - } + b = selection->preferredBounds(); break; - } - default: g_assert_not_reached (); break; - }; // end of switch + }; + + g_return_if_fail(b); + + Geom::Point mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], + a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); // Top hack: temporarily set clone compensation to unmoved, so that we can align/distribute // clones with their original (and the move of the original does not disturb the @@ -188,9 +164,8 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) { prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); bool changed = false; - Geom::OptRect b; if (sel_as_group) - b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds(); + b = selection->preferredBounds(); //Move each item in the selected list separately for (std::list::iterator it(selected.begin()); @@ -199,7 +174,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) { { sp_desktop_document (desktop)->ensureUpToDate(); if (!sel_as_group) - b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds(); + b = (*it)->desktopPreferredBounds(); if (b) { Geom::Point const sp(a.sx0 * b->min()[Geom::X] + a.sx1 * b->max()[Geom::X], a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]); -- cgit v1.2.3 From bea3d29ac007d6c8faca786538fafb0d7d789ffc Mon Sep 17 00:00:00 2001 From: Eric Greveson Date: Wed, 10 Jul 2013 11:50:45 +0100 Subject: Added "dbus-name" command line option to allow a D-Bus bus name other than "org.inkscape" to be specified. This allows multiple Inkscape instances to be controlled over D-Bus in a single user session. (bzr r12402.1.1) --- src/extension/dbus/dbus-init.cpp | 29 ++++++++++++++++++++-- src/extension/dbus/dbus-init.h | 10 ++++++++ src/extension/dbus/document-interface.h | 3 --- src/extension/dbus/wrapper/inkscape-dbus-wrapper.h | 2 -- src/main.cpp | 20 +++++++++++++++ 5 files changed, 57 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index eb62f4b3a..19b48e10d 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -36,7 +36,14 @@ #include - +namespace +{ + // This stores the bus name to use for this app instance. By default, it + // will be set to org.inkscape. However, users may provide other names by + // setting command-line parameters when starting Inkscape, so that more + // than one instance of Inkscape may be used by external scripts. + gchar *instance_bus_name = NULL; +} namespace Inkscape { namespace Extension { @@ -120,6 +127,11 @@ dbus_register_document(Inkscape::ActionContext const & target) void init (void) { + if (instance_bus_name == NULL) { + // Set the bus name to the default + instance_bus_name = strdup("org.inkscape"); + } + guint result; GError *error = NULL; DBusGConnection *connection; @@ -127,7 +139,7 @@ init (void) connection = dbus_get_connection(); proxy = dbus_get_proxy(connection); org_freedesktop_DBus_request_name (proxy, - "org.inkscape", + instance_bus_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &result, &error); //create interface for application dbus_register_object (connection, @@ -198,6 +210,19 @@ init_desktop (void) { return strdup(name.c_str()); } +void +dbus_set_bus_name(gchar * bus_name) +{ + g_assert(bus_name != NULL); + g_assert(instance_bus_name == NULL); + instance_bus_name = strdup(bus_name); +} +gchar * +dbus_get_bus_name() +{ + g_assert(instance_bus_name != NULL); + return instance_bus_name; +} } } } /* namespace Inkscape::Extension::Dbus */ diff --git a/src/extension/dbus/dbus-init.h b/src/extension/dbus/dbus-init.h index 486e55b86..7862ad3c3 100644 --- a/src/extension/dbus/dbus-init.h +++ b/src/extension/dbus/dbus-init.h @@ -28,6 +28,16 @@ gchar * init_desktop (void); gchar * dbus_init_desktop_interface (SPDesktop * dt); +/** Set the bus name to use. Default is "org.inkscape". + This function should only be called once, before init(), if a non-default + bus name is required. */ +void dbus_set_bus_name(gchar * bus_name); + +/** Get the bus name for this instance. Default is "org.inkscape". + This function should only be called after init(). + The returned gchar * is owned by this module and should not be freed. */ +gchar * dbus_get_bus_name(); + } } } /* namespace Dbus, Extension, Inkscape */ #endif /* INKSCAPE_EXTENSION_DBUS_INIT_H__ */ diff --git a/src/extension/dbus/document-interface.h b/src/extension/dbus/document-interface.h index 00d964f36..27460de52 100644 --- a/src/extension/dbus/document-interface.h +++ b/src/extension/dbus/document-interface.h @@ -34,9 +34,6 @@ class SPDesktop; class SPItem; - -// TODO: this define doesn't seem to be used... although the path itself is also hardcoded in dbus-init.cpp -#define DBUS_DOCUMENT_INTERFACE_PATH "/org/inkscape/document" #define TYPE_DOCUMENT_INTERFACE (document_interface_get_type ()) #define DOCUMENT_INTERFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_DOCUMENT_INTERFACE, DocumentInterface)) diff --git a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h index 79f8188d4..20830bd65 100644 --- a/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h +++ b/src/extension/dbus/wrapper/inkscape-dbus-wrapper.h @@ -8,8 +8,6 @@ //#include //#include - -#define DBUS_DOCUMENT_INTERFACE_PATH "/org/inkscape/document" #define TYPE_DOCUMENT_INTERFACE (document_interface_get_type ()) #define DOCUMENT_INTERFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_DOCUMENT_INTERFACE, DocumentInterface)) diff --git a/src/main.cpp b/src/main.cpp index ba51951da..4e2f2fd2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,6 +103,11 @@ #endif // WIN32 #include "extension/init.h" +// Not ideal, but there doesn't appear to be a nicer system in place for +// passing command-line parameters to extensions before initialization... +#ifdef WITH_DBUS +#include "extension/dbus/dbus-init.h" +#endif // WITH_DBUS #include #include @@ -171,6 +176,7 @@ enum { SP_ARG_VACUUM_DEFS, #ifdef WITH_DBUS SP_ARG_DBUS_LISTEN, + SP_ARG_DBUS_NAME, #endif // WITH_DBUS SP_ARG_VERB_LIST, SP_ARG_VERB, @@ -227,6 +233,7 @@ static gboolean sp_shell = FALSE; static gboolean sp_vacuum_defs = FALSE; #ifdef WITH_DBUS static gboolean sp_dbus_listen = FALSE; +static gchar *sp_dbus_name = NULL; #endif // WITH_DBUS static gchar *sp_export_png_utf8 = NULL; static gchar *sp_export_svg_utf8 = NULL; @@ -274,6 +281,7 @@ static void resetCommandlineGlobals() { sp_vacuum_defs = FALSE; #ifdef WITH_DBUS sp_dbus_listen = FALSE; + sp_dbus_name = NULL; #endif // WITH_DBUS sp_export_png_utf8 = NULL; @@ -487,6 +495,11 @@ struct poptOption options[] = { POPT_ARG_NONE, &sp_dbus_listen, SP_ARG_DBUS_LISTEN, N_("Enter a listening loop for D-Bus messages in console mode"), NULL}, + + {"dbus-name", 0, + POPT_ARG_STRING, &sp_dbus_name, SP_ARG_DBUS_NAME, + N_("Specify the D-Bus bus name to listen for messages on (default is org.inkscape)"), + N_("BUS-NAME")}, #endif // WITH_DBUS {"verb-list", 0, @@ -885,6 +898,13 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest ) if ( sp_global_printer ) sp_global_printer_utf8 = g_strdup( sp_global_printer ); } + +#ifdef WITH_DBUS + // Before initializing extensions, we must set the DBus bus name if required + if (sp_dbus_name != NULL) { + Inkscape::Extension::Dbus::dbus_set_bus_name(sp_dbus_name); + } +#endif // Return the list if wanted, else free it up. if ( flDest ) { -- cgit v1.2.3 From 80a911db81b651f38205c1eb926af4986bc033e8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 10 Jul 2013 22:24:38 -0400 Subject: Step 2 refactoring the align functions, added some functionality to selection. (bzr r12413) --- src/selection.cpp | 30 ++++++++ src/selection.h | 18 +++++ src/ui/dialog/align-and-distribute.cpp | 127 +++++---------------------------- src/ui/dialog/align-and-distribute.h | 10 +-- 4 files changed, 68 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/selection.cpp b/src/selection.cpp index d018aba0c..83caaf459 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -42,6 +42,7 @@ namespace Inkscape { Selection::Selection(LayerModel *layers, SPDesktop *desktop) : + align_point(NULL), _objs(NULL), _reprs(NULL), _items(NULL), @@ -358,6 +359,35 @@ SPItem *Selection::singleItem() { } } +SPItem *Selection::smallestItem(Selection::CompareSize compare) { + return _sizeistItem(true, compare); +} + +SPItem *Selection::largestItem(Selection::CompareSize compare) { + return _sizeistItem(false, compare); +} + +SPItem *Selection::_sizeistItem(bool small, Selection::CompareSize compare) { + GSList const *items = const_cast(this)->itemList(); + gdouble max = small ? 1e18 : 0; + SPItem *ist = NULL; + + for ( GSList const *i = items; i != NULL ; i = i->next ) { + Geom::OptRect bbox = SP_ITEM(i->data)->desktopPreferredBounds(); + if (!bbox) continue; + + gdouble size = compare == 2 ? + (*bbox)[Geom::X].extent() * (*bbox)[Geom::Y].extent() : + (*bbox)[compare == 1 ? Geom::X : Geom::Y].extent(); + size = small ? size : size * -1; + if (size < max) { + max = size; + ist = SP_ITEM(i->data); + } + } + return ist; +} + Inkscape::XML::Node *Selection::singleRepr() { SPObject *obj=single(); return obj ? obj->getRepr() : NULL; diff --git a/src/selection.h b/src/selection.h index f076cf7aa..25c018f7b 100644 --- a/src/selection.h +++ b/src/selection.h @@ -27,6 +27,7 @@ #include "sp-item.h" #include "snapped-point.h" + class SPDesktop; class SPItem; class SPBox3D; @@ -63,6 +64,7 @@ class Selection : public Inkscape::GC::Managed<>, public Inkscape::GC::Anchored { public: + enum CompareSize { HORIZONTAL, VERTICAL, AREA }; /** * Constructs an selection object, bound to a particular * layer model @@ -219,6 +221,16 @@ public: */ SPItem *singleItem(); + /** + * Returns the smallest item from this selection. + */ + SPItem *smallestItem(CompareSize compare); + + /** + * Returns the largest item from this selection. + */ + SPItem *largestItem(CompareSize compare); + /** * Returns a single selected object's xml node. * @@ -308,6 +320,11 @@ public: return _modified_signal.connect(slot); } + /** + * Selection wants to be aligned to this point, not bbox + */ + Geom::Point *align_point; + private: /** no copy. */ Selection(Selection const &); @@ -349,6 +366,7 @@ private: void add_3D_boxes_recursively(SPObject *obj); void remove_box_perspective(SPBox3D *box); void remove_3D_boxes_recursively(SPObject *obj); + SPItem *_sizeistItem(bool small, CompareSize compare); std::list _3dboxes; diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6a1cfc0ba..ed3f3adce 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -103,45 +103,30 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) const Coeffs &a = _allCoeffs[index]; Geom::OptRect b = Geom::OptRect(); - AlignAndDistribute::AlignTarget target = AlignAndDistribute::getAlignTarget(); + Selection::CompareSize horiz = (a.mx0 != 0.0) || (a.mx1 != 0.0) + ? Selection::HORIZONTAL : Selection::VERTICAL; - switch (target) + switch (AlignTarget(prefs->getInt("/dialogs/align/align-to", 6))) { - case AlignAndDistribute::LAST: - case AlignAndDistribute::FIRST: - case AlignAndDistribute::BIGGEST: - case AlignAndDistribute::SMALLEST: - { - //Check 2 or more selected objects - std::list::iterator second(selected.begin()); - ++second; - if (second == selected.end()) - return; - //Find the master (anchor on which the other objects are aligned) - std::list::iterator master( - AlignAndDistribute::find_master ( - selected, - (a.mx0 != 0.0) || - (a.mx1 != 0.0) ) - ); - //remove the master from the selection - SPItem * thing = *master; - // TODO: either uncomment or remove the following commented lines, depending on which - // behaviour of moving objects makes most sense; also cf. discussion at - // https://bugs.launchpad.net/inkscape/+bug/255933 - /*if (!sel_as_group) { */ - selected.erase(master); - /*}*/ - b = thing->desktopPreferredBounds(); + case LAST: + b = SP_ITEM(*selected.begin())->desktopPreferredBounds(); break; - } - case AlignAndDistribute::PAGE: + case FIRST: + b = SP_ITEM(*--(selected.end()))->desktopPreferredBounds(); + break; + case BIGGEST: + b = selection->largestItem(horiz)->desktopPreferredBounds(); + break; + case SMALLEST: + b = selection->smallestItem(horiz)->desktopPreferredBounds(); + break; + case PAGE: b = sp_desktop_document(desktop)->preferredBounds(); break; - case AlignAndDistribute::DRAWING: + case DRAWING: b = sp_desktop_document(desktop)->getRoot()->desktopPreferredBounds(); break; - case AlignAndDistribute::SELECTION: + case SELECTION: b = selection->preferredBounds(); break; default: @@ -151,18 +136,10 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) g_return_if_fail(b); + // Generate the move point from the selected bounding box Geom::Point mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); - // Top hack: temporarily set clone compensation to unmoved, so that we can align/distribute - // clones with their original (and the move of the original does not disturb the - // clones). The only problem with this is that if there are outside-of-selection clones of - // a selected original, they will be unmoved too, possibly contrary to user's - // expecation. However this is a minor point compared to making align/distribute always - // work as expected, and "unmoved" is the default option anyway. - int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - bool changed = false; if (sel_as_group) b = selection->preferredBounds(); @@ -186,15 +163,10 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) } } - // restore compensation setting - prefs->setInt("/options/clonecompensation/value", saved_compensation); - if (changed) { DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Align")); } - - } @@ -1240,69 +1212,6 @@ void AlignAndDistribute::addBaselineButton(const Glib::ustring &id, const Glib:: *this, table, orientation, distribute)); } - - - -std::list::iterator AlignAndDistribute::find_master( std::list &list, bool horizontal){ - std::list::iterator master = list.end(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int prefs_bbox = prefs->getBool("/tools/bounding_box"); - switch (getAlignTarget()) { - case LAST: - return list.begin(); - break; - - case FIRST: - return --(list.end()); - break; - - case BIGGEST: - { - gdouble max = -1e18; - for (std::list::iterator it = list.begin(); it != list.end(); ++it) { - Geom::OptRect b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds(); - if (b) { - gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); - if (dim > max) { - max = dim; - master = it; - } - } - } - return master; - } - - case SMALLEST: - { - gdouble max = 1e18; - for (std::list::iterator it = list.begin(); it != list.end(); ++it) { - Geom::OptRect b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds(); - if (b) { - gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); - if (dim < max) { - max = dim; - master = it; - } - } - } - return master; - } - - default: - g_assert_not_reached (); - break; - - } // end of switch statement - return master; -} - -AlignAndDistribute::AlignTarget AlignAndDistribute::getAlignTarget() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - return AlignTarget(prefs->getInt("/dialogs/align/align-to", 6)); -} - - - } // namespace Dialog } // namespace UI } // namespace Inkscape diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index c9165a83e..dfd84535b 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -47,12 +47,6 @@ public: static AlignAndDistribute &getInstance() { return *new AlignAndDistribute(); } - enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION }; - - - - static AlignTarget getAlignTarget(); - #if WITH_GTKMM_3_0 Gtk::Grid &align_table(){return _alignTable;} Gtk::Grid &distribute_table(){return _distributeTable;} @@ -67,7 +61,6 @@ public: Gtk::Table &nodes_table(){return _nodesTable;} #endif - static std::list::iterator find_master(std::list &list, bool horizontal); void setMode(bool nodeEdit); Geom::OptRect randomize_bbox; @@ -189,6 +182,7 @@ public : double sx0, sx1, sy0, sy1; int verb_id; }; + enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION }; ActionAlign(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, @@ -204,6 +198,7 @@ public : * Static function called to align from a keyboard shortcut */ static void do_verb_action(SPDesktop *desktop, int verb); + static int verb_to_coeff(int verb); private : @@ -217,7 +212,6 @@ private : } static void do_action(SPDesktop *desktop, int index); - static int verb_to_coeff(int verb); guint _index; AlignAndDistribute &_dialog; -- cgit v1.2.3 From c3074d380bbdbd8ec8f17b9cfb3059119005a30b Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 10 Jul 2013 23:08:15 -0400 Subject: Remove align point, not required any more (bzr r12414) --- src/selection.cpp | 1 - src/selection.h | 5 ----- 2 files changed, 6 deletions(-) (limited to 'src') diff --git a/src/selection.cpp b/src/selection.cpp index 83caaf459..e66137f65 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -42,7 +42,6 @@ namespace Inkscape { Selection::Selection(LayerModel *layers, SPDesktop *desktop) : - align_point(NULL), _objs(NULL), _reprs(NULL), _items(NULL), diff --git a/src/selection.h b/src/selection.h index 25c018f7b..75351a4ff 100644 --- a/src/selection.h +++ b/src/selection.h @@ -320,11 +320,6 @@ public: return _modified_signal.connect(slot); } - /** - * Selection wants to be aligned to this point, not bbox - */ - Geom::Point *align_point; - private: /** no copy. */ Selection(Selection const &); -- cgit v1.2.3 From df87c3c1c14f2483a9dbfc8bf2ac69e9834a42bf Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 11 Jul 2013 06:41:25 -0400 Subject: Change small to sml to fix windows compile problem (bzr r12415) --- src/selection.cpp | 6 +++--- src/selection.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/selection.cpp b/src/selection.cpp index e66137f65..8f43d8e70 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -366,9 +366,9 @@ SPItem *Selection::largestItem(Selection::CompareSize compare) { return _sizeistItem(false, compare); } -SPItem *Selection::_sizeistItem(bool small, Selection::CompareSize compare) { +SPItem *Selection::_sizeistItem(bool sml, Selection::CompareSize compare) { GSList const *items = const_cast(this)->itemList(); - gdouble max = small ? 1e18 : 0; + gdouble max = sml ? 1e18 : 0; SPItem *ist = NULL; for ( GSList const *i = items; i != NULL ; i = i->next ) { @@ -378,7 +378,7 @@ SPItem *Selection::_sizeistItem(bool small, Selection::CompareSize compare) { gdouble size = compare == 2 ? (*bbox)[Geom::X].extent() * (*bbox)[Geom::Y].extent() : (*bbox)[compare == 1 ? Geom::X : Geom::Y].extent(); - size = small ? size : size * -1; + size = sml ? size : size * -1; if (size < max) { max = size; ist = SP_ITEM(i->data); diff --git a/src/selection.h b/src/selection.h index 75351a4ff..32eade21f 100644 --- a/src/selection.h +++ b/src/selection.h @@ -361,7 +361,7 @@ private: void add_3D_boxes_recursively(SPObject *obj); void remove_box_perspective(SPBox3D *box); void remove_3D_boxes_recursively(SPObject *obj); - SPItem *_sizeistItem(bool small, CompareSize compare); + SPItem *_sizeistItem(bool sml, CompareSize compare); std::list _3dboxes; -- cgit v1.2.3 From f5692180123a550cfd6d1b8780ee23096418dd79 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 12 Jul 2013 12:08:13 -0400 Subject: Do not effect the focus in align computation Fixed bugs: - https://launchpad.net/bugs/1200649 (bzr r12416) --- src/ui/dialog/align-and-distribute.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index ed3f3adce..8845b60e5 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -102,6 +102,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) if (selected.empty()) return; const Coeffs &a = _allCoeffs[index]; + SPItem *focus = NULL; Geom::OptRect b = Geom::OptRect(); Selection::CompareSize horiz = (a.mx0 != 0.0) || (a.mx1 != 0.0) ? Selection::HORIZONTAL : Selection::VERTICAL; @@ -109,16 +110,16 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) switch (AlignTarget(prefs->getInt("/dialogs/align/align-to", 6))) { case LAST: - b = SP_ITEM(*selected.begin())->desktopPreferredBounds(); + focus = SP_ITEM(*selected.begin()); break; case FIRST: - b = SP_ITEM(*--(selected.end()))->desktopPreferredBounds(); + focus = SP_ITEM(*--(selected.end())); break; case BIGGEST: - b = selection->largestItem(horiz)->desktopPreferredBounds(); + focus = selection->largestItem(horiz); break; case SMALLEST: - b = selection->smallestItem(horiz)->desktopPreferredBounds(); + focus = selection->smallestItem(horiz); break; case PAGE: b = sp_desktop_document(desktop)->preferredBounds(); @@ -134,6 +135,8 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) break; }; + if(focus) + b = focus->desktopPreferredBounds(); g_return_if_fail(b); // Generate the move point from the selected bounding box @@ -146,13 +149,12 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) //Move each item in the selected list separately for (std::list::iterator it(selected.begin()); - it != selected.end(); - ++it) + it != selected.end(); ++it) { sp_desktop_document (desktop)->ensureUpToDate(); if (!sel_as_group) b = (*it)->desktopPreferredBounds(); - if (b) { + if (b && (!focus || (*it) != focus)) { Geom::Point const sp(a.sx0 * b->min()[Geom::X] + a.sx1 * b->max()[Geom::X], a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]); Geom::Point const mp_rel( mp - sp ); -- cgit v1.2.3 From ed6229c5b41b72df6c59878aaae328cb2b6e3559 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 12 Jul 2013 13:06:09 -0400 Subject: Use Jon Cruz info about OptRect to correctly get area height and width (bzr r12417) --- src/selection.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/selection.cpp b/src/selection.cpp index 8f43d8e70..784219c88 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -372,12 +372,12 @@ SPItem *Selection::_sizeistItem(bool sml, Selection::CompareSize compare) { SPItem *ist = NULL; for ( GSList const *i = items; i != NULL ; i = i->next ) { - Geom::OptRect bbox = SP_ITEM(i->data)->desktopPreferredBounds(); - if (!bbox) continue; + Geom::OptRect obox = SP_ITEM(i->data)->desktopPreferredBounds(); + if (!obox || obox.isEmpty()) continue; + Geom::Rect bbox = *obox; - gdouble size = compare == 2 ? - (*bbox)[Geom::X].extent() * (*bbox)[Geom::Y].extent() : - (*bbox)[compare == 1 ? Geom::X : Geom::Y].extent(); + gdouble size = compare == 2 ? bbox.area() : + (compare == 1 ? bbox.width() : bbox.height()); size = sml ? size : size * -1; if (size < max) { max = size; -- cgit v1.2.3 From 44431062712056a395e0708b89f600a1ffb78343 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 13 Jul 2013 14:10:01 -0700 Subject: Whitespace cleanup. (bzr r12418) --- src/util/units.cpp | 158 ++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/util/units.cpp b/src/util/units.cpp index f822d01de..002bf3b07 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -60,10 +60,10 @@ int Unit::defaultDigits() const { * * The primary unit's conversion factor is required to be 1.00 */ -UnitTable::UnitTable() +UnitTable::UnitTable() { // if we swich to the xml file, don't forget to force locale to 'C' - // load("share/ui/units.xml"); // <-- Buggy + // load("share/ui/units.xml"); // <-- Buggy gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.txt", NULL); loadText(filename); g_free(filename); @@ -72,8 +72,8 @@ UnitTable::UnitTable() UnitTable::~UnitTable() { UnitMap::iterator iter = _unit_map.begin(); while (iter != _unit_map.end()) { - delete (*iter).second; - ++iter; + delete (*iter).second; + ++iter; } } @@ -81,7 +81,7 @@ UnitTable::~UnitTable() { void UnitTable::addUnit(Unit const &u, bool primary) { _unit_map[u.abbr] = new Unit(u); if (primary) { - _primary_unit[u.type] = u.abbr; + _primary_unit[u.type] = u.abbr; } } @@ -89,26 +89,26 @@ void UnitTable::addUnit(Unit const &u, bool primary) { Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { UnitMap::const_iterator iter = _unit_map.find(unit_abbr); if (iter != _unit_map.end()) { - return *((*iter).second); + return *((*iter).second); } else { - return Unit(); + return Unit(); } } /** Remove a unit definition from the given unit type table */ bool UnitTable::deleteUnit(Unit const &u) { if (u.abbr == _primary_unit[u.type]) { - // Cannot delete the primary unit type since it's - // used for conversions - return false; + // Cannot delete the primary unit type since it's + // used for conversions + return false; } UnitMap::iterator iter = _unit_map.find(u.abbr); if (iter != _unit_map.end()) { - delete (*iter).second; - _unit_map.erase(iter); - return true; + delete (*iter).second; + _unit_map.erase(iter); + return true; } else { - return false; + return false; } } @@ -125,9 +125,9 @@ UnitTable::UnitMap UnitTable::units(UnitType type) const UnitMap submap; for (UnitMap::const_iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) { - if (((*iter).second)->type == type) { - submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second)))); - } + if (((*iter).second)->type == type) { + submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second)))); + } } return submap; @@ -140,10 +140,10 @@ Glib::ustring UnitTable::primary(UnitType type) const } /** Loads units from a text file. - + loadText loads and merges the contents of the given file into the UnitTable, possibly overwriting existing unit definitions. - + @param filename: file to be loaded*/ bool UnitTable::loadText(Glib::ustring const &filename) { @@ -152,11 +152,11 @@ bool UnitTable::loadText(Glib::ustring const &filename) // Open file for reading FILE * f = fopen(filename.c_str(), "r"); if (f == NULL) { - g_warning("Could not open units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Could not open units file '%s': %s\n", + filename.c_str(), strerror(errno)); g_warning("* INKSCAPE_DATADIR is: '%s'\n", INKSCAPE_DATADIR); g_warning("* INKSCAPE_UIDIR is: '%s'\n", INKSCAPE_UIDIR); - return false; + return false; } // bypass current locale in order to make @@ -167,51 +167,51 @@ bool UnitTable::loadText(Glib::ustring const &filename) setlocale (LC_NUMERIC, "C"); while (fgets(buf, BUFSIZE, f) != NULL) { - char name[BUFSIZE]; - char plural[BUFSIZE]; - char abbr[BUFSIZE]; - char type[BUFSIZE]; - double factor; - char primary[BUFSIZE]; - - int nchars = 0; - // locale is set to C, scanning %lf should work _everywhere_ - if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n", - name, plural, abbr, type, &factor, primary, &nchars) != 6) - { - // Skip the line - doesn't appear to be valid - continue; - } - - g_assert(nchars < BUFSIZE); - - char *desc = buf; - desc += nchars; // buf is now only the description - - // insert into _unit_map - Unit u; - u.name = name; - u.name_plural = plural; - u.abbr = abbr; - u.description = desc; - u.factor = factor; - - if (streq(type, "DIMENSIONLESS")) { - u.type = UNIT_TYPE_DIMENSIONLESS; - } else if (streq(type, "LINEAR")) { - u.type = UNIT_TYPE_LINEAR; - } else if (streq(type, "RADIAL")) { - u.type = UNIT_TYPE_RADIAL; - } else if (streq(type, "FONT_HEIGHT")) { - u.type = UNIT_TYPE_FONT_HEIGHT; - } else { - g_warning("Skipping unknown unit type '%s' for %s.\n", - type, name); - continue; - } - - // if primary is 'Y', list this unit as a primary - addUnit(u, (primary[0]=='Y' || primary[0]=='y')); + char name[BUFSIZE]; + char plural[BUFSIZE]; + char abbr[BUFSIZE]; + char type[BUFSIZE]; + double factor; + char primary[BUFSIZE]; + + int nchars = 0; + // locale is set to C, scanning %lf should work _everywhere_ + if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n", + name, plural, abbr, type, &factor, primary, &nchars) != 6) + { + // Skip the line - doesn't appear to be valid + continue; + } + + g_assert(nchars < BUFSIZE); + + char *desc = buf; + desc += nchars; // buf is now only the description + + // insert into _unit_map + Unit u; + u.name = name; + u.name_plural = plural; + u.abbr = abbr; + u.description = desc; + u.factor = factor; + + if (streq(type, "DIMENSIONLESS")) { + u.type = UNIT_TYPE_DIMENSIONLESS; + } else if (streq(type, "LINEAR")) { + u.type = UNIT_TYPE_LINEAR; + } else if (streq(type, "RADIAL")) { + u.type = UNIT_TYPE_RADIAL; + } else if (streq(type, "FONT_HEIGHT")) { + u.type = UNIT_TYPE_FONT_HEIGHT; + } else { + g_warning("Skipping unknown unit type '%s' for %s.\n", + type, name); + continue; + } + + // if primary is 'Y', list this unit as a primary + addUnit(u, (primary[0]=='Y' || primary[0]=='y')); } @@ -221,9 +221,9 @@ bool UnitTable::loadText(Glib::ustring const &filename) // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); - return false; + g_warning("Error closing units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } return true; @@ -235,9 +235,9 @@ bool UnitTable::load(Glib::ustring const &filename) { int result = handler.parseFile( filename.c_str() ); if ( result != 0 ) { // perhaps - g_warning("Problem loading units file '%s': %d\n", - filename.c_str(), result); - return false; + g_warning("Problem loading units file '%s': %d\n", + filename.c_str(), result); + return false; } return true; @@ -249,9 +249,9 @@ bool UnitTable::save(Glib::ustring const &filename) { // open file for writing FILE *f = fopen(filename.c_str(), "w"); if (f == NULL) { - g_warning("Could not open units file '%s': %s\n", - filename.c_str(), strerror(errno)); - return false; + g_warning("Could not open units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } // write out header @@ -268,9 +268,9 @@ bool UnitTable::save(Glib::ustring const &filename) { // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); - return false; + g_warning("Error closing units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } return true; -- cgit v1.2.3 From 8f989e27529c399b7bc23eed49c88df42f42ff1c Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 13 Jul 2013 15:06:55 -0700 Subject: Minor C++ish refactoring pass. (bzr r12419) --- src/util/units.cpp | 195 ++++++++++++++++++++++++++++------------------------- src/util/units.h | 62 +++++++++++++++-- 2 files changed, 158 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/util/units.cpp b/src/util/units.cpp index 002bf3b07..d1275b082 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -11,6 +11,39 @@ #include "path-prefix.h" #include "streq.h" +using Inkscape::Util::UNIT_TYPE_DIMENSIONLESS; +using Inkscape::Util::UNIT_TYPE_LINEAR; +using Inkscape::Util::UNIT_TYPE_RADIAL; +using Inkscape::Util::UNIT_TYPE_FONT_HEIGHT; + +namespace +{ + +/** + * A std::map that gives the data type value for the string version. + * + * Note that we'd normally not return a reference to an internal version, but + * for this constant case it allows us to check against getTypeMappings().end(). + */ +/** @todo consider hiding map behind hasFoo() and getFoo() type functions.*/ +std::map &getTypeMappings() +{ + static bool init = false; + static std::map typeMap; + if (!init) + { + init = true; + typeMap["DIMENSIONLESS"] = UNIT_TYPE_DIMENSIONLESS; + typeMap["LINEAR"] = UNIT_TYPE_LINEAR; + typeMap["RADIAL"] = UNIT_TYPE_RADIAL; + typeMap["FONT_HEIGHT"] = UNIT_TYPE_FONT_HEIGHT; + // Note that code was not yet handling LINEAR_SCALED, TIME, QTY and NONE + } + return typeMap; +} + +} // namespace + namespace Inkscape { namespace Util { @@ -40,26 +73,46 @@ UnitsSAXHandler::UnitsSAXHandler(UnitTable *table) : #define BUFSIZE (255) -/** - * Returns the suggested precision to use for displaying numbers - * of this unit. - */ +Unit::Unit() : + type(UNIT_TYPE_DIMENSIONLESS), // should this or NONE be the default? + factor(1.0), + name(), + name_plural(), + abbr(), + description() +{ +} + +Unit::Unit(UnitType type, + double factor, + Glib::ustring const &name, + Glib::ustring const &name_plural, + Glib::ustring const &abbr, + Glib::ustring const &description) : + type(type), + factor(factor), + name(name), + name_plural(name_plural), + abbr(abbr), + description(description) +{ +} + +void Unit::clear() +{ + *this = Unit(); +} + int Unit::defaultDigits() const { int factor_digits = int(log10(factor)); if (factor_digits < 0) { g_warning("factor = %f, factor_digits = %d", factor, factor_digits); g_warning("factor_digits < 0 - returning 0"); - return 0; - } else { - return factor_digits; + factor_digits = 0; } + return factor_digits; } -/** - * Initializes the unit tables and identifies the primary unit types. - * - * The primary unit's conversion factor is required to be 1.00 - */ UnitTable::UnitTable() { // if we swich to the xml file, don't forget to force locale to 'C' @@ -70,14 +123,12 @@ UnitTable::UnitTable() } UnitTable::~UnitTable() { - UnitMap::iterator iter = _unit_map.begin(); - while (iter != _unit_map.end()) { + for (UnitMap::iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) + { delete (*iter).second; - ++iter; } } -/** Add a new unit to the table */ void UnitTable::addUnit(Unit const &u, bool primary) { _unit_map[u.abbr] = new Unit(u); if (primary) { @@ -85,7 +136,6 @@ void UnitTable::addUnit(Unit const &u, bool primary) { } } -/** Retrieve a given unit based on its string identifier */ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { UnitMap::const_iterator iter = _unit_map.find(unit_abbr); if (iter != _unit_map.end()) { @@ -95,36 +145,31 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { } } -/** Remove a unit definition from the given unit type table */ bool UnitTable::deleteUnit(Unit const &u) { - if (u.abbr == _primary_unit[u.type]) { - // Cannot delete the primary unit type since it's - // used for conversions - return false; - } - UnitMap::iterator iter = _unit_map.find(u.abbr); - if (iter != _unit_map.end()) { - delete (*iter).second; - _unit_map.erase(iter); - return true; - } else { - return false; + bool deleted = false; + // Cannot delete the primary unit type since it's + // used for conversions + if (u.abbr != _primary_unit[u.type]) { + UnitMap::iterator iter = _unit_map.find(u.abbr); + if (iter != _unit_map.end()) { + delete (*iter).second; + _unit_map.erase(iter); + deleted = true; + } } + return deleted; } -/** Returns true if the given string 'name' is a valid unit in the table */ bool UnitTable::hasUnit(Glib::ustring const &unit) const { UnitMap::const_iterator iter = _unit_map.find(unit); return (iter != _unit_map.end()); } -/** Provides an iteratable list of items in the given unit table */ UnitTable::UnitMap UnitTable::units(UnitType type) const { UnitMap submap; - for (UnitMap::const_iterator iter = _unit_map.begin(); - iter != _unit_map.end(); ++iter) { + for (UnitMap::const_iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) { if (((*iter).second)->type == type) { submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second)))); } @@ -133,21 +178,14 @@ UnitTable::UnitMap UnitTable::units(UnitType type) const return submap; } -/** Returns the default unit abbr for the given type */ Glib::ustring UnitTable::primary(UnitType type) const { return _primary_unit[type]; } -/** Loads units from a text file. - - loadText loads and merges the contents of the given file into the UnitTable, - possibly overwriting existing unit definitions. - - @param filename: file to be loaded*/ bool UnitTable::loadText(Glib::ustring const &filename) { - char buf[BUFSIZE]; + char buf[BUFSIZE] = {0}; // Open file for reading FILE * f = fopen(filename.c_str(), "r"); @@ -159,23 +197,24 @@ bool UnitTable::loadText(Glib::ustring const &filename) return false; } + /** @todo fix this to use C++ means and explicit locale to avoid need to change. */ // bypass current locale in order to make // sscanf read floats with '.' as a separator // set locale to 'C' and keep old locale - char *old_locale; - old_locale = g_strdup (setlocale (LC_NUMERIC, NULL)); + char *old_locale = g_strdup(setlocale(LC_NUMERIC, NULL)); setlocale (LC_NUMERIC, "C"); while (fgets(buf, BUFSIZE, f) != NULL) { - char name[BUFSIZE]; - char plural[BUFSIZE]; - char abbr[BUFSIZE]; - char type[BUFSIZE]; - double factor; - char primary[BUFSIZE]; + char name[BUFSIZE] = {0}; + char plural[BUFSIZE] = {0}; + char abbr[BUFSIZE] = {0}; + char type[BUFSIZE] = {0}; + double factor = 0.0; + char primary[BUFSIZE] = {0}; int nchars = 0; // locale is set to C, scanning %lf should work _everywhere_ + /** @todo address %15n, which causes a warning: */ if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n", name, plural, abbr, type, &factor, primary, &nchars) != 6) { @@ -189,30 +228,17 @@ bool UnitTable::loadText(Glib::ustring const &filename) desc += nchars; // buf is now only the description // insert into _unit_map - Unit u; - u.name = name; - u.name_plural = plural; - u.abbr = abbr; - u.description = desc; - u.factor = factor; - - if (streq(type, "DIMENSIONLESS")) { - u.type = UNIT_TYPE_DIMENSIONLESS; - } else if (streq(type, "LINEAR")) { - u.type = UNIT_TYPE_LINEAR; - } else if (streq(type, "RADIAL")) { - u.type = UNIT_TYPE_RADIAL; - } else if (streq(type, "FONT_HEIGHT")) { - u.type = UNIT_TYPE_FONT_HEIGHT; - } else { - g_warning("Skipping unknown unit type '%s' for %s.\n", - type, name); + if (getTypeMappings().find(type) == getTypeMappings().end()) + { + g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); continue; } + UnitType utype = getTypeMappings()[type]; + + Unit u(utype, factor, name, plural, abbr, desc); // if primary is 'Y', list this unit as a primary addUnit(u, (primary[0]=='Y' || primary[0]=='y')); - } // set back the saved locale @@ -221,8 +247,7 @@ bool UnitTable::loadText(Glib::ustring const &filename) // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -235,22 +260,19 @@ bool UnitTable::load(Glib::ustring const &filename) { int result = handler.parseFile( filename.c_str() ); if ( result != 0 ) { // perhaps - g_warning("Problem loading units file '%s': %d\n", - filename.c_str(), result); + g_warning("Problem loading units file '%s': %d\n", filename.c_str(), result); return false; } return true; } -/** Saves the current UnitTable to the given file. */ bool UnitTable::save(Glib::ustring const &filename) { // open file for writing FILE *f = fopen(filename.c_str(), "w"); if (f == NULL) { - g_warning("Could not open units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Could not open units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -268,8 +290,7 @@ bool UnitTable::save(Glib::ustring const &filename) { // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -281,12 +302,7 @@ void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) { if (streq("unit", (char const *)name)) { // reset for next use - unit.name.clear(); - unit.name_plural.clear(); - unit.abbr.clear(); - unit.description.clear(); - unit.type = UNIT_TYPE_DIMENSIONLESS; - unit.factor = 1.0; + unit.clear(); primary = false; skip = false; @@ -294,14 +310,9 @@ void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) char const *const key = (char const *)attrs[i]; if (streq("type", key)) { char const *type = (char const*)attrs[i+1]; - if (streq(type, "DIMENSIONLESS")) { - unit.type = UNIT_TYPE_DIMENSIONLESS; - } else if (streq(type, "LINEAR")) { - unit.type = UNIT_TYPE_LINEAR; - } else if (streq(type, "RADIAL")) { - unit.type = UNIT_TYPE_RADIAL; - } else if (streq(type, "FONT_HEIGHT")) { - unit.type = UNIT_TYPE_FONT_HEIGHT; + if (getTypeMappings().find(type) != getTypeMappings().end()) + { + unit.type = getTypeMappings()[type]; } else { g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); skip = true; diff --git a/src/util/units.h b/src/util/units.h index b22bdb1f2..40c89a4a0 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -36,40 +36,78 @@ const char DEG[] = "°"; class Unit { public: - Glib::ustring name; - Glib::ustring name_plural; - Glib::ustring abbr; - Glib::ustring description; - - UnitType type; + Unit(); + Unit(UnitType type, + double factor, + Glib::ustring const &name, + Glib::ustring const &name_plural, + Glib::ustring const &abbr, + Glib::ustring const &description); - double factor; + void clear(); bool isAbsolute() const { return type != UNIT_TYPE_DIMENSIONLESS; } + + /** + * Returns the suggested precision to use for displaying numbers + * of this unit. + */ int defaultDigits() const; + + UnitType type; + double factor; + Glib::ustring name; + Glib::ustring name_plural; + Glib::ustring abbr; + Glib::ustring description; }; class UnitTable { public: + /** + * Initializes the unit tables and identifies the primary unit types. + * + * The primary unit's conversion factor is required to be 1.00 + */ UnitTable(); virtual ~UnitTable(); typedef std::map UnitMap; + /** Add a new unit to the table */ void addUnit(Unit const& u, bool primary); + + /** Retrieve a given unit based on its string identifier */ Unit getUnit(Glib::ustring const& name) const; + + /** Remove a unit definition from the given unit type table */ bool deleteUnit(Unit const& u); + + /** Returns true if the given string 'name' is a valid unit in the table */ bool hasUnit(Glib::ustring const &name) const; + /** Provides an iteratable list of items in the given unit table */ UnitTable::UnitMap units(UnitType type) const; + /** Returns the default unit abbr for the given type */ Glib::ustring primary(UnitType type) const; double getScale() const; + void setScale(); bool load(Glib::ustring const &filename); + + /** Loads units from a text file. + * + * loadText loads and merges the contents of the given file into the UnitTable, + * possibly overwriting existing unit definitions. + * + * @param filename file to be loaded + */ bool loadText(Glib::ustring const &filename); + + /** Saves the current UnitTable to the given file. */ bool save(Glib::ustring const &filename); protected: @@ -88,3 +126,13 @@ class UnitTable { } // namespace Inkscape #endif // define INKSCAPE_UTIL_UNITS_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:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 4e088d33c04329fe57ef987d577f5aa57f83b644 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Tue, 16 Jul 2013 15:46:56 -0400 Subject: Shape calculations. re-introduce grid of a smaller size. (http://article.gmane.org/gmane.comp.graphics.inkscape.devel/40786) (bzr r12420) --- src/livarot/Shape.cpp | 8 ++++---- src/livarot/Shape.h | 12 ++++++------ src/livarot/ShapeMisc.cpp | 12 ++++++------ src/livarot/ShapeSweep.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/livarot/Shape.cpp b/src/livarot/Shape.cpp index 130b1b03a..c29444a33 100644 --- a/src/livarot/Shape.cpp +++ b/src/livarot/Shape.cpp @@ -334,8 +334,8 @@ Shape::AddPoint (const Geom::Point x) pData[n].nextLinkedPoint = -1; pData[n].askForWindingS = NULL; pData[n].askForWindingB = -1; - pData[n].rx[0] = /*Round*/ (p.x[0]); - pData[n].rx[1] = /*Round*/ (p.x[1]); + pData[n].rx[0] = Round(p.x[0]); + pData[n].rx[1] = Round(p.x[1]); } if (_has_voronoi_data) { @@ -2116,8 +2116,8 @@ void Shape::initialisePointData() pData[i].pending = 0; pData[i].edgeOnLeft = -1; pData[i].nextLinkedPoint = -1; - pData[i].rx[0] = /*Round*/ (getPoint(i).x[0]); - pData[i].rx[1] = /*Round*/ (getPoint(i).x[1]); + pData[i].rx[0] = Round(getPoint(i).x[0]); + pData[i].rx[1] = Round(getPoint(i).x[1]); } _point_data_initialised = true; diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h index b999b9dca..98fc2d7bf 100644 --- a/src/livarot/Shape.h +++ b/src/livarot/Shape.h @@ -266,20 +266,20 @@ public: // be careful when using this function // the coordinate rounding function -// inline static double Round(double x) -// { -// return ldexp(rint(ldexp(x, 5)), -5); -// } + inline static double Round(double x) + { + return ldexp(rint(ldexp(x, 9)), -9); + } // 2 miscannellous variations on it, to scale to and back the rounding grid inline static double HalfRound(double x) { - return ldexp(x, -5); + return ldexp(x, -9); } inline static double IHalfRound(double x) { - return ldexp(x, 5); + return ldexp(x, 9); } // boolean operations on polygons (requests intersection-free poylygons) diff --git a/src/livarot/ShapeMisc.cpp b/src/livarot/ShapeMisc.cpp index 5bb8a25ef..6fd40790f 100644 --- a/src/livarot/ShapeMisc.cpp +++ b/src/livarot/ShapeMisc.cpp @@ -49,8 +49,8 @@ Shape::ConvertToForme (Path * dest) for (int i = 0; i < numberOfPoints(); i++) { - pData[i].rx[0] = /*Round*/ (getPoint(i).x[0]); - pData[i].rx[1] = /*Round*/ (getPoint(i).x[1]); + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); } for (int i = 0; i < numberOfEdges(); i++) { @@ -199,8 +199,8 @@ Shape::ConvertToForme (Path * dest, int nbP, Path * *orig, bool splitWhenForced) for (int i = 0; i < numberOfPoints(); i++) { - pData[i].rx[0] = /*Round*/ (getPoint(i).x[0]); - pData[i].rx[1] = /*Round*/ (getPoint(i).x[1]); + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); } for (int i = 0; i < numberOfEdges(); i++) { @@ -352,8 +352,8 @@ Shape::ConvertToFormeNested (Path * dest, int nbP, Path * *orig, int wildPath,in for (int i = 0; i < numberOfPoints(); i++) { - pData[i].rx[0] = /*Round*/ (getPoint(i).x[0]); - pData[i].rx[1] = /*Round*/ (getPoint(i).x[1]); + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); } for (int i = 0; i < numberOfEdges(); i++) { diff --git a/src/livarot/ShapeSweep.cpp b/src/livarot/ShapeSweep.cpp index ffe5a9d73..c2fd83e31 100644 --- a/src/livarot/ShapeSweep.cpp +++ b/src/livarot/ShapeSweep.cpp @@ -250,8 +250,8 @@ Shape::ConvertToShape (Shape * a, FillRule directed, bool invert) } Geom::Point rPtX; - rPtX[0]= /*Round*/ (ptX[0]); - rPtX[1]= /*Round*/ (ptX[1]); + rPtX[0]= Round (ptX[0]); + rPtX[1]= Round (ptX[1]); int lastPointNo = -1; lastPointNo = AddPoint (rPtX); pData[lastPointNo].rx = rPtX; @@ -1051,8 +1051,8 @@ Shape::Booleen (Shape * a, Shape * b, BooleanOp mod,int cutPathID) } Geom::Point rPtX; - rPtX[0]= /*Round*/ (ptX[0]); - rPtX[1]= /*Round*/ (ptX[1]); + rPtX[0]= Round (ptX[0]); + rPtX[1]= Round (ptX[1]); int lastPointNo = -1; lastPointNo = AddPoint (rPtX); pData[lastPointNo].rx = rPtX; -- cgit v1.2.3