Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

void file_import ( SPDocument in_doc,
const Glib::ustring &  uri,
Inkscape::Extension::Extension key 
)

Import a resource. Called by sp_file_import()

Definition at line 951 of file file.cpp.

References Inkscape::XML::Node::appendChild(), SPObject::appendChildRepr(), SPDocument::base, Inkscape::Selection::bounds(), SPDesktop::currentLayer(), Inkscape::XML::ELEMENT_NODE, Inkscape::XML::Node::firstChild(), Geom::Matrix::inverse(), Inkscape::Extension::open(), SPDesktop::point(), prevent_id_clashes(), Inkscape::XML::rebase_hrefs(), Inkscape::GC::release(), Inkscape::Selection::set(), Inkscape::XML::Node::setAttribute(), sp_css_attr_from_object(), sp_document_ensure_up_to_date(), sp_item_i2doc_affine(), and sp_selection_apply_affine().

Referenced by Inkscape::UI::ClipboardManagerImpl::_pasteImage(), sp_file_import(), and sp_file_import_from_ocal().

{
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;

    //DEBUG_MESSAGE( fileImport, "file_import( in_doc:%p uri:[%s], key:%p", in_doc, uri, key );
    SPDocument *doc;
    try {
        doc = Inkscape::Extension::open(key, uri.c_str());
    } catch (Inkscape::Extension::Input::no_extension_found &e) {
        doc = NULL;
    } catch (Inkscape::Extension::Input::open_failed &e) {
        doc = NULL;
    }

    if (doc != NULL) {
        Inkscape::XML::rebase_hrefs(doc, in_doc->base, true);
        Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);

        prevent_id_clashes(doc, in_doc);

        SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
        Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();

        SPCSSAttr *style = sp_css_attr_from_object(SP_DOCUMENT_ROOT(doc));

        // Count the number of top-level items in the imported document.
        guint items_count = 0;
        for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
             child != NULL; child = SP_OBJECT_NEXT(child))
        {
            if (SP_IS_ITEM(child)) items_count++;
        }

        // Create a new group if necessary.
        Inkscape::XML::Node *newgroup = NULL;
        if ((style && style->firstChild()) || items_count > 1) {
            newgroup = xml_in_doc->createElement("svg:g");
            sp_repr_css_set(newgroup, style, "style");
        }

        // Determine the place to insert the new object.
        // This will be the current layer, if possible.
        // FIXME: If there's no desktop (command line run?) we need
        //        a document:: method to return the current layer.
        //        For now, we just use the root in this case.
        SPObject *place_to_insert;
        if (desktop) {
            place_to_insert = desktop->currentLayer();
        } else {
            place_to_insert = SP_DOCUMENT_ROOT(in_doc);
        }

        // Construct a new object representing the imported image,
        // and insert it into the current document.
        SPObject *new_obj = NULL;
        for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
             child != NULL; child = SP_OBJECT_NEXT(child) )
        {
            if (SP_IS_ITEM(child)) {
                Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(xml_in_doc);

                // convert layers to groups, and make sure they are unlocked
                // FIXME: add "preserve layers" mode where each layer from
                //        import is copied to the same-named layer in host
                newitem->setAttribute("inkscape:groupmode", NULL);
                newitem->setAttribute("sodipodi:insensitive", NULL);

                if (newgroup) newgroup->appendChild(newitem);
                else new_obj = place_to_insert->appendChildRepr(newitem);
            }

            // don't lose top-level defs or style elements
            else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
                const gchar *tag = SP_OBJECT_REPR(child)->name();
                if (!strcmp(tag, "svg:defs")) {
                    for (SPObject *x = sp_object_first_child(child);
                         x != NULL; x = SP_OBJECT_NEXT(x))
                    {
                        SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(x)->duplicate(xml_in_doc), last_def);
                    }
                }
                else if (!strcmp(tag, "svg:style")) {
                    SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(SP_OBJECT_REPR(child)->duplicate(xml_in_doc));
                }
            }
        }
        if (newgroup) new_obj = place_to_insert->appendChildRepr(newgroup);

        // release some stuff
        if (newgroup) Inkscape::GC::release(newgroup);
        if (style) sp_repr_css_attr_unref(style);

        // select and move the imported item
        if (new_obj && SP_IS_ITEM(new_obj)) {
            Inkscape::Selection *selection = sp_desktop_selection(desktop);
            selection->set(SP_ITEM(new_obj));

            // preserve parent and viewBox transformations
            // c2p is identity matrix at this point unless sp_document_ensure_up_to_date is called
            sp_document_ensure_up_to_date(doc);
            Geom::Matrix affine = SP_ROOT(SP_DOCUMENT_ROOT(doc))->c2p * sp_item_i2doc_affine(SP_ITEM(place_to_insert)).inverse();
            sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false);

            // move to mouse pointer
            {
                sp_document_ensure_up_to_date(sp_desktop_document(desktop));
                Geom::OptRect sel_bbox = selection->bounds();
                if (sel_bbox) {
                    Geom::Point m( desktop->point() - sel_bbox->midpoint() );
                    sp_selection_move_relative(selection, m, false);
                }
            }
        }

        sp_document_unref(doc);
        sp_document_done(in_doc, SP_VERB_FILE_IMPORT,
                         _("Import"));

    } else {
        gchar *text = g_strdup_printf(_("Failed to load the requested file %s"), uri.c_str());
        sp_ui_error_dialog(text);
        g_free(text);
    }

    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index