Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
file.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * File operations (independent of GUI)
4 *
5 * Copyright (C) 2018, 2019 Tavmjong Bah
6 *
7 * The contents of this file may be used under the GNU General Public License Version 2 or later.
8 *
9 */
10
11#include "io/file.h"
12
13#include <iostream>
14#include <memory>
15#include <unistd.h>
16#include <glibmm/fileutils.h>
17#include <glibmm/miscutils.h>
18#include <giomm/file.h>
19
20#include "document.h"
21#include "document-undo.h"
22#include "extension/system.h" // Extension::open()
23#include "extension/extension.h"
24#include "extension/db.h"
25#include "extension/output.h"
26#include "extension/input.h"
27#include "object/sp-root.h"
28#include "xml/repr.h"
29
34std::unique_ptr<SPDocument> ink_file_new(std::string const &Template)
35{
36 auto doc = SPDocument::createNewDoc(Template.empty() ? nullptr : Template.c_str(), true, true);
37
38 if (!doc) {
39 std::cerr << "ink_file_new: Did not create new document!" << std::endl;
40 return nullptr;
41 }
42
43 // Remove all the template info from xml tree
44 Inkscape::XML::Node *myRoot = doc->getReprRoot();
45 for (auto const name: {"inkscape:templateinfo",
46 "inkscape:_templateinfo"}) // backwards-compatibility
47 {
48 if (auto node = std::unique_ptr<Inkscape::XML::Node>{sp_repr_lookup_name(myRoot, name)}) {
51 }
52 }
53
54 return doc;
55}
56
57namespace {
58void set_inkscape_and_svg_versions(SPRoot *root)
59{
60 // This is the only place original values should be set.
61 if (root->inkscape.version) {
62 root->inkscape.original = *root->inkscape.version;
63 }
64 if (root->svg.version) {
65 root->svg.original = *root->svg.version;
66 }
67}
68} // namespace
69
73std::unique_ptr<SPDocument> ink_file_open(std::span<char const> buffer)
74{
75 auto doc = SPDocument::createNewDocFromMem(buffer, true);
76
77 if (!doc) {
78 std::cerr << "ink_file_open: cannot open file in memory (pipe?)" << std::endl;
79 return nullptr;
80 }
81 set_inkscape_and_svg_versions(doc->getRoot());
82 return doc;
83}
84
88std::pair<std::unique_ptr<SPDocument>, bool> ink_file_open(Glib::RefPtr<Gio::File> const &file)
89{
90 std::unique_ptr<SPDocument> doc;
91 std::string path = file->get_path();
92
93 // TODO: It's useless to catch these exceptions here (and below) unless we do something with them.
94 // If we can't properly handle them (e.g. by showing a user-visible message) don't catch them!
95 try {
96 doc = Inkscape::Extension::open(nullptr, path.c_str());
100 return {nullptr, true};
101 }
102
103 // Try to open explicitly as SVG.
104 // TODO: Why is this necessary? Shouldn't this be handled by the first call already?
105 if (!doc) {
106 try {
107 doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), path.c_str());
111 return {nullptr, true};
112 }
113 }
114
115 if (!doc) {
116 std::cerr << "ink_file_open: '" << path << "' cannot be opened!" << std::endl;
117 return {nullptr, false};
118 }
119
120 set_inkscape_and_svg_versions(doc->getRoot());
121 return {std::move(doc), false};
122}
123
124namespace Inkscape::IO {
125
129TempFilename::TempFilename(const std::string &pattern)
130{
131 try {
132 _tempfd = Glib::file_open_tmp(_filename, pattern.c_str());
133 } catch (...) {
135 }
136}
137
139{
140 close(_tempfd);
141 unlink(_filename.c_str());
142}
143
150std::string find_original_file(Glib::StdStringView const filepath, Glib::StdStringView const name)
151{
152 auto path = Glib::path_get_dirname(filepath);
153 auto filename = Glib::build_filename(path, name);
154 if (Glib::file_test(filename, Glib::FileTest::IS_REGULAR)) {
155 return filename;
156 }
157 return "";
158}
159
160} // namespace Inkscape::IO
161
162/*
163 Local Variables:
164 mode:c++
165 c-file-style:"stroustrup"
166 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
167 indent-tabs-mode:nil
168 fill-column:99
169 End:
170*/
171// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
RAII-style mechanism for creating a temporary undo-insensitive context.
TempFilename(const std::string &pattern)
Create a temporary filename, which is closed and deleted when deconstructed.
Definition file.cpp:129
std::string _filename
Definition file.h:40
Interface for refcounted XML nodes.
Definition node.h:80
static std::unique_ptr< SPDocument > createNewDocFromMem(std::span< char const > buffer, bool keepalive, std::string const &filename="")
Definition document.cpp:718
static std::unique_ptr< SPDocument > createNewDoc(char const *filename, bool keepalive, bool make_new=false, SPDocument *parent=nullptr)
Fetches document from filename, or creates new, if NULL; public document appears in document list.
Definition document.cpp:668
<svg> element
Definition sp-root.h:33
RootCluster root
TODO: insert short description here.
Inkscape::Extension::Extension: Frontend to certain, possibly pluggable, actions.
Inkscape::XML::Node * node
std::unique_ptr< SPDocument > ink_file_open(std::span< char const > buffer)
Open a document from memory.
Definition file.cpp:73
std::unique_ptr< SPDocument > ink_file_new(std::string const &Template)
Create a blank document, remove any template data.
Definition file.cpp:34
DB db
This is the actual database object.
Definition db.cpp:32
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)
Definition system.cpp:66
Low-level IO code.
std::string find_original_file(Glib::StdStringView const filepath, Glib::StdStringView const name)
Takes an absolute file path and returns a second file at the same directory location,...
Definition file.cpp:150
Inkscape::XML::Node const * sp_repr_lookup_name(Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth)
C facade to Inkscape::XML::Node.
void sp_repr_unparent(Inkscape::XML::Node *repr)
Remove repr from children of its parent node.
Definition repr.h:107
SPRoot: SVG <svg> implementation.
Glib::ustring name
Definition toolbars.cpp:55