Code

implemented a number of functions, including save/load functions.
[inkscape.git] / src / extension / dbus / document-interface.cpp
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());
89     
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)
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);
114 gchar *
115 finish_create_shape (DocumentInterface *object, GError **error, Inkscape::XML::Node *newNode, gchar *desc)
118     SPCSSAttr *style = sp_desktop_get_style(object->desk, TRUE);
119     
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"));
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;
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)
168         G_OBJECT_CLASS (document_interface_parent_class)->finalize (object);
172 static void
173 document_interface_class_init (DocumentInterfaceClass *klass)
175         GObjectClass *object_class;
176         object_class = G_OBJECT_CLASS (klass);
177         object_class->finalize = document_interface_finalize;
180 static void
181 document_interface_init (DocumentInterface *object)
183         object->desk = NULL;
187 DocumentInterface *
188 document_interface_new (void)
190         return (DocumentInterface*)g_object_new (TYPE_DOCUMENT_INTERFACE, NULL);
193 /****************************************************************************
194      MISC FUNCTIONS
195 ****************************************************************************/
197 gboolean
198 document_interface_delete_all (DocumentInterface *object, GError **error)
200     sp_edit_clear_all (object->desk);
201     return TRUE;
204 void
205 document_interface_call_verb (DocumentInterface *object, gchar *verbid, GError **error)
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     }
224 /****************************************************************************
225      CREATION FUNCTIONS
226 ****************************************************************************/
228 gchar* 
229 document_interface_rectangle (DocumentInterface *object, int x, int y, 
230                               int width, int height, GError **error)
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");
242 gchar*
243 document_interface_ellipse_center (DocumentInterface *object, int cx, int cy, 
244                                    int rx, int ry, GError **error)
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");
255 gchar* 
256 document_interface_polygon (DocumentInterface *object, int cx, int cy, 
257                             int radius, int rotation, int sides, 
258                             GError **error)
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");
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)
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");
298 gchar* 
299 document_interface_ellipse (DocumentInterface *object, int x, int y, 
300                             int width, int height, GError **error)
302     int rx = width/2;
303     int ry = height/2;
304     return document_interface_ellipse_center (object, x+rx, y+ry, rx, ry, error);
307 gchar* 
308 document_interface_line (DocumentInterface *object, int x, int y, 
309                               int x2, int y2, GError **error)
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");
320 gchar* 
321 document_interface_spiral (DocumentInterface *object, int cx, int cy, 
322                            int r, int revolutions, GError **error)
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;
338 gchar* 
339 document_interface_text (DocumentInterface *object, gchar *text, GError **error)
341     //FIXME: implement.
342     return NULL;
345 gchar* 
346 document_interface_node (DocumentInterface *object, gchar *type, GError **error)
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"));
364 /****************************************************************************
365      ENVIORNMENT FUNCTIONS
366 ****************************************************************************/
367 gdouble
368 document_interface_document_get_width (DocumentInterface *object)
370     return sp_document_width(sp_desktop_document(object->desk));
373 gdouble
374 document_interface_document_get_height (DocumentInterface *object)
376     return sp_document_height(sp_desktop_document(object->desk));
379 gchar *
380 document_interface_document_get_css (DocumentInterface *object, GError **error)
382     SPCSSAttr *current = (object->desk)->current;
383     return sp_repr_css_write_string(current);
386 gboolean 
387 document_interface_document_merge_css (DocumentInterface *object,
388                                        gchar *stylestring, GError **error)
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;
396 gboolean 
397 document_interface_document_set_css (DocumentInterface *object,
398                                      gchar *stylestring, GError **error)
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;
407 gboolean 
408 document_interface_document_resize_to_fit_selection (DocumentInterface *object,
409                                                      GError **error)
411     dbus_call_verb (object, SP_VERB_FIT_CANVAS_TO_SELECTION, error);
412     return TRUE;
415 /****************************************************************************
416      OBJECT FUNCTIONS
417 ****************************************************************************/
419 gboolean
420 document_interface_set_attribute (DocumentInterface *object, char *shape, 
421                                   char *attribute, char *newval, GError **error)
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;
436 void 
437 document_interface_set_int_attribute (DocumentInterface *object, 
438                                       char *shape, char *attribute, 
439                                       int newval, GError **error)
441     Inkscape::XML::Node *newNode = get_object_by_name (object->desk, shape)->repr;
442     if (newNode)
443         sp_repr_set_int (newNode, attribute, newval);
447 void 
448 document_interface_set_double_attribute (DocumentInterface *object, 
449                                          char *shape, char *attribute, 
450                                          double newval, GError **error)
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);
457 gchar *
458 document_interface_get_attribute (DocumentInterface *object, char *shape, 
459                                   char *attribute, GError **error)
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;
474 gboolean
475 document_interface_move (DocumentInterface *object, gchar *name, gdouble x, 
476                          gdouble y, GError **error)
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;
484 gboolean
485 document_interface_move_to (DocumentInterface *object, gchar *name, gdouble x, 
486                          gdouble y, GError **error)
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;
496 void 
497 document_interface_object_to_path (DocumentInterface *object, 
498                                    char *shape, GError **error)
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);
505 gboolean
506 document_interface_get_path (DocumentInterface *object, char *pathname, GError **error)
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;
524 gboolean 
525 document_interface_transform (DocumentInterface *object, gchar *shape,
526                               gchar *transformstr, GError **error)
528     //FIXME: This should merge transformations.
529     gchar trans[] = "transform";
530     document_interface_set_attribute (object, shape, trans, transformstr, error);
531     return TRUE;
534 gchar *
535 document_interface_get_css (DocumentInterface *object, gchar *shape,
536                             GError **error)
538     gchar style[] = "style";
539     return document_interface_get_attribute (object, shape, style, error);
542 gboolean 
543 document_interface_modify_css (DocumentInterface *object, gchar *shape,
544                                gchar *cssattrb, gchar *newval, GError **error)
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;
554 gboolean 
555 document_interface_merge_css (DocumentInterface *object, gchar *shape,
556                                gchar *stylestring, GError **error)
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;
570 gboolean 
571 document_interface_move_to_layer (DocumentInterface *object, gchar *shape, 
572                               gchar *layerstr, GError **error)
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;
580 DBUSPoint ** 
581 document_interface_get_node_coordinates (DocumentInterface *object, gchar *shape)
583     //FIXME: implement.
584     return NULL;
588 /****************************************************************************
589      FILE I/O FUNCTIONS
590 ****************************************************************************/
592 gboolean 
593 document_interface_save (DocumentInterface *object, GError **error)
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;
602 gboolean 
603 document_interface_load (DocumentInterface *object, 
604                         gchar *filename, GError **error)
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;
614 gboolean 
615 document_interface_save_as (DocumentInterface *object, 
616                            gchar *filename, GError **error)
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;
638 /*
639 gboolean 
640 document_interface_print_to_file (DocumentInterface *object, GError **error)
642     SPDocument * doc = sp_desktop_document(object->desk);
643     sp_print_document_to_file (doc, g_strdup("/home/soren/test.pdf"));
644                                
645     return TRUE;
647 */
648 /****************************************************************************
649      PROGRAM CONTROL FUNCTIONS
650 ****************************************************************************/
652 gboolean
653 document_interface_close (DocumentInterface *object, GError **error)
655     return dbus_call_verb (object, SP_VERB_FILE_CLOSE_VIEW, error);
658 gboolean
659 document_interface_exit (DocumentInterface *object, GError **error)
661     return dbus_call_verb (object, SP_VERB_FILE_QUIT, error);
664 gboolean
665 document_interface_undo (DocumentInterface *object, GError **error)
667     return dbus_call_verb (object, SP_VERB_EDIT_UNDO, error);
670 gboolean
671 document_interface_redo (DocumentInterface *object, GError **error)
673     return dbus_call_verb (object, SP_VERB_EDIT_REDO, error);
678 /****************************************************************************
679      UPDATE FUNCTIONS
680 ****************************************************************************/
682 void
683 document_interface_pause_updates (DocumentInterface *object, GError **error)
685     object->updates = FALSE;
686     sp_desktop_document(object->desk)->root->uflags = FALSE;
687     sp_desktop_document(object->desk)->root->mflags = FALSE;
690 void
691 document_interface_resume_updates (DocumentInterface *object, GError **error)
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");
700 void
701 document_interface_update (DocumentInterface *object, GError **error)
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");
711 /****************************************************************************
712      SELECTION FUNCTIONS FIXME: use call_verb where appropriate.
713 ****************************************************************************/
715 gchar **
716 document_interface_selection_get (DocumentInterface *object)
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     }
739     
740     return list;
743 gboolean
744 document_interface_selection_add (DocumentInterface *object, char *name, GError **error)
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;
758 gboolean
759 document_interface_selection_add_list (DocumentInterface *object, 
760                                        char **names, GError **error)
762     //FIXME: implement.
763     return FALSE;
766 gboolean
767 document_interface_selection_set (DocumentInterface *object, char *name, GError **error)
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;
775 gboolean
776 document_interface_selection_set_list (DocumentInterface *object, 
777                                        gchar **names, GError **error)
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;
789 gboolean
790 document_interface_selection_rotate (DocumentInterface *object, int angle, GError **error)
792     Inkscape::Selection *selection = sp_desktop_selection(object->desk);
793     sp_selection_rotate(selection, angle);
794     return TRUE;
797 gboolean
798 document_interface_selection_delete (DocumentInterface *object, GError **error)
800     sp_selection_delete (object->desk);
801     return TRUE;
804 gboolean
805 document_interface_selection_clear (DocumentInterface *object, GError **error)
807     sp_desktop_selection(object->desk)->clear();
808     return TRUE;
811 gboolean
812 document_interface_select_all (DocumentInterface *object, GError **error)
814     sp_edit_select_all (object->desk);
815     return TRUE;
818 gboolean
819 document_interface_select_all_in_all_layers(DocumentInterface *object, 
820                                             GError **error)
822     sp_edit_select_all_in_all_layers (object->desk);
823     return TRUE;
826 gboolean
827 document_interface_selection_box (DocumentInterface *object, int x, int y,
828                                   int x2, int y2, gboolean replace, 
829                                   GError **error)
831     //FIXME: implement.
832     return FALSE;
835 gboolean
836 document_interface_selection_invert (DocumentInterface *object, GError **error)
838     sp_edit_invert (object->desk);
839     return TRUE;
842 gboolean
843 document_interface_selection_group (DocumentInterface *object, GError **error)
845     sp_selection_group (object->desk);
846     return TRUE;
848 gboolean
849 document_interface_selection_ungroup (DocumentInterface *object, GError **error)
851     sp_selection_ungroup (object->desk);
852     return TRUE;
854  
855 gboolean
856 document_interface_selection_cut (DocumentInterface *object, GError **error)
858     sp_selection_cut (object->desk);
859     return TRUE;
861 gboolean
862 document_interface_selection_copy (DocumentInterface *object, GError **error)
864     desktop_ensure_active (object->desk);
865     sp_selection_copy ();
866     return TRUE;
868 gboolean
869 document_interface_selection_paste (DocumentInterface *object, GError **error)
871     desktop_ensure_active (object->desk);
872     sp_selection_paste (object->desk, TRUE);
873     return TRUE;
876 gboolean
877 document_interface_selection_scale (DocumentInterface *object, gdouble grow, GError **error)
879     Inkscape::Selection *selection = sp_desktop_selection(object->desk);
880     sp_selection_scale (selection, grow);
881     return TRUE;
884 gboolean
885 document_interface_selection_move (DocumentInterface *object, gdouble x, gdouble y, GError **error)
887     sp_selection_move (object->desk, x, 0 - y); //switching coordinate systems.
888     return TRUE;
891 gboolean
892 document_interface_selection_move_to (DocumentInterface *object, gdouble x, gdouble y, GError **error)
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;
905 //FIXME: does not paste in new layer.
906 gboolean 
907 document_interface_selection_move_to_layer (DocumentInterface *object,
908                                             gchar *layerstr, GError **error)
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;
931 gboolean 
932 document_interface_selection_get_center (DocumentInterface *object)
934     //FIXME: implement: pass struct.
935     return FALSE;
938 gboolean 
939 document_interface_selection_to_path (DocumentInterface *object, GError **error)
941     return dbus_call_verb (object, SP_VERB_OBJECT_TO_CURVE, error);    
945 gchar *
946 document_interface_selection_combine (DocumentInterface *object, gchar *cmd,
947                                       GError **error)
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"));
967 gboolean
968 document_interface_selection_change_level (DocumentInterface *object, gchar *cmd,
969                                       GError **error)
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;
982 /****************************************************************************
983      LAYER FUNCTIONS
984 ****************************************************************************/
986 gchar *
987 document_interface_layer_new (DocumentInterface *object, GError **error)
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));
995 gboolean 
996 document_interface_layer_set (DocumentInterface *object,
997                               gchar *layerstr, GError **error)
999     object->desk->setCurrentLayer (get_object_by_name (object->desk, layerstr));
1000     return TRUE;
1003 gchar **
1004 document_interface_layer_get_all (DocumentInterface *object)
1006     //FIXME: implement.
1007     return NULL;
1010 gboolean 
1011 document_interface_layer_change_level (DocumentInterface *object,
1012                                        gchar *cmd, GError **error)
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;
1025 gboolean 
1026 document_interface_layer_next (DocumentInterface *object, GError **error)
1028     return dbus_call_verb (object, SP_VERB_LAYER_NEXT, error);
1031 gboolean 
1032 document_interface_layer_previous (DocumentInterface *object, GError **error)
1034     return dbus_call_verb (object, SP_VERB_LAYER_PREV, error);