1 #include "document-interface.h"
2 #include <string.h>
4 #include "verbs.h"
5 #include "helper/action.h" //sp_action_perform
7 #include "inkscape.h" //inkscape_find_desktop_by_dkey, activate desktops
9 #include "desktop-handles.h" //sp_desktop_document()
10 #include "xml/repr.h" //sp_repr_document_new
12 #include "sp-object.h"
14 #include "document.h" // sp_document_repr_doc
16 #include "desktop-style.h" //sp_desktop_get_style
18 #include "selection.h" //selection struct
19 #include "selection-chemistry.h"// lots of selection functions
21 #include "sp-ellipse.h"
23 #include "layer-fns.h" //LPOS_BELOW
25 #include "style.h" //style_write
27 /****************************************************************************
28 HELPER / SHORTCUT FUNCTIONS
29 ****************************************************************************/
31 const gchar* intToCString(int i)
32 {
33 std::stringstream ss;
34 ss << i;
35 return ss.str().c_str();
36 }
38 SPObject *
39 get_object_by_name (SPDesktop *desk, gchar *name)
40 {
41 return sp_desktop_document(desk)->getObjectById(name);
42 }
44 const gchar *
45 get_name_from_object (SPObject * obj)
46 {
47 return obj->repr->attribute("id");
48 }
50 void
51 desktop_ensure_active (SPDesktop* desk) {
52 if (desk != SP_ACTIVE_DESKTOP)
53 inkscape_activate_desktop (desk);
54 return;
55 }
57 Inkscape::XML::Node *
58 document_retrive_node (SPDocument *doc, gchar *name) {
59 return (doc->getObjectById(name))->repr;
60 }
62 gdouble
63 selection_get_center_x (Inkscape::Selection *sel){
64 NRRect *box = g_new(NRRect, 1);;
65 box = sel->boundsInDocument(box);
66 return box->x0 + ((box->x1 - box->x0)/2);
67 }
69 gdouble
70 selection_get_center_y (Inkscape::Selection *sel){
71 NRRect *box = g_new(NRRect, 1);;
72 box = sel->boundsInDocument(box);
73 return box->y0 + ((box->y1 - box->y0)/2);
74 }
75 //move_to etc
76 const GSList *
77 selection_swap(SPDesktop *desk, gchar *name)
78 {
79 Inkscape::Selection *sel = sp_desktop_selection(desk);
80 const GSList *oldsel = g_slist_copy((GSList *)sel->list());
82 sel->set(get_object_by_name(desk, name));
83 return oldsel;
84 }
86 void
87 selection_restore(SPDesktop *desk, const GSList * oldsel)
88 {
89 Inkscape::Selection *sel = sp_desktop_selection(desk);
90 sel->setList(oldsel);
91 }
93 Inkscape::XML::Node *
94 dbus_create_node (SPDesktop *desk, gboolean isrect)
95 {
96 SPDocument * doc = sp_desktop_document (desk);
97 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
98 gchar *type;
99 if (isrect)
100 type = (gchar *)"svg:rect";
101 else
102 type = (gchar *)"svg:path";
103 return xml_doc->createElement(type);
104 }
106 gchar *
107 finish_create_shape (DocumentInterface *object, GError **error, Inkscape::XML::Node *newNode, gchar *desc)
108 {
110 SPCSSAttr *style = sp_desktop_get_style(object->desk, TRUE);
112 if (style) {
113 newNode->setAttribute("style", sp_repr_css_write_string(style), TRUE);
114 }
115 else {
116 newNode->setAttribute("style", "fill:#0000ff;fill-opacity:1;stroke:#c900b9;stroke-width:0;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none", TRUE);
117 }
119 object->desk->currentLayer()->appendChildRepr(newNode);
120 object->desk->currentLayer()->updateRepr();
122 if (object->updates)
123 sp_document_done(sp_desktop_document(object->desk), 0, (gchar *)desc);
124 else
125 document_interface_pause_updates(object, error);
127 return strdup(newNode->attribute("id"));
128 }
130 gboolean
131 dbus_call_verb (DocumentInterface *object, int verbid, GError **error)
132 {
133 SPDesktop *desk2 = object->desk;
135 if ( desk2 ) {
136 Inkscape::Verb *verb = Inkscape::Verb::get( verbid );
137 if ( verb ) {
138 SPAction *action = verb->get_action(desk2);
139 if ( action ) {
140 sp_action_perform( action, NULL );
141 if (object->updates) {
142 sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip()));
143 }
144 return TRUE;
145 }
146 }
147 }
148 return FALSE;
149 }
151 /****************************************************************************
152 DOCUMENT INTERFACE CLASS STUFF
153 ****************************************************************************/
155 G_DEFINE_TYPE(DocumentInterface, document_interface, G_TYPE_OBJECT)
157 static void
158 document_interface_finalize (GObject *object)
159 {
160 G_OBJECT_CLASS (document_interface_parent_class)->finalize (object);
161 }
164 static void
165 document_interface_class_init (DocumentInterfaceClass *klass)
166 {
167 GObjectClass *object_class;
168 object_class = G_OBJECT_CLASS (klass);
169 object_class->finalize = document_interface_finalize;
170 }
172 static void
173 document_interface_init (DocumentInterface *object)
174 {
175 object->desk = NULL;
176 }
179 DocumentInterface *
180 document_interface_new (void)
181 {
182 return (DocumentInterface*)g_object_new (TYPE_DOCUMENT_INTERFACE, NULL);
183 }
185 /****************************************************************************
186 MISC FUNCTIONS
187 ****************************************************************************/
189 gboolean
190 document_interface_delete_all (DocumentInterface *object, GError **error)
191 {
192 sp_edit_clear_all (object->desk);
193 return TRUE;
194 }
196 void
197 document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error)
198 {
199 SPDesktop *desk2 = object->desk;
200 desktop_ensure_active (object->desk);
201 if ( desk2 ) {
202 Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid );
203 if ( verb ) {
204 SPAction *action = verb->get_action(desk2);
205 if ( action ) {
206 sp_action_perform( action, NULL );
207 if (object->updates) {
208 sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip()));
209 }
210 }
211 }
212 }
213 }
216 /****************************************************************************
217 CREATION FUNCTIONS
218 ****************************************************************************/
220 gchar*
221 document_interface_rectangle (DocumentInterface *object, int x, int y,
222 int width, int height, GError **error)
223 {
226 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, TRUE);
227 sp_repr_set_int(newNode, "x", x); //could also use newNode->setAttribute()
228 sp_repr_set_int(newNode, "y", y);
229 sp_repr_set_int(newNode, "width", width);
230 sp_repr_set_int(newNode, "height", height);
231 return finish_create_shape (object, error, newNode, (gchar *)"create rectangle");
232 }
234 gchar*
235 document_interface_ellipse_center (DocumentInterface *object, int cx, int cy,
236 int rx, int ry, GError **error)
237 {
238 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
239 newNode->setAttribute("sodipodi:type", "arc");
240 sp_repr_set_int(newNode, "sodipodi:cx", cx);
241 sp_repr_set_int(newNode, "sodipodi:cy", cy);
242 sp_repr_set_int(newNode, "sodipodi:rx", rx);
243 sp_repr_set_int(newNode, "sodipodi:ry", ry);
244 return finish_create_shape (object, error, newNode, (gchar *)"create circle");
245 }
247 gchar*
248 document_interface_polygon (DocumentInterface *object, int cx, int cy,
249 int radius, int rotation, int sides,
250 GError **error)
251 {
252 gdouble rot = ((rotation / 180.0) * 3.14159265) - ( 3.14159265 / 2.0);
253 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
254 newNode->setAttribute("inkscape:flatsided", "true");
255 newNode->setAttribute("sodipodi:type", "star");
256 sp_repr_set_int(newNode, "sodipodi:cx", cx);
257 sp_repr_set_int(newNode, "sodipodi:cy", cy);
258 sp_repr_set_int(newNode, "sodipodi:r1", radius);
259 sp_repr_set_int(newNode, "sodipodi:r2", radius);
260 sp_repr_set_int(newNode, "sodipodi:sides", sides);
261 sp_repr_set_int(newNode, "inkscape:randomized", 0);
262 sp_repr_set_svg_double(newNode, "sodipodi:arg1", rot);
263 sp_repr_set_svg_double(newNode, "sodipodi:arg2", rot);
264 sp_repr_set_svg_double(newNode, "inkscape:rounded", 0);
266 return finish_create_shape (object, error, newNode, (gchar *)"create polygon");
267 }
269 gchar*
270 document_interface_star (DocumentInterface *object, int cx, int cy,
271 int r1, int r2, int sides, gdouble rounded,
272 gdouble arg1, gdouble arg2, GError **error)
273 {
274 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
275 newNode->setAttribute("inkscape:flatsided", "false");
276 newNode->setAttribute("sodipodi:type", "star");
277 sp_repr_set_int(newNode, "sodipodi:cx", cx);
278 sp_repr_set_int(newNode, "sodipodi:cy", cy);
279 sp_repr_set_int(newNode, "sodipodi:r1", r1);
280 sp_repr_set_int(newNode, "sodipodi:r2", r2);
281 sp_repr_set_int(newNode, "sodipodi:sides", sides);
282 sp_repr_set_int(newNode, "inkscape:randomized", 0);
283 sp_repr_set_svg_double(newNode, "sodipodi:arg1", arg1);
284 sp_repr_set_svg_double(newNode, "sodipodi:arg2", arg2);
285 sp_repr_set_svg_double(newNode, "inkscape:rounded", rounded);
287 return finish_create_shape (object, error, newNode, (gchar *)"create star");
288 }
290 gchar*
291 document_interface_ellipse (DocumentInterface *object, int x, int y,
292 int width, int height, GError **error)
293 {
294 int rx = width/2;
295 int ry = height/2;
296 return document_interface_ellipse_center (object, x+rx, y+ry, rx, ry, error);
297 }
299 gchar*
300 document_interface_line (DocumentInterface *object, int x, int y,
301 int x2, int y2, GError **error)
302 {
303 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
304 std::stringstream out;
305 printf("X2: %d\nY2 %d\n", x2, y2);
306 out << "m " << x << "," << y << " " << x2 << "," << y2;
307 printf ("PATH: %s\n", out.str().c_str());
308 newNode->setAttribute("d", out.str().c_str());
309 return finish_create_shape (object, error, newNode, (gchar *)"create line");
310 }
312 gchar*
313 document_interface_spiral (DocumentInterface *object, int cx, int cy,
314 int r, int revolutions, GError **error)
315 {
316 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
317 newNode->setAttribute("sodipodi:type", "spiral");
318 sp_repr_set_int(newNode, "sodipodi:cx", cx);
319 sp_repr_set_int(newNode, "sodipodi:cy", cy);
320 sp_repr_set_int(newNode, "sodipodi:radius", r);
321 sp_repr_set_int(newNode, "sodipodi:revolution", revolutions);
322 sp_repr_set_int(newNode, "sodipodi:t0", 0);
323 sp_repr_set_int(newNode, "sodipodi:argument", 0);
324 sp_repr_set_int(newNode, "sodipodi:expansion", 1);
325 gchar * retval = finish_create_shape (object, error, newNode, (gchar *)"create spiral");
326 newNode->setAttribute("style", "fill:none");
327 return retval;
328 }
330 gchar*
331 document_interface_text (DocumentInterface *object, gchar *text, GError **error)
332 {
333 return NULL;
334 }
336 gchar*
337 document_interface_node (DocumentInterface *object, gchar *type, GError **error)
338 {
339 return NULL;
340 }
342 /****************************************************************************
343 ENVIORNMENT FUNCTIONS
344 ****************************************************************************/
345 gdouble
346 document_interface_document_get_width (DocumentInterface *object)
347 {
348 return sp_document_width(sp_desktop_document(object->desk));
349 }
351 gdouble
352 document_interface_document_get_height (DocumentInterface *object)
353 {
354 return sp_document_height(sp_desktop_document(object->desk));
355 }
357 gchar *
358 document_interface_document_get_css (DocumentInterface *object, GError **error)
359 {
360 SPCSSAttr *current = (object->desk)->current;
361 return sp_repr_css_write_string(current);
362 }
364 gboolean
365 document_interface_document_merge_css (DocumentInterface *object,
366 gchar *stylestring, GError **error)
367 {
368 return FALSE;
369 }
371 gboolean
372 document_interface_document_set_css (DocumentInterface *object,
373 gchar *stylestring, GError **error)
374 {
375 return FALSE;
376 }
378 gboolean
379 document_interface_document_resize_to_fit_selection (DocumentInterface *object,
380 GError **error)
381 {
382 return FALSE;
383 }
385 /****************************************************************************
386 OBJECT FUNCTIONS
387 ****************************************************************************/
389 gboolean
390 document_interface_set_attribute (DocumentInterface *object, char *shape,
391 char *attribute, char *newval, GError **error)
392 {
393 Inkscape::XML::Node *newNode = get_object_by_name(object->desk, shape)->repr;
395 /* ALTERNATIVE
396 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
397 */
398 if (newNode)
399 {
400 newNode->setAttribute(attribute, newval, TRUE);
401 return TRUE;
402 }
403 return FALSE;
404 }
406 void
407 document_interface_set_int_attribute (DocumentInterface *object,
408 char *shape, char *attribute,
409 int newval, GError **error)
410 {
411 Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr;
412 if (newNode)
413 sp_repr_set_int (newNode, attribute, newval);
414 }
417 void
418 document_interface_set_double_attribute (DocumentInterface *object,
419 char *shape, char *attribute,
420 double newval, GError **error)
421 {
422 Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr;
423 if (newNode)
424 sp_repr_set_svg_double (newNode, attribute, newval);
425 }
427 gchar *
428 document_interface_get_attribute (DocumentInterface *object, char *shape,
429 char *attribute, GError **error)
430 {
431 SPDesktop *desk2 = object->desk;
432 SPDocument * doc = sp_desktop_document (desk2);
434 // FIXME: Not sure if this is the most efficient way.
435 Inkscape::XML::Node *newNode = doc->getObjectById(shape)->repr;
437 /* WORKS
438 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
439 */
440 if (newNode)
441 return g_strdup(newNode->attribute(attribute));
442 return FALSE;
443 }
445 gboolean
446 document_interface_move (DocumentInterface *object, gchar *name, gdouble x,
447 gdouble y, GError **error)
448 {
449 const GSList *oldsel = selection_swap(object->desk, name);
450 sp_selection_move (object->desk, x, 0 - y);
451 selection_restore(object->desk, oldsel);
452 return TRUE;
453 }
455 gboolean
456 document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x,
457 gdouble y, GError **error)
458 {
459 const GSList *oldsel = selection_swap(object->desk, name);
460 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
461 sp_selection_move (object->desk, x - selection_get_center_x(sel),
462 0 - (y - selection_get_center_y(sel)));
463 selection_restore(object->desk, oldsel);
464 return TRUE;
465 }
467 void
468 document_interface_object_to_path (DocumentInterface *object,
469 char *shape, GError **error)
470 {
471 const GSList *oldsel = selection_swap(object->desk, shape);
472 dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
473 selection_restore(object->desk, oldsel);
474 }
476 gboolean
477 document_interface_get_path (DocumentInterface *object, char *pathname, GError **error)
478 {
479 Inkscape::XML::Node *node = document_retrive_node (sp_desktop_document (object->desk), pathname);
480 if (node == NULL || node->attribute("d") == NULL) {
481 g_set_error(error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION, "Object is not a path or does not exist.");
482 return FALSE;
483 }
484 gchar *pathstr = strdup(node->attribute("d"));
485 printf("PATH: %s\n", pathstr);
486 //gfree (pathstr);
487 std::istringstream iss(pathstr);
488 std::copy(std::istream_iterator<std::string>(iss),
489 std::istream_iterator<std::string>(),
490 std::ostream_iterator<std::string>(std::cout, "\n"));
492 return TRUE;
493 }
495 gboolean
496 document_interface_transform (DocumentInterface *object, gchar *shape,
497 gchar *transformstr, GError **error)
498 {
499 //FIXME: This should merge transformations.
500 gchar trans[] = "transform";
501 document_interface_set_attribute (object, shape, trans, transformstr, error);
502 return TRUE;
503 }
505 gchar *
506 document_interface_get_css (DocumentInterface *object, gchar *shape,
507 GError **error)
508 {
509 return NULL;
510 }
512 gboolean
513 document_interface_modify_css (DocumentInterface *object, gchar *shape,
514 gchar *cssattrb, gchar *newval, GError **error)
515 {
516 return FALSE;
517 }
519 gboolean
520 document_interface_merge_css (DocumentInterface *object, gchar *shape,
521 gchar *stylestring, GError **error)
522 {
523 return FALSE;
524 }
526 gboolean
527 document_interface_move_to_layer (DocumentInterface *object, gchar *shape,
528 gchar *layerstr, GError **error)
529 {
530 return FALSE;
531 }
533 DBUSPoint **
534 document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape)
535 {
536 return NULL;
537 }
540 /****************************************************************************
541 FILE I/O FUNCTIONS
542 ****************************************************************************/
544 gboolean
545 document_interface_save (DocumentInterface *object, GError **error){
546 return FALSE;
547 }
549 gboolean
550 document_interface_load (DocumentInterface *object,
551 gchar *filename, GError **error){
552 return FALSE;
553 }
555 gboolean
556 document_interface_save_as (DocumentInterface *object,
557 gchar *filename, GError **error){
558 return FALSE;
559 }
561 gboolean
562 document_interface_print (DocumentInterface *object, GError **error){
563 return FALSE;
564 }
566 /****************************************************************************
567 PROGRAM CONTROL FUNCTIONS
568 ****************************************************************************/
570 gboolean
571 document_interface_close (DocumentInterface *object, GError **error){
572 return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error);
573 }
575 gboolean
576 document_interface_exit (DocumentInterface *object, GError **error){
577 return dbus_call_verb (object, SP_VERB_FILE_QUIT, error);
578 }
580 gboolean
581 document_interface_undo (DocumentInterface *object, GError **error){
582 return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error);
583 }
585 gboolean
586 document_interface_redo (DocumentInterface *object, GError **error){
587 return dbus_call_verb (object, SP_VERB_EDIT_REDO, error);
588 }
592 /****************************************************************************
593 UPDATE FUNCTIONS
594 ****************************************************************************/
596 void
597 document_interface_pause_updates (DocumentInterface *object, GError **error)
598 {
599 object->updates = FALSE;
600 sp_desktop_document(object->desk)->root->uflags = FALSE;
601 sp_desktop_document(object->desk)->root->mflags = FALSE;
602 }
604 void
605 document_interface_resume_updates (DocumentInterface *object, GError **error)
606 {
607 object->updates = TRUE;
608 sp_desktop_document(object->desk)->root->uflags = TRUE;
609 sp_desktop_document(object->desk)->root->mflags = TRUE;
610 //sp_desktop_document(object->desk)->_updateDocument();
611 sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
612 }
614 void
615 document_interface_update (DocumentInterface *object, GError **error)
616 {
617 sp_desktop_document(object->desk)->root->uflags = TRUE;
618 sp_desktop_document(object->desk)->root->mflags = TRUE;
619 sp_desktop_document(object->desk)->_updateDocument();
620 sp_desktop_document(object->desk)->root->uflags = FALSE;
621 sp_desktop_document(object->desk)->root->mflags = FALSE;
622 //sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
623 }
625 /****************************************************************************
626 SELECTION FUNCTIONS FIXME: use call_verb where appropriate.
627 ****************************************************************************/
629 gchar **
630 document_interface_selection_get (DocumentInterface *object)
631 {
632 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
633 GSList const *oldsel = sel->list();
635 int size = g_slist_length((GSList *) oldsel);
636 int i;
637 printf("premalloc\n");
638 gchar **list = (gchar **)malloc(size);
639 printf("postmalloc\n");
640 for(i = 0; i < size; i++)
641 list[i] = (gchar *)malloc(sizeof(gchar) * 10);
642 printf("postmalloc2\n");
643 i=0;
644 printf("prealloc\n");
645 for (GSList const *iter = oldsel; iter != NULL; iter = iter->next) {
646 strcpy (list[i], SP_OBJECT(iter->data)->repr->attribute("id"));
647 i++;
648 }
649 printf("postalloc\n");
650 for (i=0; i<size; i++) {
651 printf("%d = %s\n", i, list[i]);
652 }
654 return list;
655 }
657 gboolean
658 document_interface_selection_add (DocumentInterface *object, char *name, GError **error)
659 {
660 if (name == NULL)
661 return FALSE;
662 //FIXME: This gets called a lot. Efficient?
663 SPDocument * doc = sp_desktop_document (object->desk);
664 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
665 /* WORKS
666 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
667 selection->add(repr2, TRUE);
668 */
669 selection->add(doc->getObjectById(name));
670 return TRUE;
671 }
673 gboolean
674 document_interface_selection_add_list (DocumentInterface *object,
675 char **names, GError **error)
676 {
677 return FALSE;
678 }
680 gboolean
681 document_interface_selection_set (DocumentInterface *object, char *name, GError **error)
682 {
683 SPDocument * doc = sp_desktop_document (object->desk);
684 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
685 selection->set(doc->getObjectById(name));
686 return TRUE;
687 }
689 gboolean
690 document_interface_selection_set_list (DocumentInterface *object,
691 gchar **names, GError **error)
692 {
693 sp_desktop_selection(object->desk)->clear();
694 int i;
695 for (i=0;((i<30000) && (names[i] != NULL));i++) {
696 printf("NAME: %s\n", names[i]);
697 document_interface_selection_add(object, names[i], error);
698 }
699 return TRUE;
700 }
702 gboolean
703 document_interface_selection_rotate (DocumentInterface *object, int angle, GError **error)
704 {
705 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
706 sp_selection_rotate(selection, angle);
707 return TRUE;
708 }
710 gboolean
711 document_interface_selection_delete (DocumentInterface *object, GError **error)
712 {
713 sp_selection_delete (object->desk);
714 return TRUE;
715 }
717 gboolean
718 document_interface_selection_clear (DocumentInterface *object, GError **error)
719 {
720 sp_desktop_selection(object->desk)->clear();
721 return TRUE;
722 }
724 gboolean
725 document_interface_select_all (DocumentInterface *object, GError **error)
726 {
727 sp_edit_select_all (object->desk);
728 return TRUE;
729 }
731 gboolean
732 document_interface_select_all_in_all_layers(DocumentInterface *object,
733 GError **error)
734 {
735 sp_edit_select_all_in_all_layers (object->desk);
736 }
738 gboolean
739 document_interface_selection_box (DocumentInterface *object, int x, int y,
740 int x2, int y2, gboolean replace,
741 GError **error)
742 {
743 return FALSE;
744 }
746 gboolean
747 document_interface_selection_invert (DocumentInterface *object, GError **error)
748 {
749 sp_edit_invert (object->desk);
750 return TRUE;
751 }
753 gboolean
754 document_interface_selection_group (DocumentInterface *object, GError **error)
755 {
756 sp_selection_group (object->desk);
757 return TRUE;
758 }
759 gboolean
760 document_interface_selection_ungroup (DocumentInterface *object, GError **error)
761 {
762 sp_selection_ungroup (object->desk);
763 return TRUE;
764 }
766 gboolean
767 document_interface_selection_cut (DocumentInterface *object, GError **error)
768 {
769 sp_selection_cut (object->desk);
770 return TRUE;
771 }
772 gboolean
773 document_interface_selection_copy (DocumentInterface *object, GError **error)
774 {
775 desktop_ensure_active (object->desk);
776 sp_selection_copy ();
777 return TRUE;
778 }
779 gboolean
780 document_interface_selection_paste (DocumentInterface *object, GError **error)
781 {
782 desktop_ensure_active (object->desk);
783 sp_selection_paste (object->desk, TRUE);
784 return TRUE;
785 }
787 gboolean
788 document_interface_selection_scale (DocumentInterface *object, gdouble grow, GError **error)
789 {
790 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
791 sp_selection_scale (selection, grow);
792 return TRUE;
793 }
795 gboolean
796 document_interface_selection_move (DocumentInterface *object, gdouble x, gdouble y, GError **error)
797 {
798 sp_selection_move (object->desk, x, 0 - y); //switching coordinate systems.
799 return TRUE;
800 }
802 gboolean
803 document_interface_selection_move_to (DocumentInterface *object, gdouble x, gdouble y, GError **error)
804 {
805 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
807 Geom::OptRect sel_bbox = sel->bounds();
808 if (sel_bbox) {
809 //Geom::Point m( (object->desk)->point() - sel_bbox->midpoint() );
810 Geom::Point m( x - selection_get_center_x(sel) , 0 - (y - selection_get_center_y(sel)) );
811 sp_selection_move_relative(sel, m, true);
813 }
815 //FIXME: dosn't work with transformations
816 //sp_selection_move (object->desk, x - selection_get_center_x(sel),
817 // 0 - (y - selection_get_center_y(sel)));
818 return TRUE;
819 }
821 gboolean
822 document_interface_selection_move_to_layer (DocumentInterface *object,
823 gchar *layerstr, GError **error)
824 {
825 return FALSE;
826 }
828 gboolean
829 document_interface_selection_get_center (DocumentInterface *object)
830 {
831 return FALSE;
832 }
834 gboolean
835 document_interface_selection_to_path (DocumentInterface *object, GError **error)
836 {
837 return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
838 }
841 gchar *
842 document_interface_selection_combine (DocumentInterface *object, gchar *cmd,
843 GError **error)
844 {
846 if (strcmp(cmd, "union") == 0)
847 dbus_call_verb (object, SP_VERB_SELECTION_UNION, error);
848 else if (strcmp(cmd, "intersection") == 0)
849 dbus_call_verb (object, SP_VERB_SELECTION_INTERSECT, error);
850 else if (strcmp(cmd, "difference") == 0)
851 dbus_call_verb (object, SP_VERB_SELECTION_DIFF, error);
852 else if (strcmp(cmd, "exclusion") == 0)
853 dbus_call_verb (object, SP_VERB_SELECTION_SYMDIFF, error);
854 else if (strcmp(cmd, "division") == 0)
855 dbus_call_verb (object, SP_VERB_SELECTION_CUT, error);
856 else
857 return NULL;
859 //FIXME: this WILL cause problems with division
860 return g_strdup((sp_desktop_selection(object->desk)->singleRepr())->attribute("id"));
861 }
863 gboolean
864 document_interface_selection_change_level (DocumentInterface *object, gchar *cmd,
865 GError **error)
866 {
867 if (strcmp(cmd, "raise") == 0)
868 return dbus_call_verb (object, SP_VERB_SELECTION_RAISE, error);
869 if (strcmp(cmd, "lower") == 0)
870 return dbus_call_verb (object, SP_VERB_SELECTION_LOWER, error);
871 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
872 return dbus_call_verb (object, SP_VERB_SELECTION_TO_FRONT, error);
873 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
874 return dbus_call_verb (object, SP_VERB_SELECTION_TO_BACK, error);
875 return TRUE;
876 }
878 /****************************************************************************
879 LAYER FUNCTIONS
880 ****************************************************************************/
882 gchar *
883 document_interface_layer_new (DocumentInterface *object, GError **error)
884 {
885 SPDesktop * dt = object->desk;
886 SPObject *new_layer = Inkscape::create_layer(dt->currentRoot(), dt->currentLayer(), Inkscape::LPOS_BELOW);
887 dt->setCurrentLayer(new_layer);
888 return g_strdup(get_name_from_object (new_layer));
889 }
891 gboolean
892 document_interface_layer_set (DocumentInterface *object,
893 gchar *layerstr, GError **error)
894 {
895 object->desk->setCurrentLayer (get_object_by_name (object->desk, layerstr));
896 return TRUE;
897 }
899 gchar **
900 document_interface_layer_get_all (DocumentInterface *object)
901 {
902 return NULL;
903 }
905 gboolean
906 document_interface_layer_change_level (DocumentInterface *object,
907 gchar *cmd, GError **error)
908 {
909 if (strcmp(cmd, "raise") == 0)
910 return dbus_call_verb (object, SP_VERB_LAYER_RAISE, error);
911 if (strcmp(cmd, "lower") == 0)
912 return dbus_call_verb (object, SP_VERB_LAYER_LOWER, error);
913 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
914 return dbus_call_verb (object, SP_VERB_LAYER_TO_TOP, error);
915 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
916 return dbus_call_verb (object, SP_VERB_LAYER_TO_BOTTOM, error);
917 return TRUE;
918 }
920 gboolean
921 document_interface_layer_next (DocumentInterface *object, GError **error)
922 {
923 return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error);
924 }
926 gboolean
927 document_interface_layer_previous (DocumentInterface *object, GError **error)
928 {
929 return dbus_call_verb (object, SP_VERB_LAYER_PREV, error);
930 }