summaryrefslogtreecommitdiffstats
path: root/src/io/file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/file.cpp')
-rw-r--r--src/io/file.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/io/file.cpp b/src/io/file.cpp
new file mode 100644
index 0000000..4c509dc
--- /dev/null
+++ b/src/io/file.cpp
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * File operations (independent of GUI)
+ *
+ * Copyright (C) 2018, 2019 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include "io/file.h"
+
+#include <iostream>
+#include <unistd.h>
+#include <giomm.h>
+
+#include "document.h"
+#include "document-undo.h"
+
+#include "extension/system.h" // Extension::open()
+#include "extension/extension.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "extension/input.h"
+
+#include "object/sp-root.h"
+
+#include "xml/repr.h"
+
+
+/**
+ * Create a blank document, remove any template data.
+ * Input: Empty string or template file name.
+ */
+SPDocument*
+ink_file_new(const std::string &Template)
+{
+ SPDocument *doc = SPDocument::createNewDoc ((Template.empty() ? nullptr : Template.c_str()), true, true );
+
+ if (doc) {
+ // Remove all the template info from xml tree
+ Inkscape::XML::Node *myRoot = doc->getReprRoot();
+ Inkscape::XML::Node *nodeToRemove;
+
+ nodeToRemove = sp_repr_lookup_name(myRoot, "inkscape:templateinfo");
+ if (nodeToRemove != nullptr) {
+ Inkscape::DocumentUndo::ScopedInsensitive no_undo(doc);
+ sp_repr_unparent(nodeToRemove);
+ delete nodeToRemove;
+ }
+ nodeToRemove = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo"); // backwards-compatibility
+ if (nodeToRemove != nullptr) {
+ Inkscape::DocumentUndo::ScopedInsensitive no_undo(doc);
+ sp_repr_unparent(nodeToRemove);
+ delete nodeToRemove;
+ }
+ } else {
+ std::cerr << "ink_file_new: Did not create new document!" << std::endl;
+ }
+
+ return doc;
+}
+
+/**
+ * Open a document from memory.
+ */
+SPDocument*
+ink_file_open(const Glib::ustring& data)
+{
+ SPDocument *doc = SPDocument::createNewDocFromMem (data.c_str(), data.length(), true);
+
+ if (doc == nullptr) {
+ std::cerr << "ink_file_open: cannot open file in memory (pipe?)" << std::endl;
+ } else {
+
+ // This is the only place original values should be set.
+ SPRoot *root = doc->getRoot();
+ root->original.inkscape = root->version.inkscape;
+ root->original.svg = root->version.svg;
+ }
+
+ return doc;
+}
+
+/**
+ * Open a document.
+ */
+SPDocument*
+ink_file_open(const Glib::RefPtr<Gio::File>& file, bool *cancelled_param)
+{
+ bool cancelled = false;
+
+ SPDocument *doc = nullptr;
+
+ std::string path = file->get_path();
+
+ // TODO: It's useless to catch these exceptions here (and below) unless we do something with them.
+ // If we can't properly handle them (e.g. by showing a user-visible message) don't catch them!
+ try {
+ doc = Inkscape::Extension::open(nullptr, path.c_str());
+ } catch (Inkscape::Extension::Input::no_extension_found &e) {
+ doc = nullptr;
+ } catch (Inkscape::Extension::Input::open_failed &e) {
+ doc = nullptr;
+ } catch (Inkscape::Extension::Input::open_cancelled &e) {
+ cancelled = true;
+ doc = nullptr;
+ }
+
+ // Try to open explicitly as SVG.
+ // TODO: Why is this necessary? Shouldn't this be handled by the first call already?
+ if (doc == nullptr && !cancelled) {
+ try {
+ doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), path.c_str());
+ } catch (Inkscape::Extension::Input::no_extension_found &e) {
+ doc = nullptr;
+ } catch (Inkscape::Extension::Input::open_failed &e) {
+ doc = nullptr;
+ } catch (Inkscape::Extension::Input::open_cancelled &e) {
+ cancelled = true;
+ doc = nullptr;
+ }
+ }
+
+ if (doc != nullptr) {
+ // This is the only place original values should be set.
+ SPRoot *root = doc->getRoot();
+ root->original.inkscape = root->version.inkscape;
+ root->original.svg = root->version.svg;
+ } else if (!cancelled) {
+ std::cerr << "ink_file_open: '" << path << "' cannot be opened!" << std::endl;
+ }
+
+ if (cancelled_param) {
+ *cancelled_param = cancelled;
+ }
+ return doc;
+}
+
+namespace Inkscape {
+namespace IO {
+
+/**
+ * Create a temporary filename, which is closed and deleted when deconstructed.
+ */
+TempFilename::TempFilename(const std::string &pattern)
+ : _filename("")
+ , _tempfd(0)
+{
+ try {
+ _tempfd = Glib::file_open_tmp(_filename, pattern.c_str());
+ } catch (...) {
+ /// \todo Popup dialog here
+ return;
+ }
+}
+
+TempFilename::~TempFilename()
+{
+ close(_tempfd);
+ unlink(_filename.c_str());
+}
+
+/**
+ * Takes an absolute file path and returns a second file at the same
+ * directory location, if and only if the filename exists and is a file.
+ *
+ * Returns the empty string if the new file is not found.
+ */
+Glib::ustring find_original_file(Glib::ustring filepath, Glib::ustring name)
+{
+ auto path = Glib::path_get_dirname(filepath);
+ auto filename = Glib::build_filename(path, name);
+
+ if (Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR)) {
+ return filename;
+ }
+ return "";
+}
+
+}}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :