From f24f34bd713c7a26fbb6e13c2a44111223950738 Mon Sep 17 00:00:00 2001 From: Soren Berg Date: Sun, 12 Jul 2009 16:02:09 +0000 Subject: Core Dbus files. Init creates interfaces on Inkscape startup. Application and document interface provide API functions over Dbus. service.in file makes sure Inkscape starts automatically when someone connects to it over Dbus. (bzr r8254.1.3) --- src/extension/dbus/document-interface.cpp | 936 ++++++++++++++++++++++++++++++ 1 file changed, 936 insertions(+) create mode 100644 src/extension/dbus/document-interface.cpp (limited to 'src/extension/dbus/document-interface.cpp') diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp new file mode 100644 index 000000000..94f442865 --- /dev/null +++ b/src/extension/dbus/document-interface.cpp @@ -0,0 +1,936 @@ +#include "document-interface.h" +#include + +#include "verbs.h" +#include "helper/action.h" //sp_action_perform + +#include "inkscape.h" //inkscape_find_desktop_by_dkey, activate desktops + +#include "desktop-handles.h" //sp_desktop_document() +#include "xml/repr.h" //sp_repr_document_new + +#include "sp-object.h" + +#include "document.h" // sp_document_repr_doc + +#include "desktop-style.h" //sp_desktop_get_style + +#include "selection.h" //selection struct +#include "selection-chemistry.h"// lots of selection functions + +#include "sp-ellipse.h" + +#include "layer-fns.h" //LPOS_BELOW + +#include "style.h" //style_write + +/**************************************************************************** + HELPER / SHORTCUT FUNCTIONS +****************************************************************************/ + +const gchar* intToCString(int i) +{ + std::stringstream ss; + ss << i; + return ss.str().c_str(); +} + +SPObject * +get_object_by_name (SPDesktop *desk, gchar *name) +{ + return sp_desktop_document(desk)->getObjectById(name); +} + +const gchar * +get_name_from_object (SPObject * obj) +{ + return obj->repr->attribute("id"); +} + +void +desktop_ensure_active (SPDesktop* desk) { + if (desk != SP_ACTIVE_DESKTOP) + inkscape_activate_desktop (desk); + return; +} + +Inkscape::XML::Node * +document_retrive_node (SPDocument *doc, gchar *name) { + return (doc->getObjectById(name))->repr; +} + +gdouble +selection_get_center_x (Inkscape::Selection *sel){ + NRRect *box = g_new(NRRect, 1);; + box = sel->boundsInDocument(box); + return box->x0 + ((box->x1 - box->x0)/2); +} + +gdouble +selection_get_center_y (Inkscape::Selection *sel){ + NRRect *box = g_new(NRRect, 1);; + box = sel->boundsInDocument(box); + return box->y0 + ((box->y1 - box->y0)/2); +} +//move_to etc +const GSList * +selection_swap(SPDesktop *desk, gchar *name) +{ + Inkscape::Selection *sel = sp_desktop_selection(desk); + const GSList *oldsel = g_slist_copy((GSList *)sel->list()); + + sel->set(get_object_by_name(desk, name)); + return oldsel; +} + +void +selection_restore(SPDesktop *desk, const GSList * oldsel) +{ + Inkscape::Selection *sel = sp_desktop_selection(desk); + sel->setList(oldsel); +} + +Inkscape::XML::Node * +dbus_create_node (SPDesktop *desk, gboolean isrect) +{ + SPDocument * doc = sp_desktop_document (desk); + Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); + gchar *type; + if (isrect) + type = (gchar *)"svg:rect"; + else + type = (gchar *)"svg:path"; + return xml_doc->createElement(type); +} + +gchar * +finish_create_shape (DocumentInterface *object, GError **error, Inkscape::XML::Node *newNode, gchar *desc) +{ + + SPCSSAttr *style = sp_desktop_get_style(object->desk, TRUE); + + if (style) { + newNode->setAttribute("style", sp_repr_css_write_string(style), TRUE); + } + else { + 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(); + + if (object->updates) + sp_document_done(sp_desktop_document(object->desk), 0, (gchar *)desc); + else + document_interface_pause_updates(object, error); + + return strdup(newNode->attribute("id")); +} + +gboolean +dbus_call_verb (DocumentInterface *object, int verbid, GError **error) +{ + SPDesktop *desk2 = object->desk; + + if ( desk2 ) { + Inkscape::Verb *verb = Inkscape::Verb::get( verbid ); + if ( verb ) { + SPAction *action = verb->get_action(desk2); + if ( action ) { + sp_action_perform( action, NULL ); + if (object->updates) { + sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip())); + } + return TRUE; + } + } + } + return FALSE; +} + +/**************************************************************************** + DOCUMENT INTERFACE CLASS STUFF +****************************************************************************/ + +G_DEFINE_TYPE(DocumentInterface, document_interface, G_TYPE_OBJECT) + +static void +document_interface_finalize (GObject *object) +{ + G_OBJECT_CLASS (document_interface_parent_class)->finalize (object); +} + + +static void +document_interface_class_init (DocumentInterfaceClass *klass) +{ + GObjectClass *object_class; + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = document_interface_finalize; +} + +static void +document_interface_init (DocumentInterface *object) +{ + object->desk = NULL; +} + + +DocumentInterface * +document_interface_new (void) +{ + return (DocumentInterface*)g_object_new (TYPE_DOCUMENT_INTERFACE, NULL); +} + +/**************************************************************************** + MISC FUNCTIONS +****************************************************************************/ + +gboolean +document_interface_delete_all (DocumentInterface *object, GError **error) +{ + sp_edit_clear_all (object->desk); + return TRUE; +} + +void +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(desk2); + if ( action ) { + sp_action_perform( action, NULL ); + if (object->updates) { + sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip())); + } + } + } + } +} + + +/**************************************************************************** + CREATION FUNCTIONS +****************************************************************************/ + +gchar* +document_interface_rectangle (DocumentInterface *object, int x, int y, + int width, int height, GError **error) +{ + + + Inkscape::XML::Node *newNode = dbus_create_node(object->desk, TRUE); + 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"); +} + +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, FALSE); + 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"); +} + +gchar* +document_interface_polygon (DocumentInterface *object, 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->desk, FALSE); + newNode->setAttribute("inkscape:flatsided", "true"); + newNode->setAttribute("sodipodi:type", "star"); + sp_repr_set_int(newNode, "sodipodi:cx", cx); + sp_repr_set_int(newNode, "sodipodi:cy", cy); + sp_repr_set_int(newNode, "sodipodi:r1", radius); + sp_repr_set_int(newNode, "sodipodi:r2", radius); + sp_repr_set_int(newNode, "sodipodi:sides", sides); + sp_repr_set_int(newNode, "inkscape:randomized", 0); + sp_repr_set_svg_double(newNode, "sodipodi:arg1", rot); + 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"); +} + +gchar* +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, FALSE); + newNode->setAttribute("inkscape:flatsided", "false"); + newNode->setAttribute("sodipodi:type", "star"); + sp_repr_set_int(newNode, "sodipodi:cx", cx); + sp_repr_set_int(newNode, "sodipodi:cy", cy); + sp_repr_set_int(newNode, "sodipodi:r1", r1); + sp_repr_set_int(newNode, "sodipodi:r2", r2); + sp_repr_set_int(newNode, "sodipodi:sides", sides); + sp_repr_set_int(newNode, "inkscape:randomized", 0); + sp_repr_set_svg_double(newNode, "sodipodi:arg1", arg1); + 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"); +} + +gchar* +document_interface_ellipse (DocumentInterface *object, 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); +} + +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, FALSE); + std::stringstream out; + printf("X2: %d\nY2 %d\n", x2, y2); + out << "m " << x << "," << y << " " << x2 << "," << y2; + printf ("PATH: %s\n", out.str().c_str()); + newNode->setAttribute("d", out.str().c_str()); + return finish_create_shape (object, error, newNode, (gchar *)"create line"); +} + +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, FALSE); + newNode->setAttribute("sodipodi:type", "spiral"); + sp_repr_set_int(newNode, "sodipodi:cx", cx); + sp_repr_set_int(newNode, "sodipodi:cy", cy); + sp_repr_set_int(newNode, "sodipodi:radius", r); + sp_repr_set_int(newNode, "sodipodi:revolution", revolutions); + 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"); + newNode->setAttribute("style", "fill:none"); + return retval; +} + +gchar* +document_interface_text (DocumentInterface *object, gchar *text, GError **error) +{ + return NULL; +} + +gchar* +document_interface_node (DocumentInterface *object, gchar *type, GError **error) +{ + return NULL; +} + +/**************************************************************************** + ENVIORNMENT FUNCTIONS +****************************************************************************/ +gdouble +document_interface_document_get_width (DocumentInterface *object) +{ + return sp_document_width(sp_desktop_document(object->desk)); +} + +gdouble +document_interface_document_get_height (DocumentInterface *object) +{ + return sp_document_height(sp_desktop_document(object->desk)); +} + +gchar * +document_interface_document_get_css (DocumentInterface *object, GError **error) +{ + SPCSSAttr *current = (object->desk)->current; + return sp_repr_css_write_string(current); +} + +gboolean +document_interface_document_merge_css (DocumentInterface *object, + gchar *stylestring, GError **error) +{ + return FALSE; +} + +gboolean +document_interface_document_set_css (DocumentInterface *object, + gchar *stylestring, GError **error) +{ + return FALSE; +} + +gboolean +document_interface_document_resize_to_fit_selection (DocumentInterface *object, + GError **error) +{ + return FALSE; +} + +/**************************************************************************** + OBJECT FUNCTIONS +****************************************************************************/ + +gboolean +document_interface_set_attribute (DocumentInterface *object, char *shape, + char *attribute, char *newval, GError **error) +{ + Inkscape::XML::Node *newNode = get_object_by_name(object->desk, shape)->repr; + + /* ALTERNATIVE + Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name); + */ + if (newNode) + { + newNode->setAttribute(attribute, newval, TRUE); + return TRUE; + } + return FALSE; +} + +void +document_interface_set_int_attribute (DocumentInterface *object, + char *shape, char *attribute, + int newval, GError **error) +{ + Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr; + if (newNode) + sp_repr_set_int (newNode, attribute, newval); +} + + +void +document_interface_set_double_attribute (DocumentInterface *object, + char *shape, char *attribute, + double newval, GError **error) +{ + Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr; + if (newNode) + sp_repr_set_svg_double (newNode, attribute, newval); +} + +gchar * +document_interface_get_attribute (DocumentInterface *object, char *shape, + char *attribute, GError **error) +{ + SPDesktop *desk2 = object->desk; + SPDocument * doc = sp_desktop_document (desk2); + + // FIXME: Not sure if this is the most efficient way. + Inkscape::XML::Node *newNode = doc->getObjectById(shape)->repr; + + /* WORKS + Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name); + */ + if (newNode) + return g_strdup(newNode->attribute(attribute)); + return FALSE; +} + +gboolean +document_interface_move (DocumentInterface *object, gchar *name, gdouble x, + gdouble y, GError **error) +{ + const GSList *oldsel = selection_swap(object->desk, name); + sp_selection_move (object->desk, x, 0 - y); + selection_restore(object->desk, oldsel); + return TRUE; +} + +gboolean +document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x, + gdouble y, GError **error) +{ + const GSList *oldsel = selection_swap(object->desk, name); + Inkscape::Selection * sel = sp_desktop_selection(object->desk); + sp_selection_move (object->desk, x - selection_get_center_x(sel), + 0 - (y - selection_get_center_y(sel))); + selection_restore(object->desk, oldsel); + return TRUE; +} + +void +document_interface_object_to_path (DocumentInterface *object, + char *shape, GError **error) +{ + const GSList *oldsel = selection_swap(object->desk, shape); + dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); + selection_restore(object->desk, oldsel); +} + +gboolean +document_interface_get_path (DocumentInterface *object, char *pathname, GError **error) +{ + Inkscape::XML::Node *node = document_retrive_node (sp_desktop_document (object->desk), pathname); + if (node == NULL || node->attribute("d") == NULL) { + g_set_error(error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION, "Object is not a path or does not exist."); + return FALSE; + } + gchar *pathstr = strdup(node->attribute("d")); + printf("PATH: %s\n", pathstr); + //gfree (pathstr); + std::istringstream iss(pathstr); + std::copy(std::istream_iterator(iss), + std::istream_iterator(), + std::ostream_iterator(std::cout, "\n")); + + return TRUE; +} + +gboolean +document_interface_transform (DocumentInterface *object, gchar *shape, + gchar *transformstr, GError **error) +{ + //FIXME: This should merge transformations. + gchar trans[] = "transform"; + document_interface_set_attribute (object, shape, trans, transformstr, error); + return TRUE; +} + +gchar * +document_interface_get_css (DocumentInterface *object, gchar *shape, + GError **error) +{ +return NULL; +} + +gboolean +document_interface_modify_css (DocumentInterface *object, gchar *shape, + gchar *cssattrb, gchar *newval, GError **error) +{ + return FALSE; +} + +gboolean +document_interface_merge_css (DocumentInterface *object, gchar *shape, + gchar *stylestring, GError **error) +{ + return FALSE; +} + +gboolean +document_interface_move_to_layer (DocumentInterface *object, gchar *shape, + gchar *layerstr, GError **error) +{ + return FALSE; +} + +DBUSPoint ** +document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape) +{ + return NULL; +} + + +/**************************************************************************** + FILE I/O FUNCTIONS +****************************************************************************/ + +gboolean +document_interface_save (DocumentInterface *object, GError **error){ + return FALSE; +} + +gboolean +document_interface_load (DocumentInterface *object, + gchar *filename, GError **error){ + return FALSE; +} + +gboolean +document_interface_save_as (DocumentInterface *object, + gchar *filename, GError **error){ + return FALSE; +} + +gboolean +document_interface_print (DocumentInterface *object, GError **error){ + return FALSE; +} + +/**************************************************************************** + PROGRAM CONTROL FUNCTIONS +****************************************************************************/ + +gboolean +document_interface_close (DocumentInterface *object, GError **error){ + return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error); +} + +gboolean +document_interface_exit (DocumentInterface *object, GError **error){ + return dbus_call_verb (object, SP_VERB_FILE_QUIT, error); +} + +gboolean +document_interface_undo (DocumentInterface *object, GError **error){ + return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error); +} + +gboolean +document_interface_redo (DocumentInterface *object, GError **error){ + return dbus_call_verb (object, SP_VERB_EDIT_REDO, error); +} + + + +/**************************************************************************** + UPDATE FUNCTIONS +****************************************************************************/ + +void +document_interface_pause_updates (DocumentInterface *object, GError **error) +{ + object->updates = FALSE; + sp_desktop_document(object->desk)->root->uflags = FALSE; + sp_desktop_document(object->desk)->root->mflags = FALSE; +} + +void +document_interface_resume_updates (DocumentInterface *object, GError **error) +{ + object->updates = TRUE; + sp_desktop_document(object->desk)->root->uflags = TRUE; + sp_desktop_document(object->desk)->root->mflags = TRUE; + //sp_desktop_document(object->desk)->_updateDocument(); + sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions"); +} + +void +document_interface_update (DocumentInterface *object, GError **error) +{ + sp_desktop_document(object->desk)->root->uflags = TRUE; + sp_desktop_document(object->desk)->root->mflags = TRUE; + sp_desktop_document(object->desk)->_updateDocument(); + sp_desktop_document(object->desk)->root->uflags = FALSE; + sp_desktop_document(object->desk)->root->mflags = FALSE; + //sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions"); +} + +/**************************************************************************** + SELECTION FUNCTIONS FIXME: use call_verb where appropriate. +****************************************************************************/ + +gchar ** +document_interface_selection_get (DocumentInterface *object) +{ + Inkscape::Selection * sel = sp_desktop_selection(object->desk); + GSList const *oldsel = sel->list(); + + int size = g_slist_length((GSList *) oldsel); + int i; + printf("premalloc\n"); + gchar **list = (gchar **)malloc(size); + printf("postmalloc\n"); + for(i = 0; i < size; i++) + list[i] = (gchar *)malloc(sizeof(gchar) * 10); + printf("postmalloc2\n"); + i=0; + printf("prealloc\n"); + for (GSList const *iter = oldsel; iter != NULL; iter = iter->next) { + strcpy (list[i], SP_OBJECT(iter->data)->repr->attribute("id")); + i++; + } + printf("postalloc\n"); + for (i=0; idesk); + Inkscape::Selection *selection = sp_desktop_selection(object->desk); + /* WORKS + Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name); + selection->add(repr2, TRUE); + */ + selection->add(doc->getObjectById(name)); + return TRUE; +} + +gboolean +document_interface_selection_add_list (DocumentInterface *object, + char **names, GError **error) +{ + return FALSE; +} + +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); + selection->set(doc->getObjectById(name)); + return TRUE; +} + +gboolean +document_interface_selection_set_list (DocumentInterface *object, + gchar **names, GError **error) +{ + sp_desktop_selection(object->desk)->clear(); + int i; + for (i=0;((i<30000) && (names[i] != NULL));i++) { + printf("NAME: %s\n", names[i]); + document_interface_selection_add(object, names[i], error); + } + return TRUE; +} + +gboolean +document_interface_selection_rotate (DocumentInterface *object, int angle, GError **error) +{ + Inkscape::Selection *selection = sp_desktop_selection(object->desk); + sp_selection_rotate(selection, angle); + return TRUE; +} + +gboolean +document_interface_selection_delete (DocumentInterface *object, GError **error) +{ + sp_selection_delete (object->desk); + return TRUE; +} + +gboolean +document_interface_selection_clear (DocumentInterface *object, GError **error) +{ + sp_desktop_selection(object->desk)->clear(); + return TRUE; +} + +gboolean +document_interface_select_all (DocumentInterface *object, GError **error) +{ + sp_edit_select_all (object->desk); + return TRUE; +} + +gboolean +document_interface_select_all_in_all_layers(DocumentInterface *object, + GError **error) +{ + sp_edit_select_all_in_all_layers (object->desk); +} + +gboolean +document_interface_selection_box (DocumentInterface *object, int x, int y, + int x2, int y2, gboolean replace, + GError **error) +{ + return FALSE; +} + +gboolean +document_interface_selection_invert (DocumentInterface *object, GError **error) +{ + sp_edit_invert (object->desk); + return TRUE; +} + +gboolean +document_interface_selection_group (DocumentInterface *object, GError **error) +{ + sp_selection_group (object->desk); + return TRUE; +} +gboolean +document_interface_selection_ungroup (DocumentInterface *object, GError **error) +{ + sp_selection_ungroup (object->desk); + return TRUE; +} + +gboolean +document_interface_selection_cut (DocumentInterface *object, GError **error) +{ + sp_selection_cut (object->desk); + return TRUE; +} +gboolean +document_interface_selection_copy (DocumentInterface *object, GError **error) +{ + desktop_ensure_active (object->desk); + sp_selection_copy (); + return TRUE; +} +gboolean +document_interface_selection_paste (DocumentInterface *object, GError **error) +{ + desktop_ensure_active (object->desk); + sp_selection_paste (object->desk, TRUE); + return TRUE; +} + +gboolean +document_interface_selection_scale (DocumentInterface *object, gdouble grow, GError **error) +{ + Inkscape::Selection *selection = sp_desktop_selection(object->desk); + sp_selection_scale (selection, grow); + return TRUE; +} + +gboolean +document_interface_selection_move (DocumentInterface *object, gdouble x, gdouble y, GError **error) +{ + sp_selection_move (object->desk, 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); + + Geom::OptRect sel_bbox = sel->bounds(); + if (sel_bbox) { + //Geom::Point m( (object->desk)->point() - sel_bbox->midpoint() ); + Geom::Point m( x - selection_get_center_x(sel) , 0 - (y - selection_get_center_y(sel)) ); + sp_selection_move_relative(sel, m, true); + + } + + //FIXME: dosn't work with transformations + //sp_selection_move (object->desk, x - selection_get_center_x(sel), + // 0 - (y - selection_get_center_y(sel))); + return TRUE; +} + +gboolean +document_interface_selection_move_to_layer (DocumentInterface *object, + gchar *layerstr, GError **error) +{ + return FALSE; +} + +gboolean +document_interface_selection_get_center (DocumentInterface *object) +{ + return FALSE; +} + +gboolean +document_interface_selection_to_path (DocumentInterface *object, GError **error) +{ + return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error); +} + + +gchar * +document_interface_selection_combine (DocumentInterface *object, gchar *cmd, + GError **error) +{ + + if (strcmp(cmd, "union") == 0) + dbus_call_verb (object, SP_VERB_SELECTION_UNION, error); + else if (strcmp(cmd, "intersection") == 0) + dbus_call_verb (object, SP_VERB_SELECTION_INTERSECT, error); + else if (strcmp(cmd, "difference") == 0) + 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 if (strcmp(cmd, "division") == 0) + dbus_call_verb (object, SP_VERB_SELECTION_CUT, error); + else + return NULL; + + //FIXME: this WILL cause problems with division + return g_strdup((sp_desktop_selection(object->desk)->singleRepr())->attribute("id")); +} + +gboolean +document_interface_selection_change_level (DocumentInterface *object, gchar *cmd, + GError **error) +{ + if (strcmp(cmd, "raise") == 0) + return dbus_call_verb (object, SP_VERB_SELECTION_RAISE, error); + if (strcmp(cmd, "lower") == 0) + return dbus_call_verb (object, 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); + if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0)) + return dbus_call_verb (object, SP_VERB_SELECTION_TO_BACK, error); + return TRUE; +} + +/**************************************************************************** + LAYER FUNCTIONS +****************************************************************************/ + +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); + return g_strdup(get_name_from_object (new_layer)); +} + +gboolean +document_interface_layer_set (DocumentInterface *object, + gchar *layerstr, GError **error) +{ + object->desk->setCurrentLayer (get_object_by_name (object->desk, layerstr)); + return TRUE; +} + +gchar ** +document_interface_layer_get_all (DocumentInterface *object) +{ + return NULL; +} + +gboolean +document_interface_layer_change_level (DocumentInterface *object, + gchar *cmd, GError **error) +{ + if (strcmp(cmd, "raise") == 0) + return dbus_call_verb (object, SP_VERB_LAYER_RAISE, error); + if (strcmp(cmd, "lower") == 0) + return dbus_call_verb (object, 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); + if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0)) + return dbus_call_verb (object, SP_VERB_LAYER_TO_BOTTOM, error); + return TRUE; +} + +gboolean +document_interface_layer_next (DocumentInterface *object, GError **error) +{ + return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error); +} + +gboolean +document_interface_layer_previous (DocumentInterface *object, GError **error) +{ + return dbus_call_verb (object, SP_VERB_LAYER_PREV, error); +} + + + + + + -- cgit v1.2.3