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 #include "file.h" //IO
29 #include "extension/system.h" //IO
31 #include "extension/output.h" //IO
33 #include "print.h" //IO
35 /****************************************************************************
36 HELPER / SHORTCUT FUNCTIONS
37 ****************************************************************************/
39 const gchar* intToCString(int i)
40 {
41 std::stringstream ss;
42 ss << i;
43 return ss.str().c_str();
44 }
46 SPObject *
47 get_object_by_name (SPDesktop *desk, gchar *name)
48 {
49 return sp_desktop_document(desk)->getObjectById(name);
50 }
52 const gchar *
53 get_name_from_object (SPObject * obj)
54 {
55 return obj->repr->attribute("id");
56 }
58 void
59 desktop_ensure_active (SPDesktop* desk) {
60 if (desk != SP_ACTIVE_DESKTOP)
61 inkscape_activate_desktop (desk);
62 return;
63 }
65 Inkscape::XML::Node *
66 document_retrive_node (SPDocument *doc, gchar *name) {
67 return (doc->getObjectById(name))->repr;
68 }
70 gdouble
71 selection_get_center_x (Inkscape::Selection *sel){
72 NRRect *box = g_new(NRRect, 1);;
73 box = sel->boundsInDocument(box);
74 return box->x0 + ((box->x1 - box->x0)/2);
75 }
77 gdouble
78 selection_get_center_y (Inkscape::Selection *sel){
79 NRRect *box = g_new(NRRect, 1);;
80 box = sel->boundsInDocument(box);
81 return box->y0 + ((box->y1 - box->y0)/2);
82 }
83 //move_to etc
84 const GSList *
85 selection_swap(SPDesktop *desk, gchar *name)
86 {
87 Inkscape::Selection *sel = sp_desktop_selection(desk);
88 const GSList *oldsel = g_slist_copy((GSList *)sel->list());
90 sel->set(get_object_by_name(desk, name));
91 return oldsel;
92 }
94 void
95 selection_restore(SPDesktop *desk, const GSList * oldsel)
96 {
97 Inkscape::Selection *sel = sp_desktop_selection(desk);
98 sel->setList(oldsel);
99 }
101 Inkscape::XML::Node *
102 dbus_create_node (SPDesktop *desk, gboolean isrect)
103 {
104 SPDocument * doc = sp_desktop_document (desk);
105 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
106 gchar *type;
107 if (isrect)
108 type = (gchar *)"svg:rect";
109 else
110 type = (gchar *)"svg:path";
111 return xml_doc->createElement(type);
112 }
114 gchar *
115 finish_create_shape (DocumentInterface *object, GError **error, Inkscape::XML::Node *newNode, gchar *desc)
116 {
118 SPCSSAttr *style = sp_desktop_get_style(object->desk, TRUE);
120 if (style) {
121 newNode->setAttribute("style", sp_repr_css_write_string(style), TRUE);
122 }
123 else {
124 newNode->setAttribute("style", "fill:#0000ff;fill-opacity:1;stroke:#c900b9;stroke-width:0;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none", TRUE);
125 }
127 object->desk->currentLayer()->appendChildRepr(newNode);
128 object->desk->currentLayer()->updateRepr();
130 if (object->updates)
131 sp_document_done(sp_desktop_document(object->desk), 0, (gchar *)desc);
132 else
133 document_interface_pause_updates(object, error);
135 return strdup(newNode->attribute("id"));
136 }
138 gboolean
139 dbus_call_verb (DocumentInterface *object, int verbid, GError **error)
140 {
141 SPDesktop *desk2 = object->desk;
143 if ( desk2 ) {
144 Inkscape::Verb *verb = Inkscape::Verb::get( verbid );
145 if ( verb ) {
146 SPAction *action = verb->get_action(desk2);
147 if ( action ) {
148 sp_action_perform( action, NULL );
149 if (object->updates) {
150 sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip()));
151 }
152 return TRUE;
153 }
154 }
155 }
156 return FALSE;
157 }
159 /****************************************************************************
160 DOCUMENT INTERFACE CLASS STUFF
161 ****************************************************************************/
163 G_DEFINE_TYPE(DocumentInterface, document_interface, G_TYPE_OBJECT)
165 static void
166 document_interface_finalize (GObject *object)
167 {
168 G_OBJECT_CLASS (document_interface_parent_class)->finalize (object);
169 }
172 static void
173 document_interface_class_init (DocumentInterfaceClass *klass)
174 {
175 GObjectClass *object_class;
176 object_class = G_OBJECT_CLASS (klass);
177 object_class->finalize = document_interface_finalize;
178 }
180 static void
181 document_interface_init (DocumentInterface *object)
182 {
183 object->desk = NULL;
184 }
187 DocumentInterface *
188 document_interface_new (void)
189 {
190 return (DocumentInterface*)g_object_new (TYPE_DOCUMENT_INTERFACE, NULL);
191 }
193 /****************************************************************************
194 MISC FUNCTIONS
195 ****************************************************************************/
197 gboolean
198 document_interface_delete_all (DocumentInterface *object, GError **error)
199 {
200 sp_edit_clear_all (object->desk);
201 return TRUE;
202 }
204 void
205 document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error)
206 {
207 SPDesktop *desk2 = object->desk;
208 desktop_ensure_active (object->desk);
209 if ( desk2 ) {
210 Inkscape::Verb *verb = Inkscape::Verb::getbyid( verbid );
211 if ( verb ) {
212 SPAction *action = verb->get_action(desk2);
213 if ( action ) {
214 sp_action_perform( action, NULL );
215 if (object->updates) {
216 sp_document_done(sp_desktop_document(desk2), verb->get_code(), g_strdup(verb->get_tip()));
217 }
218 }
219 }
220 }
221 }
224 /****************************************************************************
225 CREATION FUNCTIONS
226 ****************************************************************************/
228 gchar*
229 document_interface_rectangle (DocumentInterface *object, int x, int y,
230 int width, int height, GError **error)
231 {
234 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, TRUE);
235 sp_repr_set_int(newNode, "x", x); //could also use newNode->setAttribute()
236 sp_repr_set_int(newNode, "y", y);
237 sp_repr_set_int(newNode, "width", width);
238 sp_repr_set_int(newNode, "height", height);
239 return finish_create_shape (object, error, newNode, (gchar *)"create rectangle");
240 }
242 gchar*
243 document_interface_ellipse_center (DocumentInterface *object, int cx, int cy,
244 int rx, int ry, GError **error)
245 {
246 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
247 newNode->setAttribute("sodipodi:type", "arc");
248 sp_repr_set_int(newNode, "sodipodi:cx", cx);
249 sp_repr_set_int(newNode, "sodipodi:cy", cy);
250 sp_repr_set_int(newNode, "sodipodi:rx", rx);
251 sp_repr_set_int(newNode, "sodipodi:ry", ry);
252 return finish_create_shape (object, error, newNode, (gchar *)"create circle");
253 }
255 gchar*
256 document_interface_polygon (DocumentInterface *object, int cx, int cy,
257 int radius, int rotation, int sides,
258 GError **error)
259 {
260 gdouble rot = ((rotation / 180.0) * 3.14159265) - ( 3.14159265 / 2.0);
261 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
262 newNode->setAttribute("inkscape:flatsided", "true");
263 newNode->setAttribute("sodipodi:type", "star");
264 sp_repr_set_int(newNode, "sodipodi:cx", cx);
265 sp_repr_set_int(newNode, "sodipodi:cy", cy);
266 sp_repr_set_int(newNode, "sodipodi:r1", radius);
267 sp_repr_set_int(newNode, "sodipodi:r2", radius);
268 sp_repr_set_int(newNode, "sodipodi:sides", sides);
269 sp_repr_set_int(newNode, "inkscape:randomized", 0);
270 sp_repr_set_svg_double(newNode, "sodipodi:arg1", rot);
271 sp_repr_set_svg_double(newNode, "sodipodi:arg2", rot);
272 sp_repr_set_svg_double(newNode, "inkscape:rounded", 0);
274 return finish_create_shape (object, error, newNode, (gchar *)"create polygon");
275 }
277 gchar*
278 document_interface_star (DocumentInterface *object, int cx, int cy,
279 int r1, int r2, int sides, gdouble rounded,
280 gdouble arg1, gdouble arg2, GError **error)
281 {
282 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
283 newNode->setAttribute("inkscape:flatsided", "false");
284 newNode->setAttribute("sodipodi:type", "star");
285 sp_repr_set_int(newNode, "sodipodi:cx", cx);
286 sp_repr_set_int(newNode, "sodipodi:cy", cy);
287 sp_repr_set_int(newNode, "sodipodi:r1", r1);
288 sp_repr_set_int(newNode, "sodipodi:r2", r2);
289 sp_repr_set_int(newNode, "sodipodi:sides", sides);
290 sp_repr_set_int(newNode, "inkscape:randomized", 0);
291 sp_repr_set_svg_double(newNode, "sodipodi:arg1", arg1);
292 sp_repr_set_svg_double(newNode, "sodipodi:arg2", arg2);
293 sp_repr_set_svg_double(newNode, "inkscape:rounded", rounded);
295 return finish_create_shape (object, error, newNode, (gchar *)"create star");
296 }
298 gchar*
299 document_interface_ellipse (DocumentInterface *object, int x, int y,
300 int width, int height, GError **error)
301 {
302 int rx = width/2;
303 int ry = height/2;
304 return document_interface_ellipse_center (object, x+rx, y+ry, rx, ry, error);
305 }
307 gchar*
308 document_interface_line (DocumentInterface *object, int x, int y,
309 int x2, int y2, GError **error)
310 {
311 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
312 std::stringstream out;
313 printf("X2: %d\nY2 %d\n", x2, y2);
314 out << "m " << x << "," << y << " " << x2 << "," << y2;
315 printf ("PATH: %s\n", out.str().c_str());
316 newNode->setAttribute("d", out.str().c_str());
317 return finish_create_shape (object, error, newNode, (gchar *)"create line");
318 }
320 gchar*
321 document_interface_spiral (DocumentInterface *object, int cx, int cy,
322 int r, int revolutions, GError **error)
323 {
324 Inkscape::XML::Node *newNode = dbus_create_node(object->desk, FALSE);
325 newNode->setAttribute("sodipodi:type", "spiral");
326 sp_repr_set_int(newNode, "sodipodi:cx", cx);
327 sp_repr_set_int(newNode, "sodipodi:cy", cy);
328 sp_repr_set_int(newNode, "sodipodi:radius", r);
329 sp_repr_set_int(newNode, "sodipodi:revolution", revolutions);
330 sp_repr_set_int(newNode, "sodipodi:t0", 0);
331 sp_repr_set_int(newNode, "sodipodi:argument", 0);
332 sp_repr_set_int(newNode, "sodipodi:expansion", 1);
333 gchar * retval = finish_create_shape (object, error, newNode, (gchar *)"create spiral");
334 newNode->setAttribute("style", "fill:none");
335 return retval;
336 }
338 gchar*
339 document_interface_text (DocumentInterface *object, gchar *text, GError **error)
340 {
341 //FIXME: implement.
342 return NULL;
343 }
345 gchar*
346 document_interface_node (DocumentInterface *object, gchar *type, GError **error)
347 {
348 SPDocument * doc = sp_desktop_document (object->desk);
349 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
351 Inkscape::XML::Node *newNode = xml_doc->createElement(type);
353 object->desk->currentLayer()->appendChildRepr(newNode);
354 object->desk->currentLayer()->updateRepr();
356 if (object->updates)
357 sp_document_done(sp_desktop_document(object->desk), 0, (gchar *)"created empty node");
358 else
359 document_interface_pause_updates(object, error);
361 return strdup(newNode->attribute("id"));
362 }
364 /****************************************************************************
365 ENVIORNMENT FUNCTIONS
366 ****************************************************************************/
367 gdouble
368 document_interface_document_get_width (DocumentInterface *object)
369 {
370 return sp_document_width(sp_desktop_document(object->desk));
371 }
373 gdouble
374 document_interface_document_get_height (DocumentInterface *object)
375 {
376 return sp_document_height(sp_desktop_document(object->desk));
377 }
379 gchar *
380 document_interface_document_get_css (DocumentInterface *object, GError **error)
381 {
382 SPCSSAttr *current = (object->desk)->current;
383 return sp_repr_css_write_string(current);
384 }
386 gboolean
387 document_interface_document_merge_css (DocumentInterface *object,
388 gchar *stylestring, GError **error)
389 {
390 SPCSSAttr * style = sp_repr_css_attr_new();
391 sp_repr_css_attr_add_from_string (style, stylestring);
392 sp_desktop_set_style (object->desk, style);
393 return TRUE;
394 }
396 gboolean
397 document_interface_document_set_css (DocumentInterface *object,
398 gchar *stylestring, GError **error)
399 {
400 SPCSSAttr * style = sp_repr_css_attr_new();
401 sp_repr_css_attr_add_from_string (style, stylestring);
402 //Memory leak?
403 object->desk->current = style;
404 return TRUE;
405 }
407 gboolean
408 document_interface_document_resize_to_fit_selection (DocumentInterface *object,
409 GError **error)
410 {
411 dbus_call_verb (object, SP_VERB_FIT_CANVAS_TO_SELECTION, error);
412 return TRUE;
413 }
415 /****************************************************************************
416 OBJECT FUNCTIONS
417 ****************************************************************************/
419 gboolean
420 document_interface_set_attribute (DocumentInterface *object, char *shape,
421 char *attribute, char *newval, GError **error)
422 {
423 Inkscape::XML::Node *newNode = get_object_by_name(object->desk, shape)->repr;
425 /* ALTERNATIVE (is this faster?)
426 Inkscape::XML::Node *newnode = sp_repr_lookup_name((doc->root)->repr, name);
427 */
428 if (newNode)
429 {
430 newNode->setAttribute(attribute, newval, TRUE);
431 return TRUE;
432 }
433 return FALSE;
434 }
436 void
437 document_interface_set_int_attribute (DocumentInterface *object,
438 char *shape, char *attribute,
439 int newval, GError **error)
440 {
441 Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr;
442 if (newNode)
443 sp_repr_set_int (newNode, attribute, newval);
444 }
447 void
448 document_interface_set_double_attribute (DocumentInterface *object,
449 char *shape, char *attribute,
450 double newval, GError **error)
451 {
452 Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr;
453 if (newNode)
454 sp_repr_set_svg_double (newNode, attribute, newval);
455 }
457 gchar *
458 document_interface_get_attribute (DocumentInterface *object, char *shape,
459 char *attribute, GError **error)
460 {
461 Inkscape::XML::Node *newNode = get_object_by_name(object->desk, shape)->repr;
463 if (newNode)
464 return g_strdup(newNode->attribute(attribute));
465 return FALSE;
466 }
468 gboolean
469 document_interface_move (DocumentInterface *object, gchar *name, gdouble x,
470 gdouble y, GError **error)
471 {
472 const GSList *oldsel = selection_swap(object->desk, name);
473 sp_selection_move (object->desk, x, 0 - y);
474 selection_restore(object->desk, oldsel);
475 return TRUE;
476 }
478 gboolean
479 document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x,
480 gdouble y, GError **error)
481 {
482 const GSList *oldsel = selection_swap(object->desk, name);
483 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
484 sp_selection_move (object->desk, x - selection_get_center_x(sel),
485 0 - (y - selection_get_center_y(sel)));
486 selection_restore(object->desk, oldsel);
487 return TRUE;
488 }
490 gboolean
491 document_interface_object_to_path (DocumentInterface *object,
492 char *shape, GError **error)
493 {
494 const GSList *oldsel = selection_swap(object->desk, shape);
495 dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
496 selection_restore(object->desk, oldsel);
497 return TRUE;
498 }
500 gchar *
501 document_interface_get_path (DocumentInterface *object, char *pathname, GError **error)
502 {
503 Inkscape::XML::Node *node = document_retrive_node (sp_desktop_document (object->desk), pathname);
504 if (node == NULL || node->attribute("d") == NULL) {
505 g_set_error(error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION, "Object is not a path or does not exist.");
506 return FALSE;
507 }
508 return strdup(node->attribute("d"));
509 }
511 gboolean
512 document_interface_transform (DocumentInterface *object, gchar *shape,
513 gchar *transformstr, GError **error)
514 {
515 //FIXME: This should merge transformations.
516 gchar trans[] = "transform";
517 document_interface_set_attribute (object, shape, trans, transformstr, error);
518 return TRUE;
519 }
521 gchar *
522 document_interface_get_css (DocumentInterface *object, gchar *shape,
523 GError **error)
524 {
525 gchar style[] = "style";
526 return document_interface_get_attribute (object, shape, style, error);
527 }
529 gboolean
530 document_interface_modify_css (DocumentInterface *object, gchar *shape,
531 gchar *cssattrb, gchar *newval, GError **error)
532 {
533 gchar style[] = "style";
534 Inkscape::XML::Node *node = get_object_by_name(object->desk, shape)->repr;
535 SPCSSAttr * oldstyle = sp_repr_css_attr (node, style);
536 sp_repr_css_set_property(oldstyle, cssattrb, newval);
537 node->setAttribute (style, sp_repr_css_write_string (oldstyle), TRUE);
538 return TRUE;
539 }
541 gboolean
542 document_interface_merge_css (DocumentInterface *object, gchar *shape,
543 gchar *stylestring, GError **error)
544 {
545 SPCSSAttr * newstyle = sp_repr_css_attr_new();
546 sp_repr_css_attr_add_from_string (newstyle, stylestring);
548 gchar style[] = "style";
549 Inkscape::XML::Node *node = get_object_by_name(object->desk, shape)->repr;
550 SPCSSAttr * oldstyle = sp_repr_css_attr (node, style);
552 sp_repr_css_merge(oldstyle, newstyle);
553 node->setAttribute (style, sp_repr_css_write_string (oldstyle), TRUE);
554 return TRUE;
555 }
557 gboolean
558 document_interface_move_to_layer (DocumentInterface *object, gchar *shape,
559 gchar *layerstr, GError **error)
560 {
561 const GSList *oldsel = selection_swap(object->desk, shape);
562 document_interface_selection_move_to_layer(object, layerstr, error);
563 selection_restore(object->desk, oldsel);
564 return TRUE;
565 }
567 DBUSPoint **
568 document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape)
569 {
570 //FIXME: Needs lot's of work.
571 /*
572 Inkscape::XML::Node *node = document_retrive_node (sp_desktop_document (object->desk), pathname);
573 if (node == NULL || node->attribute("d") == NULL) {
574 g_set_error(error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION, "Object is not a path or does not exist.");
575 return FALSE;
576 }
577 //char * path = strdup(node->attribute("d"));
578 */
579 return NULL;
580 }
583 /****************************************************************************
584 FILE I/O FUNCTIONS
585 ****************************************************************************/
587 gboolean
588 document_interface_save (DocumentInterface *object, GError **error)
589 {
590 SPDocument * doc = sp_desktop_document(object->desk);
591 printf("1: %s\n2: %s\n3: %s\n", doc->uri, doc->base, doc->name);
592 if (doc->uri)
593 return document_interface_save_as (object, doc->uri, error);
594 return FALSE;
595 }
597 gboolean
598 document_interface_load (DocumentInterface *object,
599 gchar *filename, GError **error)
600 {
601 desktop_ensure_active (object->desk);
602 const Glib::ustring file(filename);
603 sp_file_open(file, NULL, TRUE, TRUE);
604 if (object->updates)
605 sp_document_done(sp_desktop_document(object->desk), SP_VERB_FILE_OPEN, "Opened File");
606 return TRUE;
607 }
609 gboolean
610 document_interface_save_as (DocumentInterface *object,
611 gchar *filename, GError **error)
612 {
613 SPDocument * doc = sp_desktop_document(object->desk);
614 #ifdef WITH_GNOME_VFS
615 const Glib::ustring file(filename);
616 return file_save_remote(doc, file, NULL, TRUE, TRUE);
617 #endif
618 if (!doc || strlen(filename)<1) //Safety check
619 return false;
621 try {
622 Inkscape::Extension::save(NULL, doc, filename,
623 false, false, true);
624 } catch (...) {
625 //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
626 return false;
627 }
629 //SP_ACTIVE_DESKTOP->event_log->rememberFileSave();
630 //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, "Document saved.");
631 return true;
632 }
633 /*
634 gboolean
635 document_interface_print_to_file (DocumentInterface *object, GError **error)
636 {
637 SPDocument * doc = sp_desktop_document(object->desk);
638 sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf"));
640 return TRUE;
641 }
642 */
643 /****************************************************************************
644 PROGRAM CONTROL FUNCTIONS
645 ****************************************************************************/
647 gboolean
648 document_interface_close (DocumentInterface *object, GError **error)
649 {
650 return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error);
651 }
653 gboolean
654 document_interface_exit (DocumentInterface *object, GError **error)
655 {
656 return dbus_call_verb (object, SP_VERB_FILE_QUIT, error);
657 }
659 gboolean
660 document_interface_undo (DocumentInterface *object, GError **error)
661 {
662 return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error);
663 }
665 gboolean
666 document_interface_redo (DocumentInterface *object, GError **error)
667 {
668 return dbus_call_verb (object, SP_VERB_EDIT_REDO, error);
669 }
673 /****************************************************************************
674 UPDATE FUNCTIONS
675 ****************************************************************************/
677 void
678 document_interface_pause_updates (DocumentInterface *object, GError **error)
679 {
680 object->updates = FALSE;
681 sp_desktop_document(object->desk)->root->uflags = FALSE;
682 sp_desktop_document(object->desk)->root->mflags = FALSE;
683 }
685 void
686 document_interface_resume_updates (DocumentInterface *object, GError **error)
687 {
688 object->updates = TRUE;
689 sp_desktop_document(object->desk)->root->uflags = TRUE;
690 sp_desktop_document(object->desk)->root->mflags = TRUE;
691 //sp_desktop_document(object->desk)->_updateDocument();
692 sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
693 }
695 void
696 document_interface_update (DocumentInterface *object, GError **error)
697 {
698 sp_desktop_document(object->desk)->root->uflags = TRUE;
699 sp_desktop_document(object->desk)->root->mflags = TRUE;
700 sp_desktop_document(object->desk)->_updateDocument();
701 sp_desktop_document(object->desk)->root->uflags = FALSE;
702 sp_desktop_document(object->desk)->root->mflags = FALSE;
703 //sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
704 }
706 /****************************************************************************
707 SELECTION FUNCTIONS FIXME: use call_verb where appropriate.
708 ****************************************************************************/
710 gboolean
711 document_interface_selection_get (DocumentInterface *object, GSList const * listy, GError **error)
712 {
713 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
714 GSList const *oldsel = sel->list();
716 int size = g_slist_length((GSList *) oldsel);
717 int i;
718 printf("premalloc\n");
719 gchar **list = (gchar **)malloc(size);
720 printf("postmalloc\n");
721 for(i = 0; i < size; i++)
722 list[i] = (gchar *)malloc(sizeof(gchar) * 10);
723 printf("postmalloc2\n");
724 i=0;
725 printf("prealloc\n");
726 for (GSList const *iter = oldsel; iter != NULL; iter = iter->next) {
727 strcpy (list[i], SP_OBJECT(iter->data)->repr->attribute("id"));
728 i++;
729 }
730 printf("postalloc\n");
731 for (i=0; i<size; i++) {
732 printf("%d = %s\n", i, list[i]);
733 }
735 listy = oldsel;
736 return TRUE;
737 }
739 gboolean
740 document_interface_selection_add (DocumentInterface *object, char *name, GError **error)
741 {
742 if (name == NULL)
743 return FALSE;
744 SPDocument * doc = sp_desktop_document (object->desk);
745 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
746 /* WORKS
747 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
748 selection->add(repr2, TRUE);
749 */
750 selection->add(doc->getObjectById(name));
751 return TRUE;
752 }
754 gboolean
755 document_interface_selection_add_list (DocumentInterface *object,
756 char **names, GError **error)
757 {
758 //FIXME: implement.
759 return FALSE;
760 }
762 gboolean
763 document_interface_selection_set (DocumentInterface *object, char *name, GError **error)
764 {
765 SPDocument * doc = sp_desktop_document (object->desk);
766 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
767 selection->set(doc->getObjectById(name));
768 return TRUE;
769 }
771 gboolean
772 document_interface_selection_set_list (DocumentInterface *object,
773 gchar **names, GError **error)
774 {
775 //FIXME: broken array passing.
776 sp_desktop_selection(object->desk)->clear();
777 int i;
778 for (i=0;((i<30000) && (names[i] != NULL));i++) {
779 printf("NAME: %s\n", names[i]);
780 document_interface_selection_add(object, names[i], error);
781 }
782 return TRUE;
783 }
785 gboolean
786 document_interface_selection_rotate (DocumentInterface *object, int angle, GError **error)
787 {
788 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
789 sp_selection_rotate(selection, angle);
790 return TRUE;
791 }
793 gboolean
794 document_interface_selection_delete (DocumentInterface *object, GError **error)
795 {
796 sp_selection_delete (object->desk);
797 return TRUE;
798 }
800 gboolean
801 document_interface_selection_clear (DocumentInterface *object, GError **error)
802 {
803 sp_desktop_selection(object->desk)->clear();
804 return TRUE;
805 }
807 gboolean
808 document_interface_select_all (DocumentInterface *object, GError **error)
809 {
810 sp_edit_select_all (object->desk);
811 return TRUE;
812 }
814 gboolean
815 document_interface_select_all_in_all_layers(DocumentInterface *object,
816 GError **error)
817 {
818 sp_edit_select_all_in_all_layers (object->desk);
819 return TRUE;
820 }
822 gboolean
823 document_interface_selection_box (DocumentInterface *object, int x, int y,
824 int x2, int y2, gboolean replace,
825 GError **error)
826 {
827 //FIXME: implement.
828 return FALSE;
829 }
831 gboolean
832 document_interface_selection_invert (DocumentInterface *object, GError **error)
833 {
834 sp_edit_invert (object->desk);
835 return TRUE;
836 }
838 gboolean
839 document_interface_selection_group (DocumentInterface *object, GError **error)
840 {
841 sp_selection_group (object->desk);
842 return TRUE;
843 }
844 gboolean
845 document_interface_selection_ungroup (DocumentInterface *object, GError **error)
846 {
847 sp_selection_ungroup (object->desk);
848 return TRUE;
849 }
851 gboolean
852 document_interface_selection_cut (DocumentInterface *object, GError **error)
853 {
854 sp_selection_cut (object->desk);
855 return TRUE;
856 }
857 gboolean
858 document_interface_selection_copy (DocumentInterface *object, GError **error)
859 {
860 desktop_ensure_active (object->desk);
861 sp_selection_copy ();
862 return TRUE;
863 }
864 gboolean
865 document_interface_selection_paste (DocumentInterface *object, GError **error)
866 {
867 desktop_ensure_active (object->desk);
868 sp_selection_paste (object->desk, TRUE);
869 return TRUE;
870 }
872 gboolean
873 document_interface_selection_scale (DocumentInterface *object, gdouble grow, GError **error)
874 {
875 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
876 sp_selection_scale (selection, grow);
877 return TRUE;
878 }
880 gboolean
881 document_interface_selection_move (DocumentInterface *object, gdouble x, gdouble y, GError **error)
882 {
883 sp_selection_move (object->desk, x, 0 - y); //switching coordinate systems.
884 return TRUE;
885 }
887 gboolean
888 document_interface_selection_move_to (DocumentInterface *object, gdouble x, gdouble y, GError **error)
889 {
890 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
892 Geom::OptRect sel_bbox = sel->bounds();
893 if (sel_bbox) {
894 //Geom::Point m( (object->desk)->point() - sel_bbox->midpoint() );
895 Geom::Point m( x - selection_get_center_x(sel) , 0 - (y - selection_get_center_y(sel)) );
896 sp_selection_move_relative(sel, m, true);
897 }
898 return TRUE;
899 }
901 //FIXME: does not paste in new layer.
902 gboolean
903 document_interface_selection_move_to_layer (DocumentInterface *object,
904 gchar *layerstr, GError **error)
905 {
906 SPDesktop * dt = object->desk;
908 Inkscape::Selection *selection = sp_desktop_selection(dt);
910 // check if something is selected
911 if (selection->isEmpty())
912 return FALSE;
914 SPObject *next = get_object_by_name(object->desk, layerstr);
916 if (next && (strcmp("layer", (next->repr)->attribute("inkscape:groupmode")) == 0)) {
918 sp_selection_cut(dt);
920 dt->setCurrentLayer(next);
922 sp_selection_paste(dt, TRUE);
923 }
924 return TRUE;
925 }
927 gboolean
928 document_interface_selection_get_center (DocumentInterface *object)
929 {
930 //FIXME: implement: pass struct.
931 return FALSE;
932 }
934 gboolean
935 document_interface_selection_to_path (DocumentInterface *object, GError **error)
936 {
937 return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
938 }
941 gchar *
942 document_interface_selection_combine (DocumentInterface *object, gchar *cmd,
943 GError **error)
944 {
946 if (strcmp(cmd, "union") == 0)
947 dbus_call_verb (object, SP_VERB_SELECTION_UNION, error);
948 else if (strcmp(cmd, "intersection") == 0)
949 dbus_call_verb (object, SP_VERB_SELECTION_INTERSECT, error);
950 else if (strcmp(cmd, "difference") == 0)
951 dbus_call_verb (object, SP_VERB_SELECTION_DIFF, error);
952 else if (strcmp(cmd, "exclusion") == 0)
953 dbus_call_verb (object, SP_VERB_SELECTION_SYMDIFF, error);
954 else if (strcmp(cmd, "division") == 0)
955 dbus_call_verb (object, SP_VERB_SELECTION_CUT, error);
956 else
957 return NULL;
959 //FIXME: this WILL cause problems with division
960 return g_strdup((sp_desktop_selection(object->desk)->singleRepr())->attribute("id"));
961 }
963 gboolean
964 document_interface_selection_change_level (DocumentInterface *object, gchar *cmd,
965 GError **error)
966 {
967 if (strcmp(cmd, "raise") == 0)
968 return dbus_call_verb (object, SP_VERB_SELECTION_RAISE, error);
969 if (strcmp(cmd, "lower") == 0)
970 return dbus_call_verb (object, SP_VERB_SELECTION_LOWER, error);
971 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
972 return dbus_call_verb (object, SP_VERB_SELECTION_TO_FRONT, error);
973 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
974 return dbus_call_verb (object, SP_VERB_SELECTION_TO_BACK, error);
975 return TRUE;
976 }
978 /****************************************************************************
979 LAYER FUNCTIONS
980 ****************************************************************************/
982 gchar *
983 document_interface_layer_new (DocumentInterface *object, GError **error)
984 {
985 SPDesktop * dt = object->desk;
986 SPObject *new_layer = Inkscape::create_layer(dt->currentRoot(), dt->currentLayer(), Inkscape::LPOS_BELOW);
987 dt->setCurrentLayer(new_layer);
988 return g_strdup(get_name_from_object (new_layer));
989 }
991 gboolean
992 document_interface_layer_set (DocumentInterface *object,
993 gchar *layerstr, GError **error)
994 {
995 object->desk->setCurrentLayer (get_object_by_name (object->desk, layerstr));
996 return TRUE;
997 }
999 gchar **
1000 document_interface_layer_get_all (DocumentInterface *object)
1001 {
1002 //FIXME: implement.
1003 return NULL;
1004 }
1006 gboolean
1007 document_interface_layer_change_level (DocumentInterface *object,
1008 gchar *cmd, GError **error)
1009 {
1010 if (strcmp(cmd, "raise") == 0)
1011 return dbus_call_verb (object, SP_VERB_LAYER_RAISE, error);
1012 if (strcmp(cmd, "lower") == 0)
1013 return dbus_call_verb (object, SP_VERB_LAYER_LOWER, error);
1014 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
1015 return dbus_call_verb (object, SP_VERB_LAYER_TO_TOP, error);
1016 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
1017 return dbus_call_verb (object, SP_VERB_LAYER_TO_BOTTOM, error);
1018 return TRUE;
1019 }
1021 gboolean
1022 document_interface_layer_next (DocumentInterface *object, GError **error)
1023 {
1024 return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error);
1025 }
1027 gboolean
1028 document_interface_layer_previous (DocumentInterface *object, GError **error)
1029 {
1030 return dbus_call_verb (object, SP_VERB_LAYER_PREV, error);
1031 }