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
426 Inkscape::XML::Node *repr2 = 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 SPDesktop *desk2 = object->desk;
462 SPDocument * doc = sp_desktop_document (desk2);
464 Inkscape::XML::Node *newNode = doc->getObjectById(shape)->repr;
466 /* WORKS
467 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
468 */
469 if (newNode)
470 return g_strdup(newNode->attribute(attribute));
471 return FALSE;
472 }
474 gboolean
475 document_interface_move (DocumentInterface *object, gchar *name, gdouble x,
476 gdouble y, GError **error)
477 {
478 const GSList *oldsel = selection_swap(object->desk, name);
479 sp_selection_move (object->desk, x, 0 - y);
480 selection_restore(object->desk, oldsel);
481 return TRUE;
482 }
484 gboolean
485 document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x,
486 gdouble y, GError **error)
487 {
488 const GSList *oldsel = selection_swap(object->desk, name);
489 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
490 sp_selection_move (object->desk, x - selection_get_center_x(sel),
491 0 - (y - selection_get_center_y(sel)));
492 selection_restore(object->desk, oldsel);
493 return TRUE;
494 }
496 void
497 document_interface_object_to_path (DocumentInterface *object,
498 char *shape, GError **error)
499 {
500 const GSList *oldsel = selection_swap(object->desk, shape);
501 dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
502 selection_restore(object->desk, oldsel);
503 }
505 gboolean
506 document_interface_get_path (DocumentInterface *object, char *pathname, GError **error)
507 {
508 Inkscape::XML::Node *node = document_retrive_node (sp_desktop_document (object->desk), pathname);
509 if (node == NULL || node->attribute("d") == NULL) {
510 g_set_error(error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION, "Object is not a path or does not exist.");
511 return FALSE;
512 }
513 gchar *pathstr = strdup(node->attribute("d"));
514 printf("PATH: %s\n", pathstr);
515 //gfree (pathstr);
516 std::istringstream iss(pathstr);
517 std::copy(std::istream_iterator<std::string>(iss),
518 std::istream_iterator<std::string>(),
519 std::ostream_iterator<std::string>(std::cout, "\n"));
521 return TRUE;
522 }
524 gboolean
525 document_interface_transform (DocumentInterface *object, gchar *shape,
526 gchar *transformstr, GError **error)
527 {
528 //FIXME: This should merge transformations.
529 gchar trans[] = "transform";
530 document_interface_set_attribute (object, shape, trans, transformstr, error);
531 return TRUE;
532 }
534 gchar *
535 document_interface_get_css (DocumentInterface *object, gchar *shape,
536 GError **error)
537 {
538 gchar style[] = "style";
539 return document_interface_get_attribute (object, shape, style, error);
540 }
542 gboolean
543 document_interface_modify_css (DocumentInterface *object, gchar *shape,
544 gchar *cssattrb, gchar *newval, GError **error)
545 {
546 gchar style[] = "style";
547 Inkscape::XML::Node *node = get_object_by_name(object->desk, shape)->repr;
548 SPCSSAttr * oldstyle = sp_repr_css_attr (node, style);
549 sp_repr_css_set_property(oldstyle, cssattrb, newval);
550 node->setAttribute (style, sp_repr_css_write_string (oldstyle), TRUE);
551 return TRUE;
552 }
554 gboolean
555 document_interface_merge_css (DocumentInterface *object, gchar *shape,
556 gchar *stylestring, GError **error)
557 {
558 SPCSSAttr * newstyle = sp_repr_css_attr_new();
559 sp_repr_css_attr_add_from_string (newstyle, stylestring);
561 gchar style[] = "style";
562 Inkscape::XML::Node *node = get_object_by_name(object->desk, shape)->repr;
563 SPCSSAttr * oldstyle = sp_repr_css_attr (node, style);
565 sp_repr_css_merge(oldstyle, newstyle);
566 node->setAttribute (style, sp_repr_css_write_string (oldstyle), TRUE);
567 return TRUE;
568 }
570 gboolean
571 document_interface_move_to_layer (DocumentInterface *object, gchar *shape,
572 gchar *layerstr, GError **error)
573 {
574 const GSList *oldsel = selection_swap(object->desk, shape);
575 document_interface_selection_move_to_layer(object, layerstr, error);
576 selection_restore(object->desk, oldsel);
577 return TRUE;
578 }
580 DBUSPoint **
581 document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape)
582 {
583 //FIXME: implement.
584 return NULL;
585 }
588 /****************************************************************************
589 FILE I/O FUNCTIONS
590 ****************************************************************************/
592 gboolean
593 document_interface_save (DocumentInterface *object, GError **error)
594 {
595 SPDocument * doc = sp_desktop_document(object->desk);
596 printf("1: %s\n2: %s\n3: %s\n", doc->uri, doc->base, doc->name);
597 if (doc->uri)
598 return document_interface_save_as (object, doc->uri, error);
599 return FALSE;
600 }
602 gboolean
603 document_interface_load (DocumentInterface *object,
604 gchar *filename, GError **error)
605 {
606 desktop_ensure_active (object->desk);
607 const Glib::ustring file(filename);
608 sp_file_open(file, NULL, TRUE, TRUE);
609 if (object->updates)
610 sp_document_done(sp_desktop_document(object->desk), SP_VERB_FILE_OPEN, "Opened File");
611 return TRUE;
612 }
614 gboolean
615 document_interface_save_as (DocumentInterface *object,
616 gchar *filename, GError **error)
617 {
618 SPDocument * doc = sp_desktop_document(object->desk);
619 #ifdef WITH_GNOME_VFS
620 const Glib::ustring file(filename);
621 return file_save_remote(doc, file, NULL, TRUE, TRUE);
622 #endif
623 if (!doc || strlen(filename)<1) //Safety check
624 return false;
626 try {
627 Inkscape::Extension::save(NULL, doc, filename,
628 false, false, true);
629 } catch (...) {
630 //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
631 return false;
632 }
634 //SP_ACTIVE_DESKTOP->event_log->rememberFileSave();
635 //SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, "Document saved.");
636 return true;
637 }
638 /*
639 gboolean
640 document_interface_print_to_file (DocumentInterface *object, GError **error)
641 {
642 SPDocument * doc = sp_desktop_document(object->desk);
643 sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf"));
645 return TRUE;
646 }
647 */
648 /****************************************************************************
649 PROGRAM CONTROL FUNCTIONS
650 ****************************************************************************/
652 gboolean
653 document_interface_close (DocumentInterface *object, GError **error)
654 {
655 return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error);
656 }
658 gboolean
659 document_interface_exit (DocumentInterface *object, GError **error)
660 {
661 return dbus_call_verb (object, SP_VERB_FILE_QUIT, error);
662 }
664 gboolean
665 document_interface_undo (DocumentInterface *object, GError **error)
666 {
667 return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error);
668 }
670 gboolean
671 document_interface_redo (DocumentInterface *object, GError **error)
672 {
673 return dbus_call_verb (object, SP_VERB_EDIT_REDO, error);
674 }
678 /****************************************************************************
679 UPDATE FUNCTIONS
680 ****************************************************************************/
682 void
683 document_interface_pause_updates (DocumentInterface *object, GError **error)
684 {
685 object->updates = FALSE;
686 sp_desktop_document(object->desk)->root->uflags = FALSE;
687 sp_desktop_document(object->desk)->root->mflags = FALSE;
688 }
690 void
691 document_interface_resume_updates (DocumentInterface *object, GError **error)
692 {
693 object->updates = TRUE;
694 sp_desktop_document(object->desk)->root->uflags = TRUE;
695 sp_desktop_document(object->desk)->root->mflags = TRUE;
696 //sp_desktop_document(object->desk)->_updateDocument();
697 sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
698 }
700 void
701 document_interface_update (DocumentInterface *object, GError **error)
702 {
703 sp_desktop_document(object->desk)->root->uflags = TRUE;
704 sp_desktop_document(object->desk)->root->mflags = TRUE;
705 sp_desktop_document(object->desk)->_updateDocument();
706 sp_desktop_document(object->desk)->root->uflags = FALSE;
707 sp_desktop_document(object->desk)->root->mflags = FALSE;
708 //sp_document_done(sp_desktop_document(object->desk), SP_VERB_CONTEXT_RECT, "Multiple actions");
709 }
711 /****************************************************************************
712 SELECTION FUNCTIONS FIXME: use call_verb where appropriate.
713 ****************************************************************************/
715 gchar **
716 document_interface_selection_get (DocumentInterface *object)
717 {
718 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
719 GSList const *oldsel = sel->list();
721 int size = g_slist_length((GSList *) oldsel);
722 int i;
723 printf("premalloc\n");
724 gchar **list = (gchar **)malloc(size);
725 printf("postmalloc\n");
726 for(i = 0; i < size; i++)
727 list[i] = (gchar *)malloc(sizeof(gchar) * 10);
728 printf("postmalloc2\n");
729 i=0;
730 printf("prealloc\n");
731 for (GSList const *iter = oldsel; iter != NULL; iter = iter->next) {
732 strcpy (list[i], SP_OBJECT(iter->data)->repr->attribute("id"));
733 i++;
734 }
735 printf("postalloc\n");
736 for (i=0; i<size; i++) {
737 printf("%d = %s\n", i, list[i]);
738 }
740 return list;
741 }
743 gboolean
744 document_interface_selection_add (DocumentInterface *object, char *name, GError **error)
745 {
746 if (name == NULL)
747 return FALSE;
748 SPDocument * doc = sp_desktop_document (object->desk);
749 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
750 /* WORKS
751 Inkscape::XML::Node *repr2 = sp_repr_lookup_name((doc->root)->repr, name);
752 selection->add(repr2, TRUE);
753 */
754 selection->add(doc->getObjectById(name));
755 return TRUE;
756 }
758 gboolean
759 document_interface_selection_add_list (DocumentInterface *object,
760 char **names, GError **error)
761 {
762 //FIXME: implement.
763 return FALSE;
764 }
766 gboolean
767 document_interface_selection_set (DocumentInterface *object, char *name, GError **error)
768 {
769 SPDocument * doc = sp_desktop_document (object->desk);
770 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
771 selection->set(doc->getObjectById(name));
772 return TRUE;
773 }
775 gboolean
776 document_interface_selection_set_list (DocumentInterface *object,
777 gchar **names, GError **error)
778 {
779 //FIXME: broken array passing.
780 sp_desktop_selection(object->desk)->clear();
781 int i;
782 for (i=0;((i<30000) && (names[i] != NULL));i++) {
783 printf("NAME: %s\n", names[i]);
784 document_interface_selection_add(object, names[i], error);
785 }
786 return TRUE;
787 }
789 gboolean
790 document_interface_selection_rotate (DocumentInterface *object, int angle, GError **error)
791 {
792 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
793 sp_selection_rotate(selection, angle);
794 return TRUE;
795 }
797 gboolean
798 document_interface_selection_delete (DocumentInterface *object, GError **error)
799 {
800 sp_selection_delete (object->desk);
801 return TRUE;
802 }
804 gboolean
805 document_interface_selection_clear (DocumentInterface *object, GError **error)
806 {
807 sp_desktop_selection(object->desk)->clear();
808 return TRUE;
809 }
811 gboolean
812 document_interface_select_all (DocumentInterface *object, GError **error)
813 {
814 sp_edit_select_all (object->desk);
815 return TRUE;
816 }
818 gboolean
819 document_interface_select_all_in_all_layers(DocumentInterface *object,
820 GError **error)
821 {
822 sp_edit_select_all_in_all_layers (object->desk);
823 return TRUE;
824 }
826 gboolean
827 document_interface_selection_box (DocumentInterface *object, int x, int y,
828 int x2, int y2, gboolean replace,
829 GError **error)
830 {
831 //FIXME: implement.
832 return FALSE;
833 }
835 gboolean
836 document_interface_selection_invert (DocumentInterface *object, GError **error)
837 {
838 sp_edit_invert (object->desk);
839 return TRUE;
840 }
842 gboolean
843 document_interface_selection_group (DocumentInterface *object, GError **error)
844 {
845 sp_selection_group (object->desk);
846 return TRUE;
847 }
848 gboolean
849 document_interface_selection_ungroup (DocumentInterface *object, GError **error)
850 {
851 sp_selection_ungroup (object->desk);
852 return TRUE;
853 }
855 gboolean
856 document_interface_selection_cut (DocumentInterface *object, GError **error)
857 {
858 sp_selection_cut (object->desk);
859 return TRUE;
860 }
861 gboolean
862 document_interface_selection_copy (DocumentInterface *object, GError **error)
863 {
864 desktop_ensure_active (object->desk);
865 sp_selection_copy ();
866 return TRUE;
867 }
868 gboolean
869 document_interface_selection_paste (DocumentInterface *object, GError **error)
870 {
871 desktop_ensure_active (object->desk);
872 sp_selection_paste (object->desk, TRUE);
873 return TRUE;
874 }
876 gboolean
877 document_interface_selection_scale (DocumentInterface *object, gdouble grow, GError **error)
878 {
879 Inkscape::Selection *selection = sp_desktop_selection(object->desk);
880 sp_selection_scale (selection, grow);
881 return TRUE;
882 }
884 gboolean
885 document_interface_selection_move (DocumentInterface *object, gdouble x, gdouble y, GError **error)
886 {
887 sp_selection_move (object->desk, x, 0 - y); //switching coordinate systems.
888 return TRUE;
889 }
891 gboolean
892 document_interface_selection_move_to (DocumentInterface *object, gdouble x, gdouble y, GError **error)
893 {
894 Inkscape::Selection * sel = sp_desktop_selection(object->desk);
896 Geom::OptRect sel_bbox = sel->bounds();
897 if (sel_bbox) {
898 //Geom::Point m( (object->desk)->point() - sel_bbox->midpoint() );
899 Geom::Point m( x - selection_get_center_x(sel) , 0 - (y - selection_get_center_y(sel)) );
900 sp_selection_move_relative(sel, m, true);
901 }
902 return TRUE;
903 }
905 //FIXME: does not paste in new layer.
906 gboolean
907 document_interface_selection_move_to_layer (DocumentInterface *object,
908 gchar *layerstr, GError **error)
909 {
910 SPDesktop * dt = object->desk;
912 Inkscape::Selection *selection = sp_desktop_selection(dt);
914 // check if something is selected
915 if (selection->isEmpty())
916 return FALSE;
918 SPObject *next = get_object_by_name(object->desk, layerstr);
920 if (next && (strcmp("layer", (next->repr)->attribute("inkscape:groupmode")) == 0)) {
922 sp_selection_cut(dt);
924 dt->setCurrentLayer(next);
926 sp_selection_paste(dt, TRUE);
927 }
928 return TRUE;
929 }
931 gboolean
932 document_interface_selection_get_center (DocumentInterface *object)
933 {
934 //FIXME: implement: pass struct.
935 return FALSE;
936 }
938 gboolean
939 document_interface_selection_to_path (DocumentInterface *object, GError **error)
940 {
941 return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);
942 }
945 gchar *
946 document_interface_selection_combine (DocumentInterface *object, gchar *cmd,
947 GError **error)
948 {
950 if (strcmp(cmd, "union") == 0)
951 dbus_call_verb (object, SP_VERB_SELECTION_UNION, error);
952 else if (strcmp(cmd, "intersection") == 0)
953 dbus_call_verb (object, SP_VERB_SELECTION_INTERSECT, error);
954 else if (strcmp(cmd, "difference") == 0)
955 dbus_call_verb (object, SP_VERB_SELECTION_DIFF, error);
956 else if (strcmp(cmd, "exclusion") == 0)
957 dbus_call_verb (object, SP_VERB_SELECTION_SYMDIFF, error);
958 else if (strcmp(cmd, "division") == 0)
959 dbus_call_verb (object, SP_VERB_SELECTION_CUT, error);
960 else
961 return NULL;
963 //FIXME: this WILL cause problems with division
964 return g_strdup((sp_desktop_selection(object->desk)->singleRepr())->attribute("id"));
965 }
967 gboolean
968 document_interface_selection_change_level (DocumentInterface *object, gchar *cmd,
969 GError **error)
970 {
971 if (strcmp(cmd, "raise") == 0)
972 return dbus_call_verb (object, SP_VERB_SELECTION_RAISE, error);
973 if (strcmp(cmd, "lower") == 0)
974 return dbus_call_verb (object, SP_VERB_SELECTION_LOWER, error);
975 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
976 return dbus_call_verb (object, SP_VERB_SELECTION_TO_FRONT, error);
977 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
978 return dbus_call_verb (object, SP_VERB_SELECTION_TO_BACK, error);
979 return TRUE;
980 }
982 /****************************************************************************
983 LAYER FUNCTIONS
984 ****************************************************************************/
986 gchar *
987 document_interface_layer_new (DocumentInterface *object, GError **error)
988 {
989 SPDesktop * dt = object->desk;
990 SPObject *new_layer = Inkscape::create_layer(dt->currentRoot(), dt->currentLayer(), Inkscape::LPOS_BELOW);
991 dt->setCurrentLayer(new_layer);
992 return g_strdup(get_name_from_object (new_layer));
993 }
995 gboolean
996 document_interface_layer_set (DocumentInterface *object,
997 gchar *layerstr, GError **error)
998 {
999 object->desk->setCurrentLayer (get_object_by_name (object->desk, layerstr));
1000 return TRUE;
1001 }
1003 gchar **
1004 document_interface_layer_get_all (DocumentInterface *object)
1005 {
1006 //FIXME: implement.
1007 return NULL;
1008 }
1010 gboolean
1011 document_interface_layer_change_level (DocumentInterface *object,
1012 gchar *cmd, GError **error)
1013 {
1014 if (strcmp(cmd, "raise") == 0)
1015 return dbus_call_verb (object, SP_VERB_LAYER_RAISE, error);
1016 if (strcmp(cmd, "lower") == 0)
1017 return dbus_call_verb (object, SP_VERB_LAYER_LOWER, error);
1018 if ((strcmp(cmd, "to_top") == 0) || (strcmp(cmd, "to_front") == 0))
1019 return dbus_call_verb (object, SP_VERB_LAYER_TO_TOP, error);
1020 if ((strcmp(cmd, "to_bottom") == 0) || (strcmp(cmd, "to_back") == 0))
1021 return dbus_call_verb (object, SP_VERB_LAYER_TO_BOTTOM, error);
1022 return TRUE;
1023 }
1025 gboolean
1026 document_interface_layer_next (DocumentInterface *object, GError **error)
1027 {
1028 return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error);
1029 }
1031 gboolean
1032 document_interface_layer_previous (DocumentInterface *object, GError **error)
1033 {
1034 return dbus_call_verb (object, SP_VERB_LAYER_PREV, error);
1035 }