94 auto doc = app->document_new(templ);
96 std::cerr <<
"sp_file_new: failed to open document: " << templ << std::endl;
99 return app->desktopOpen(doc);
124 g_assert(doc !=
nullptr);
127 g_assert(repr !=
nullptr);
135 bool do_revert =
true;
137 Glib::ustring tmpString = Glib::ustring::compose(_(
"Changes will be lost! Are you sure you want to reload document %1?"), filename);
144 bool reverted =
false;
147 reverted = app->document_revert (doc);
176 ngettext(
"Removed <b>%i</b> unused definition in <defs>.",
177 "Removed <b>%i</b> unused definitions in <defs>.",
199 const Glib::RefPtr<Gio::File> file,
209 auto path = file->get_path();
210 auto display_name = file->get_parse_name();
216 checkoverwrite, official,
219 gchar *text = g_strdup_printf(_(
"No Inkscape extension found to save document (%s). This may have been caused by an unknown or missing filename extension."), display_name.c_str());
227 gchar *text = g_strdup_printf(_(
"File %s is write protected. Please remove write protection and try again."), display_name.c_str());
234 gchar *text = g_strdup_printf(_(
"File %s could not be saved."), display_name.c_str());
245 gchar *text = g_strdup_printf(_(
"File could not be saved:\nNo object with ID '%s' found."), e.id);
253 }
catch (std::exception &e) {
254 gchar *text = g_strdup_printf(_(
"File %s could not be saved.\n\n"
255 "The following additional information was returned by the output extension:\n"
256 "'%s'"), display_name.c_str(), e.what());
263 g_critical(
"Extension '%s' threw an unspecified exception.",
key ?
key->get_id() :
nullptr);
264 gchar *text = g_strdup_printf(_(
"File %s could not be saved."), display_name.c_str());
272 if (SP_ACTIVE_DESKTOP) {
273 if (! SP_ACTIVE_DESKTOP->messageStack()) {
274 g_message(
"file_save: ->messageStack() == NULL. please report to bug #967416");
277 g_message(
"file_save: SP_ACTIVE_DESKTOP == NULL. please report to bug #967416");
282 recently_used->prepend_to_list(font_lister->get_font_family());
283 recently_used->set_continuous_streak(
false);
288 msg = Glib::ustring::format(_(
"Document saved."));
309 std::string filename_extension =
".svg";
320 if (save_path.empty()) {
321 save_path = Glib::get_home_dir();
324 std::string save_loc = save_path;
325 save_loc.append(G_DIR_SEPARATOR_S);
330 save_loc = save_loc + _(
"drawing") + filename_extension;
333 save_loc = save_path;
334 save_loc.append(G_DIR_SEPARATOR_S);
335 save_loc = save_loc + Glib::ustring::compose(_(
"drawing-%1"), i++) + filename_extension;
342 const Glib::ustring dialog_title = is_copy ?
343 _(
"Select file to save a copy to") :
344 _(
"Select file to save to");
348 std::string basename = Glib::path_get_basename(save_loc);
349 std::string dirname = Glib::path_get_dirname(save_loc);
350 auto file = choose_file_save( dialog_title, &parentWindow,
375 for (
auto omod : extension_list) {
376 if (file_extension == omod->get_extension()) {
384 std::cerr <<
"sp_file_save_dialog(): Cannot find output module for file type: "
385 << file_extension <<
"!" << std::endl;
389 if (
file_save(parentWindow, doc, file, extension,
true, !is_copy, save_method)) {
392 Glib::RefPtr<Gtk::RecentManager> recent = Gtk::RecentManager::get_default();
393 recent->add_item(file->get_uri());
396 save_path = Glib::path_get_dirname(file->get_path());
426 std::string::size_type pos = path.rfind(
'.');
427 if (pos != std::string::npos) {
430 ext = path.substr( pos );
432 auto file = Gio::File::create_for_path(path);
434 if (success ==
false) {
442 msg = Glib::ustring::format(_(
"No changes need to be saved."));
459 if (!SP_ACTIVE_DOCUMENT) {
475 if (!SP_ACTIVE_DOCUMENT) {
489 if (!SP_ACTIVE_DOCUMENT) {
502 Glib::ustring author, Glib::ustring description, Glib::ustring keywords,
505 if (!SP_ACTIVE_DOCUMENT ||
name.length() == 0)
508 auto document = SP_ACTIVE_DOCUMENT;
510 DocumentUndo::ScopedInsensitive _no_undo(document);
512 auto root = document->getReprRoot();
513 auto xml_doc = document->getReprDoc();
515 auto templateinfo_node = xml_doc->createElement(
"inkscape:templateinfo");
518 auto element_node = xml_doc->createElement(
"inkscape:name");
521 element_node->appendChild(xml_doc->createTextNode(
name.c_str()));
522 templateinfo_node->appendChild(element_node);
524 if (author.length() != 0) {
526 element_node = xml_doc->createElement(
"inkscape:author");
529 element_node->appendChild(xml_doc->createTextNode(author.c_str()));
530 templateinfo_node->appendChild(element_node);
533 if (description.length() != 0) {
535 element_node = xml_doc->createElement(
"inkscape:shortdesc");
538 element_node->appendChild(xml_doc->createTextNode(description.c_str()));
539 templateinfo_node->appendChild(element_node);
543 element_node = xml_doc->createElement(
"inkscape:date");
546 element_node->appendChild(xml_doc->createTextNode(
547 Glib::DateTime::create_now_local().format(
"%F").c_str()));
548 templateinfo_node->appendChild(element_node);
550 if (keywords.length() != 0) {
552 element_node = xml_doc->createElement(
"inkscape:keywords");
555 element_node->appendChild(xml_doc->createTextNode(keywords.c_str()));
556 templateinfo_node->appendChild(element_node);
560 root->appendChild(templateinfo_node);
564 auto encodedName = Glib::uri_escape_string(
name,
" ",
true);
565 encodedName.append(
".svg");
571 auto file = Gio::File::create_for_path(path);
573 if (operation_confirmed) {
581 std::string default_svg_localized = std::string(
"default.") + _(
"en") +
".svg";
588 file = Gio::File::create_for_path(path);
596 root->removeChild(templateinfo_node);
598 return operation_confirmed;
629 if (node_after && prefs->
getBool(
"/options/paste/aboveselected",
true) && node_after != target_parent) {
630 target_parent = node_after->
parent();
633 for (
auto p = target_document->
getObjectByRepr(node_after->parent()); p; p = p->parent) {
634 if (
auto parent_group = cast<SPGroup>(p)) {
635 layer = parent_group;
648 std::vector<Inkscape::XML::Node*> pasted_objects;
651 if (!strcmp(obj->name(),
"svg:defs")) {
654 if (!strcmp(obj->name(),
"svg:metadata")) {
657 if (!strcmp(obj->name(),
"sodipodi:namedview")) {
660 if (!strcmp(obj->name(),
"inkscape:clipboard")) {
666 target_parent->
addChild(obj_copy, node_after);
667 node_after = obj_copy;
673 auto use = cast<SPUse>(spobject);
682 if (is<SPItem>(spobject)) {
683 pasted_objects.push_back(obj_copy);
687 std::vector<Inkscape::XML::Node*> pasted_objects_not;
700 layer->appendChildRepr(obj_copy);
702 pasted_objects_not.push_back(obj_copy);
714 auto pasted_lpe_item = cast<SPLPEItem>(
item);
715 if (pasted_lpe_item) {
748 }
else if (on_page && from_page && to_page) {
756 for (
auto po : pasted_objects) {
774 bool cancelled =
false;
786 std::unique_ptr<SPDocument> doc;
795 bool is_svg =
key && !strcmp(
key->get_id(), SP_MODULE_KEY_INPUT_SVG);
797 if (doc && is_svg && prefs->getString(
"/dialogs/import/import_mode_svg") ==
"new") {
800 auto doc_ptr = app->document_add(std::move(doc));
801 app->desktopOpen(doc_ptr);
817 if (doc->getPageManager().hasPages()) {
827 guint items_count = 0;
829 for (
auto&
child: doc->getRoot()->children) {
830 if (is<SPItem>(&
child)) {
837 bool did_ungroup =
false;
838 while(items_count==1 && o && is<SPGroup>(o) && o->
children.size()==1){
839 std::vector<SPItem *>v;
841 o = v.empty() ? nullptr : v[0];
848 if ((style && !al.empty()) || items_count > 1) {
862 place_to_insert = in_doc->
getRoot();
868 for (
auto&
child: doc->getRoot()->children) {
869 if (is<SPItem>(&
child)) {
885 if (!strcmp(tag,
"svg:style")) {
898 if (
auto new_item = cast<SPItem>(new_obj)) {
900 selection->
set(new_item);
904 doc->ensureUpToDate();
905 Geom::Affine affine = doc->getRoot()->c2p * cast<SPItem>(place_to_insert)->i2doc_affine().
inverse();
911 auto m = pointer_location.round() - sel_bbox->midpoint();
918 }
else if (!cancelled) {
919 gchar *text = g_strdup_printf(_(
"Failed to load the requested file %s"), path.c_str());
942 this_pm.enablePages();
945 for (
auto &that_page : that_pm.getPages()) {
946 auto this_page = this_pm.newDocumentPage(that_page->getDocumentRect() * tr);
948 this_page->copyFrom(that_page);
956 if (!strcmp(that_repr->name(),
"svg:defs") ||
957 !strcmp(that_repr->name(),
"svg:metadata") ||
958 !strcmp(that_repr->name(),
"sodipodi:namedview")) {
962 auto this_repr = that_repr->duplicate(this_doc->
getReprDoc());
963 this_root->addChild(this_repr, this_root->lastChild());
969 set.applyAffine(tr,
true,
false,
true);
3x3 matrix representing an affine transformation.
Affine inverse() const
Compute the inverse matrix.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
Translate inverse() const
Get the inverse translation.
static InkscapeApplication * instance()
Singleton instance.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
std::list< Output * > OutputList
OutputList & get_output_list(OutputList &ou_list)
Creates a list of all the Output extensions.
Extension * get(const gchar *key) const
This function looks up a Inkscape::Extension::Extension by using its unique id. It then returns a ref...
An error class for when a filename already exists, but the user doesn't want to overwrite it.
The object that is the basis for the Extension system.
The existing file can not be opened for writing.
Failed because we couldn't find an extension to match the filename.
Generic failure for an undescribed reason.
gchar const * get_extension() const
Get the filename extension for this extension.
static Inkscape::FontLister * get_instance()
SPGroup * currentLayer() const
Returns current top layer.
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
MessageId flashF(MessageType type, char const *format,...) G_GNUC_PRINTF(3
temporarily pushes a message onto the stack using printf-like formatting
SPItemRange items()
Returns a range of selected SPItems.
void setReprList(std::vector< XML::Node * > const &list)
Selects the objects with the same IDs as those in list.
void applyAffine(Geom::Affine const &affine, bool set_i2d=true, bool compensate=true, bool adjust_transf_center=true)
Apply matrix to the selection.
void moveRelative(const Geom::Point &move, bool compensate=true)
void deleteItems(bool skip_undo=false)
XML::Node * topRepr() const
The top-most item, or NULL if the selection is empty.
Geom::OptRect visualBounds() const
SPPage * getSelected() const
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
static RecentlyUsedFonts * get()
The set of selected SPObjects for a given document and layer model.
void set(XML::Node *repr)
Set the selection to an XML node's SPObject.
std::string const & str() const
Interface for refcounted XML nodes.
virtual Node * parent()=0
Get the parent of this node.
virtual Node * next()=0
Get the next sibling of this node.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
virtual void appendChild(Node *child)=0
Append a node as the last child of this node.
virtual char const * name() const =0
Get the name of the element node.
virtual const AttributeVector & attributeList() const =0
Get a list of the node's attributes.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
Change an attribute of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
virtual Node * firstChild()=0
Get the first child of this node.
Geom::Point getAttributePoint(Util::const_char_ptr key, Geom::Point default_value={}) const
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
void removeAttribute(Inkscape::Util::const_char_ptr key)
Remove an attribute of this node.
virtual Node * lastChild()=0
Get the last child of this node.
To do: update description of desktop.
SPDocument * getDocument() const
Inkscape::MessageStack * messageStack() const
Geom::Affine const & dt2doc() const
Geom::Point point() const
Returns the mouse point in desktop coordinates; if mouse is outside the canvas, returns the center of...
SPNamedView * getNamedView() const
Inkscape::Selection * getSelection() const
Inkscape::UI::Tools::ToolBase * getTool() const
Inkscape::LayerManager & layerManager()
Geom::Affine const & doc2dt() const
bool warnDialog(Glib::ustring const &text)
Typed SVG document implementation.
void importDefs(SPDocument *source)
Paste SVG defs from the document retrieved from the clipboard or imported document into the active do...
SPRoot * getRoot()
Returns our SPRoot.
char const * getDocumentBase() const
char const * getDocumentFilename() const
SPObject * getObjectById(std::string const &id) const
bool isModifiedSinceSave() const
Inkscape::EventLog * get_event_log()
Inkscape::XML::Node * getReprRoot()
unsigned int vacuumDocument()
Remove unused definitions etc.
Inkscape::PageManager & getPageManager()
void emitReconstructionFinish()
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
Geom::Scale getDocumentScale(bool computed=true) const
Returns document scale as defined by width/height (in pixels) and viewBox (real world to user-units).
Base class for visual SVG elements.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
char * title() const
Returns the title of this object, or NULL if there is none.
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
Geom::Rect getDesktopRect() const
Get the rectangle of the page, in desktop units.
struct SPRoot::@40 inkscape
void setup(SPDesktop const *desktop, bool snapindicator=true, SPObject const *item_to_ignore=nullptr, std::vector< Inkscape::SnapCandidatePoint > *unselected_nodes=nullptr)
Convenience shortcut when there is only one item to ignore.
Editable view implementation.
TODO: insert short description here.
void sp_file_fix_lpe(SPDocument *doc)
bool sp_file_save_template(Gtk::Window &parentWindow, Glib::ustring name, Glib::ustring author, Glib::ustring description, Glib::ustring keywords, bool isDefault)
Save a copy of a document as template.
void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place, bool on_page)
Paste the contents of a document into the active desktop.
void sp_file_vacuum(SPDocument *doc)
Remove unreferenced defs from the defs section of the document.
SPDesktop * sp_file_new_default()
void sp_file_revert_dialog()
Handle prompting user for "do you want to revert"? Revert on "OK".
void file_import_pages(SPDocument *this_doc, SPDocument *that_doc)
Import the given document as a set of multiple pages and append to this one.
std::string sp_file_default_template_uri()
bool sp_file_save_a_copy(Gtk::Window &parentWindow, gpointer, gpointer)
Save a copy of a document, always displaying a sort of SaveAs dialog.
bool sp_file_save(Gtk::Window &parentWindow, gpointer, gpointer)
Save a document.
SPDesktop * sp_file_new(const std::string &templ)
Create a blank document and add it to the desktop Input: empty string or template file name.
SPObject * file_import(SPDocument *in_doc, const std::string &path, Inkscape::Extension::Extension *key)
Import a resource.
static bool file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::RefPtr< Gio::File > file, Inkscape::Extension::Extension *key, bool checkoverwrite, bool official, Inkscape::Extension::FileSaveMethod save_method)
This 'save' function called by the others below.
bool sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, Inkscape::Extension::FileSaveMethod save_method)
Display a SaveAs dialog.
void sp_file_print(Gtk::Window &parentWindow)
Print the current document, if any.
bool sp_file_save_document(Gtk::Window &parentWindow, SPDocument *doc)
Save a document, displaying a SaveAs dialog if necessary.
bool sp_file_save_as(Gtk::Window &parentWindow, gpointer, gpointer)
Save a document, always displaying the SaveAs dialog.
Macro for icon names used in Inkscape.
void prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc, bool from_clipboard)
This function resolves ID clashes between the document being imported and the current open document: ...
TODO: insert short description here.
Mini static library that contains the version of Inkscape.
Inkscape - An SVG editor.
void sp_ui_error_dialog(char const *message)
bool sp_ui_overwrite_file(std::string const &filename)
If necessary, ask the user if a file may be overwritten.
Raw stack of active status messages.
DB db
This is the actual database object.
Glib::ustring get_file_save_extension(Inkscape::Extension::FileSaveMethod method)
Determine the desired default file extension depending on the given file save method.
std::unique_ptr< SPDocument > open(Extension *key, char const *filename, bool is_importing)
This is a generic function to use the open function of a module (including Autodetect)
void save(Extension *key, SPDocument *doc, gchar const *filename, bool check_overwrite, bool official, Inkscape::Extension::FileSaveMethod save_method)
This is a generic function to use the save function of a module (including Autodetect)
void store_save_path_in_prefs(Glib::ustring path, FileSaveMethod method)
Write the given path back to prefs so that it can be used later on.
FileSaveMethod
Used to distinguish between the various invocations of the save dialogs (and thus to determine the fi...
@ FILE_SAVE_METHOD_SAVE_COPY
@ FILE_SAVE_METHOD_INKSCAPE_SVG
@ FILE_SAVE_METHOD_SAVE_AS
Glib::ustring get_file_save_path(SPDocument *doc, FileSaveMethod method)
Determine the desired default save path depending on the given FileSaveMethod.
static R & release(R &r)
Decrements the reference count of a anchored object.
std::string get_path_string(Domain domain, Type type, char const *filename, char const *extra)
std::string get_filename(Type type, char const *filename, bool localized, bool silent)
Glib::ustring get_file_extension(Glib::ustring const &path)
bool file_test(char const *utf8name, GFileTest test)
Glib::RefPtr< Gio::ListStore< Gtk::FileFilter > > create_export_filters(bool for_save)
Create a Gtk::FileFilter for all export file types.
void rebase_hrefs(Inkscape::XML::Node *rootxml, gchar const *const old_base, gchar const *const new_base, bool const spns)
Change relative hrefs in current root XML node (faster than full document generation)
@ ELEMENT_NODE
Regular element node, e.g. <group />.
char const * version_string
full version string
static cairo_user_data_key_t key
TODO: insert short description here.
void sp_print_document(Gtk::Window &parentWindow, SPDocument *doc)
unsigned int rdf_set_work_entity(SPDocument *doc, struct rdf_work_entity_t *entity, const gchar *text)
struct rdf_work_entity_t * rdf_find_entity(gchar const *name)
Retrieves a known RDF/Work entity by name.
TODO: insert short description here.
void sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr)
Sets an attribute (e.g.
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
Inkscape::XML::Node const * sp_repr_lookup_name(Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth)
Inkscape::IO::Resource - simple resource API.
SPCSSAttr - interface for CSS Attributes.
void sp_item_group_ungroup(SPGroup *group, std::vector< SPItem * > &children)
void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable)
void sp_namedview_document_from_window(SPDesktop *desktop)
SPRoot: SVG <svg> implementation.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
SPCSSAttr * sp_css_attr_from_object(SPObject *object, guint const flags)
SPStyle - a style object for SPItem objects.
std::string sp_svg_transform_write(Geom::Affine const &transform)