summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extension/dbus/application-interface.cpp9
-rw-r--r--src/extension/dbus/application-interface.h4
-rw-r--r--src/extension/dbus/application-interface.xml18
-rw-r--r--src/extension/dbus/dbus-init.cpp40
-rw-r--r--src/extension/dbus/dbus-init.h5
-rw-r--r--src/extension/dbus/document-interface.cpp361
-rw-r--r--src/extension/dbus/document-interface.h10
-rw-r--r--src/file.cpp33
-rw-r--r--src/file.h2
-rw-r--r--src/helper/action-context.cpp10
-rw-r--r--src/helper/action-context.h11
-rw-r--r--src/helper/action.cpp17
-rw-r--r--src/helper/action.h2
-rw-r--r--src/inkscape.cpp54
-rw-r--r--src/inkscape.h11
-rw-r--r--src/main.cpp53
-rw-r--r--src/select-context.cpp32
-rw-r--r--src/selection-chemistry.cpp37
-rw-r--r--src/selection-chemistry.h6
-rw-r--r--src/verbs.cpp74
20 files changed, 536 insertions, 253 deletions
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 <string.h>
#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 @@
</arg>
<doc:doc>
<doc:description>
- <doc:para>Create a new document interface and return it's location.</doc:para>
+ <doc:para>Create a new document interface and return its location.</doc:para>
</doc:description>
</doc:doc>
</method>
@@ -59,7 +59,7 @@
<method name="exit">
<doc:doc>
<doc:description>
- <doc:para>Exit Inkscape without saving. Fairly straightforward. </doc:para>
+ <doc:para>Exit Inkscape without saving (in GUI mode). Fairly straightforward.</doc:para>
</doc:description>
</doc:doc>
</method>
@@ -76,6 +76,20 @@
<doc:description>
<doc:para>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.</doc:para>
<doc:para>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.</doc:para>
+ <doc:para>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.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+ <method name="get_active_document">
+ <arg type="s" name="document_name" direction="out" >
+ <annotation name="org.freedesktop.DBus.GLib.ReturnVal" value="error"/>
+ <doc:doc>
+ <doc:summary>This string can be used to connect to the current active document.</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Get the location of the current active document (e.g. when running in console mode, when desktops are not available).</doc:para>
</doc:description>
</doc:doc>
</method>
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();
@@ -123,6 +127,38 @@ init_document (void) {
} //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)
{
DBusGConnection *connection;
@@ -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 <string.h>
#include <dbus/dbus-glib.h>
+#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 <gtk/gtk.h>
+#include <gtkmm/main.h>
#include <glibmm/convert.h>
#include <glibmm/i18n.h>
@@ -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 <b>%i</b> unused definition in &lt;defs&gt;.",
- "Removed <b>%i</b> unused definitions in &lt;defs&gt;.",
- diff),
- diff);
- } else {
- dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No unused definitions in &lt;defs&gt;."));
+ if (dt != NULL) {
+ // Show status messages when in GUI mode
+ if (diff > 0) {
+ dt->messageStack()->flashF(Inkscape::NORMAL_MESSAGE,
+ ngettext("Removed <b>%i</b> unused definition in &lt;defs&gt;.",
+ "Removed <b>%i</b> unused definitions in &lt;defs&gt;.",
+ diff),
+ diff);
+ } else {
+ dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No unused definitions in &lt;defs&gt;."));
+ }
}
}
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<SPDesktop *>(_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<SPDesktop *>(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<SPDocument *, int> document_set;
+ std::map<SPDocument *, AppSelectionModel *> selection_models;
GSList *desktops;
gchar *argv0;
gboolean dialogs_toggle;
@@ -481,6 +500,7 @@ inkscape_init (SPObject * object)
}
new (&inkscape->document_set) std::map<SPDocument *, int>();
+ new (&inkscape->selection_models) std::map<SPDocument *, AppSelectionModel *>();
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<SPDocument *, AppSelectionModel *>::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<SPDocument *, AppSelectionModel *>::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<SPObject*>(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<std::size_t>(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<SPDesktop*>(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<SPDesktop*>(sp_action_get_view(action));
+ // We can clear all without a desktop
+ bool handled = true;
+ switch (reinterpret_cast<std::size_t>(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<SPDesktop*>(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<SPDesktop*>(sp_action_get_view(action));
+ SPDesktop *dt = sp_action_get_desktop(action);
size_t verb = reinterpret_cast<std::size_t>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(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<SPDesktop*>(sp_action_get_view(action));
+ SPDesktop *dt = sp_action_get_desktop(action);
if (dt == NULL) {
show_gui_required_message(action);
return;