summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/document.cpp25
-rw-r--r--src/document.h1
-rw-r--r--src/extension/dbus/document-interface.cpp15
-rw-r--r--src/file-update.cpp45
-rw-r--r--src/file.cpp155
-rw-r--r--src/file.h11
-rw-r--r--src/help.cpp7
-rw-r--r--src/inkscape-application.cpp508
-rw-r--r--src/inkscape-application.h33
-rw-r--r--src/inkscape-window.cpp7
-rw-r--r--src/io/file.cpp105
-rw-r--r--src/io/file.h2
-rw-r--r--src/io/resource-manager.cpp7
-rw-r--r--src/ui/desktop/menubar.cpp9
-rw-r--r--src/ui/interface.cpp53
-rw-r--r--src/ui/view/view.cpp4
16 files changed, 632 insertions, 355 deletions
diff --git a/src/document.cpp b/src/document.cpp
index a6ad44c9d..1fc32d8a0 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -216,7 +216,6 @@ SPDocument::~SPDocument() {
// This is at the end of the destructor, because preceding code adds new orphans to the queue
collectOrphans();
-
}
sigc::connection SPDocument::connectDestroy(sigc::signal<void>::slot_type slot)
@@ -460,6 +459,10 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
));
document->oldSignalsConnected = true;
+
+ // ************* Fix Document **************
+ // Move to separate function?
+
/** Fix baseline spacing (pre-92 files) **/
if ( (!sp_no_convert_text_baseline_spacing)
&& sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) {
@@ -471,11 +474,17 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
sp_file_convert_font_name(document);
}
- /** Fix dpi (pre-92 files) **/
+ /** Fix dpi (pre-92 files). With GUI fixed in Inkscape::Application::fix_document. **/
if ( !(INKSCAPE.use_gui()) && sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) {
sp_file_convert_dpi(document);
}
+ // Update LPE's See: Related bug:#1769679 #18
+ SPDefs * defs = document->getDefs();
+ if (defs) {
+ defs->emitModified(SP_OBJECT_MODIFIED_CASCADE);
+ }
+
return document;
}
@@ -513,7 +522,6 @@ SPDocument *SPDocument::createChildDoc(std::string const &document_uri)
} else {
path = document_uri;
}
- std::cout << "Added document_base: '" << path << std::endl;
document = createNewDoc(path.c_str(), false, false, this);
}
return document;
@@ -782,6 +790,17 @@ Geom::Rect SPDocument::getViewBox() const
return viewBox;
}
+/**
+ * Set default viewbox calculated from document properties.
+ */
+void SPDocument::setViewBox()
+{
+ setViewBox(Geom::Rect(0,
+ 0,
+ getWidth().value(getDisplayUnit()),
+ getHeight().value(getDisplayUnit())));
+}
+
void SPDocument::setViewBox(const Geom::Rect &viewBox)
{
root->viewBox_set = true;
diff --git a/src/document.h b/src/document.h
index 2c8a8f5ce..b3fa7da4d 100644
--- a/src/document.h
+++ b/src/document.h
@@ -284,6 +284,7 @@ public:
void setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize=true);
void setWidth(const Inkscape::Util::Quantity &width, bool changeSize=true);
void setHeight(const Inkscape::Util::Quantity &height, bool changeSize=true);
+ void setViewBox();
void setViewBox(const Geom::Rect &viewBox);
void requestModified();
int ensureUpToDate();
diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp
index bb888d4e2..a22585cb4 100644
--- a/src/extension/dbus/document-interface.cpp
+++ b/src/extension/dbus/document-interface.cpp
@@ -20,9 +20,9 @@
#include <string.h>
#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib.h>
//#include "2geom/svg-path-parser.h" //get_node_coordinates
+#include "inkscape-application.h" // create_window()
#include "application-interface.h"
#include "desktop-style.h" //sp_desktop_get_style
@@ -930,12 +930,21 @@ document_interface_save (DocumentInterface *doc_interface, GError **error)
gboolean document_interface_load(DocumentInterface *doc_interface,
gchar *filename, GError ** /*error*/)
{
+ if (!filename) {
+ return false;
+ }
+
SPDesktop *desk = doc_interface->target.getDesktop();
if (desk) {
desktop_ensure_active(desk);
}
- const Glib::ustring file(filename);
- sp_file_open(file, NULL, TRUE, TRUE);
+
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename);
+
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
+ app->create_window(file);
+
if (doc_interface->updates) {
Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), SP_VERB_FILE_OPEN, "Opened File");
}
diff --git a/src/file-update.cpp b/src/file-update.cpp
index f35107e2d..5489ee499 100644
--- a/src/file-update.cpp
+++ b/src/file-update.cpp
@@ -492,51 +492,8 @@ void sp_file_convert_dpi(SPDocument *doc)
prefs->setBool("/options/transform/gradient", transform_gradient);
did_scaling = true;
-/*
-
-// There used to be 2 "experimental" scaling methods in trunk. Considering that the method in .92.x appear to work, so I'm commenting those.
-
- // Save preferences
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true);
- bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
-
- prefs->setBool("/options/kbselection/onlysensitive", false);
- prefs->setBool("/options/kbselection/onlyvisible", false);
-
- Inkscape::Selection *selection = desktop->getSelection();
- Inkscape::SelectionHelper::selectAllInAll( desktop );
-
-//method 1 ...
- selection->group();
- SPItem * group = selection->singleItem();
- if (group) {
- group->setAttribute("transform","scale(1.06666667,1.06666667)");
- } else {
- std::cerr << "sp_file_open: Failed to get group!" << std::endl;
- }
- selection->clear();
- selection->add( group );
- selection->ungroup();
-
-// OR method 2...
-
- double height = root->height.computed;
- selection->setScaleRelative( Geom::Point(0,height), Geom::Scale(96.0/90.0,96.0/90.0) );
-
-... end method 2
-
- selection->clear();
-
- prefs->setBool("/options/kbselection/onlysensitive", onlysensitive);
- prefs->setBool("/options/kbselection/onlyvisible", onlyvisible );
-
- did_scaling = true;
-*/
-
-
-
}
+
} else { // FILE_DPI_UNCHANGED
if (need_fix_units)
need_fix_grid_mm = true;
diff --git a/src/file.cpp b/src/file.cpp
index b23ed2185..74bf9c162 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -35,6 +35,7 @@
#include <gtkmm.h>
#include "file.h"
+#include "inkscape-application.h"
#include "inkscape-window.h"
#include "desktop.h"
@@ -123,38 +124,24 @@ static void sp_file_add_recent(gchar const *uri)
/**
* Create a blank document and add it to the desktop
+ * Input: empty string or template file name.
*/
SPDesktop *sp_file_new(const std::string &templ)
{
- SPDocument *doc = SPDocument::createNewDoc( !templ.empty() ? templ.c_str() : nullptr , TRUE, true );
- g_return_val_if_fail(doc != nullptr, NULL);
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
- // Remove all the template info from xml tree
- Inkscape::XML::Node *myRoot = doc->getReprRoot();
- Inkscape::XML::Node *nodeToRemove = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo");
- if (nodeToRemove != nullptr){
- DocumentUndo::setUndoSensitive(doc, false);
- sp_repr_unparent(nodeToRemove);
- delete nodeToRemove;
- DocumentUndo::setUndoSensitive(doc, true);
+ SPDocument* doc = app->document_new (templ);
+ if (!doc) {
+ std::cerr << "sp_file_new: failed to open document: " << templ << std::endl;
}
+ InkscapeWindow* win = app->window_open (doc);
- SPDesktop *olddesktop = SP_ACTIVE_DESKTOP;
- if (olddesktop)
- olddesktop->setWaitingCursor();
-
- InkscapeWindow* win = new InkscapeWindow(doc);
SPDesktop* desktop = win->get_desktop();
#ifdef WITH_DBUS
Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop);
#endif
- if (olddesktop)
- olddesktop->clearWaitingCursor();
- if (desktop)
- desktop->clearWaitingCursor();
-
return desktop;
}
@@ -194,105 +181,6 @@ sp_file_exit()
-/*######################
-## O P E N
-######################*/
-
-/**
- * Open a file, add the document to the desktop
- *
- * \param replace_empty if true, and the current desktop is empty, this document
- * will replace the empty one.
- */
-bool sp_file_open(const Glib::ustring &uri,
- Inkscape::Extension::Extension *key,
- bool add_to_recent,
- bool replace_empty)
-{
- if (!INKSCAPE.use_gui()) {
- std::cerr << "sp_file_open requires GUI, use ink_file_open() instead." << std::endl;
- return false;
- }
-
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if (desktop) {
- desktop->setWaitingCursor();
- }
-
- bool cancelled = false;
- Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(uri);
- SPDocument* doc = ink_file_open(file, cancelled);
-
- if (desktop) {
- desktop->clearWaitingCursor();
- }
-
- if (doc) {
-
- SPDocument *existing = desktop ? desktop->getDocument() : nullptr;
-
- if (existing && existing->virgin && replace_empty) {
-
- // If the current desktop is empty, open the document there
- doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc.
- desktop->change_document(doc);
- doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px"));
- } else {
-
- InkscapeWindow* win = new InkscapeWindow(doc);
- desktop = win->get_desktop();
- }
-
- doc->virgin = FALSE;
-
- if (add_to_recent) {
- sp_file_add_recent( doc->getDocumentURI() );
- }
-
- // --------------- Fix up document ----------------
-
- // Fix DPI (90->96)
- if (sp_version_inside_range(doc->getRoot()->version.inkscape, 0, 1, 0, 92)) {
- sp_file_convert_dpi(doc);
- }
-
- // Perform a fixup pass for hrefs.
- if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) {
- Glib::ustring msg = _("Broken links have been changed to point to existing files.");
- desktop->showInfoDialog(msg);
- }
-
- // Check for font substitutions
- Inkscape::UI::Dialog::FontSubstitution::getInstance().checkFontSubstitutions(doc);
-
- // Update LPE's See: Related bug:#1769679 #18
- SPDefs * defs = dynamic_cast<SPDefs *>(doc->getDefs());
- if (defs && !existing) {
- defs->emitModified(SP_OBJECT_MODIFIED_CASCADE);
- }
-
- // ------------------ Window options ---------------
-
- // Lock Guides
- SPNamedView *nv = desktop->namedview;
- if (nv->lockguides) {
- nv->lockGuides();
- }
-
- return true;
-
- } else if (!cancelled) {
- gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str());
- gchar *text = g_strdup_printf(_("Failed to load the requested file %s"), safeUri);
- sp_ui_error_dialog(text);
- g_free(text);
- g_free(safeUri);
- return false;
- }
-
- return false;
-}
-
/**
* Handle prompting user for "do you want to revert"? Revert on "OK"
*/
@@ -322,22 +210,10 @@ void sp_file_revert_dialog()
}
}
- bool reverted;
+ bool reverted = false;
if (do_revert) {
- // Allow overwriting of current document.
- doc->virgin = TRUE;
-
- // remember current zoom and view
- double zoom = desktop->current_zoom();
- Geom::Point c = desktop->get_display_area().midpoint();
-
- reverted = sp_file_open(uri,nullptr);
- if (reverted) {
- // restore zoom and view
- desktop->zoom_absolute_center_point(c, zoom);
- }
- } else {
- reverted = false;
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+ reverted = app->document_revert (doc);
}
if (reverted) {
@@ -507,6 +383,8 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
return;
}
+ // FIXME: This is silly to have separate code paths for opening one vs many files!
+
//# User selected something. Get name and type
Glib::ustring fileName = openDialogInstance->getFilename();
@@ -520,6 +398,8 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
delete openDialogInstance;
openDialogInstance = nullptr;
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
//# Iterate through filenames if more than 1
if (flist.size() > 1)
{
@@ -536,7 +416,9 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
#ifdef INK_DUMP_FILENAME_CONV
g_message("Opening File %s\n", fileName.c_str());
#endif
- sp_file_open(fileName, fileType);
+
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(fileName);
+ app->create_window (file);
}
return;
@@ -556,7 +438,8 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
open_path.append(G_DIR_SEPARATOR_S);
prefs->setString("/dialogs/open/path", open_path);
- sp_file_open(fileName, fileType);
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(fileName);
+ app->create_window (file);
}
return;
diff --git a/src/file.h b/src/file.h
index 183233a1b..fc0925b78 100644
--- a/src/file.h
+++ b/src/file.h
@@ -62,17 +62,6 @@ void sp_file_exit ();
######################*/
/**
- * Opens a new file and window from the given URI
- */
-
-bool sp_file_open(
- const Glib::ustring &uri,
- Inkscape::Extension::Extension *key,
- bool add_to_recent = true,
- bool replace_empty = true
- );
-
-/**
* Displays a file open dialog. Calls sp_file_open on
* an OK.
*/
diff --git a/src/help.cpp b/src/help.cpp
index a32f8529a..5bfa282a9 100644
--- a/src/help.cpp
+++ b/src/help.cpp
@@ -15,7 +15,8 @@
#include <glibmm.h>
#include <glibmm/i18n.h>
-#include "file.h"
+#include "inkscape-application.h"
+
#include "help.h"
#include "io/resource.h"
#include "io/sys.h"
@@ -38,7 +39,9 @@ void sp_help_open_tutorial(Glib::ustring name)
filename = get_filename(TUTORIALS, filename.c_str(), true);
if (!filename.empty()) {
- sp_file_open(filename.c_str(), nullptr, false, false);
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename);
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+ app->create_window(file, false, false);
} else {
sp_ui_error_dialog(_("The tutorial files are not installed.\nFor Linux, you may need to install "
"'inkscape-tutorials'; for Windows, please re-run the setup and select 'Tutorials'.\nThe "
diff --git a/src/inkscape-application.cpp b/src/inkscape-application.cpp
index 6c6bd4ba4..e88dba707 100644
--- a/src/inkscape-application.cpp
+++ b/src/inkscape-application.cpp
@@ -16,11 +16,22 @@
#include "inkscape-window.h"
#include "inkscape.h" // Inkscape::Application
+#include "desktop.h" // Access to window
+#include "file.h" // sp_file_convert_dpi
+
#include "inkgc/gc-core.h" // Garbage Collecting init
-#include "ui/widget/panel.h" // Panel prep
-#include "file.h" // File open and window creation.
+
#include "io/file.h" // File open (command line).
-#include "desktop.h" // Access to window
+#include "io/resource.h" // TEMPLATE
+#include "io/resource-manager.h" // Fix up references.
+
+#include "object/sp-root.h" // Inkscape version.
+
+#include "ui/dialog/font-substitution.h" // Warn user about font substitution.
+#include "ui/widget/panel.h" // Panel prep
+#include "widgets/desktop-widget.h" // Close without saving dialog
+
+#include "util/units.h" // Redimension window
#include "actions/actions-base.h" // Actions
#include "actions/actions-output.h" // Actions
@@ -53,61 +64,254 @@ InkscapeApplication::InkscapeApplication()
, _active_view(nullptr)
{}
- // Open a document, add it to app.
+// Add document to app.
+void
+InkscapeApplication::document_add(SPDocument* document)
+{
+ if (document) {
+ auto it = _documents.find(document);
+ if (it == _documents.end()) {
+ _documents[document] = std::vector<InkscapeWindow*>();
+ } else {
+ // Should never happen.
+ std::cerr << "InkscapeApplication::add_document: Document already opened!" << std::endl;
+ }
+ } else {
+ // Should never happen!
+ std::cerr << "InkscapeApplication::add_document: No document!" << std::endl;
+ }
+}
+
+// New document, add it to app. TODO: This should really be open_document with option to strip template data.
+SPDocument*
+InkscapeApplication::document_new(const std::string &Template)
+{
+ // Open file
+ SPDocument *document = ink_file_new(Template);
+ if (document) {
+ document_add(document);
+
+ // Set viewBox if it doesn't exist.
+ if (!document->getRoot()->viewBox_set) {
+ document->setViewBox();
+ }
+
+ } else {
+ std::cerr << "InkscapeApplication::new_document: failed to open new document!" << std::endl;
+ }
+
+ return document;
+}
+
+
+// Open a document, add it to app.
SPDocument*
-InkscapeApplication::open_document(const Glib::RefPtr<Gio::File>& file)
+InkscapeApplication::document_open(const Glib::RefPtr<Gio::File>& file)
{
// Open file
bool cancelled = false;
SPDocument *document = ink_file_open(file, cancelled);
if (document) {
- auto it = _documents.find(document);
- if (it == _documents.end()) {
- _documents[document] = std::vector<InkscapeWindow*>();
+ document->virgin = false; // Prevents replacing document in same window during file open.
+
+ document_add (document);
+ } else {
+ std::cerr << "InkscapeApplication::open_document: Failed to open: " << file->get_parse_name() << std::endl;
+ }
+
+ return document;
+}
+
+
+/** Swap out one document for another in a window... maybe this should disappear.
+ * Does not delete old document!
+ */
+bool
+InkscapeApplication::document_swap(InkscapeWindow* window, SPDocument* document)
+{
+ if (!document || !window) {
+ std::cerr << "InkscapeAppliation::swap_document: Missing window or document!" << std::endl;
+ return false;
+ }
+
+ SPDesktop* desktop = window->get_desktop();
+ SPDocument* old_document = window->get_document();
+ desktop->change_document(document);
+ document->emitResizedSignal(document->getWidth().value("px"), document->getHeight().value("px"));
+
+ // We need to move window from the old document to the new document.
+
+ // Find old document
+ auto it = _documents.find(old_document);
+ if (it != _documents.end()) {
+
+ // Remove window from document map.
+ auto it2 = std::find(it->second.begin(), it->second.end(), window);
+ if (it2 != it->second.end()) {
+ it->second.erase(it2);
} else {
- std::cerr << "ConcreteInkscapeApplication<T>::open_document: Document already opened: " << file->get_parse_name() << std::endl;
+ std::cerr << "InkscapeApplication::swap_document: Window not found!" << std::endl;
}
+
} else {
- std::cerr << "ConcreteInkscapeApplication<T>::open_document: Failed to open: " << file->get_parse_name() << std::endl;
+ std::cerr << "InkscapeApplication::swap_document: Document not in map!" << std::endl;
}
- return document;
+ // Find new document
+ it = _documents.find(document);
+ if (it != _documents.end()) {
+ it->second.push_back(window);
+ } else {
+ std::cerr << "InkscapeApplication::swap_document: Document not in map!" << std::endl;
+ }
+
+ // To be removed (add/delete once per window)!
+ INKSCAPE.add_document(document);
+ INKSCAPE.remove_document(old_document);
+
+ // ActionContext should be removed once verbs are gone but we use it for now.
+ Inkscape::ActionContext context = INKSCAPE.action_context_for_document(document);
+ _active_document = document;
+ _active_selection = context.getSelection();
+ _active_view = context.getView();
+
+ return true;
+}
+
+/** Revert document: open saved document and swap it for each window.
+ */
+bool
+InkscapeApplication::document_revert(SPDocument* document)
+{
+ // Find saved document.
+ gchar const *path = document->getDocumentURI();
+ if (!path) {
+ std::cerr << "InkscapeApplication::revert_document: Document never saved, cannot revert." << std::endl;
+ return false;
+ }
+
+ // Open saved document.
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(document->getDocumentURI());
+ SPDocument* new_document = document_open (file);
+ if (!new_document) {
+ std::cerr << "InkscapeApplication::revert_document: Cannot open saved document!" << std::endl;
+ return false;
+ }
+
+ // Allow overwriting current document.
+ document->virgin = true;
+
+ auto it = _documents.find(document);
+ if (it != _documents.end()) {
+
+ // Swap reverted document in all windows.
+ for (auto it2 : it->second) {
+
+ SPDesktop* desktop = it2->get_desktop();
+
+ // Remember current zoom and view.
+ double zoom = desktop->current_zoom();
+ Geom::Point c = desktop->get_display_area().midpoint();
+
+ bool reverted = document_swap (it2, new_document);
+
+ if (reverted) {
+ desktop->zoom_absolute_center_point (c, zoom);
+ } else {
+ std::cerr << "InkscapeApplication::revert_document: Revert failed!" << std::endl;
+ }
+ }
+
+ document_close (document);
+
+ } else {
+ std::cerr << "InkscapeApplication::revert_document: Document not found!" << std::endl;
+ return false;
+ }
+
+ return true;
}
-// Close a document, remove from app. No checking is done on modified status, etc.
+
+
+/** Close a document, remove from app. No checking is done on modified status, etc.
+ */
void
-InkscapeApplication::close_document(SPDocument* document)
+InkscapeApplication::document_close(SPDocument* document)
{
if (document) {
+
auto it = _documents.find(document);
if (it != _documents.end()) {
if (it->second.size() != 0) {
- std::cerr << "ConcreteInkscapeApplication<T>::close_document: Window vector not empty!" << std::endl;
+ std::cerr << "InkscapeApplication::close_document: Window vector not empty!" << std::endl;
}
_documents.erase(it);
} else {
- std::cerr << "ConcreteInkscapeApplication<T>::close_document: Document not registered with application." << std::endl;
+ std::cerr << "InkscapeApplication::close_document: Document not registered with application." << std::endl;
}
delete document;
} else {
- std::cerr << "ConcreteInkscapeApplication<T>::close_document: No document!" << std::endl;
+ std::cerr << "InkscapeApplication::close_document: No document!" << std::endl;
+ }
+}
+
+
+/** Return number of windows with document.
+ */
+unsigned
+InkscapeApplication::document_window_count(SPDocument* document)
+{
+ unsigned count = 0;
+
+ auto it = _documents.find(document);
+ if (it != _documents.end()) {
+ count = it->second.size();
+ } else {
+ std::cerr << "InkscapeApplication::document_window_count: Document not in map!" << std::endl;
}
+
+ return count;
}
-// Fix up a document if necessary.
+/** Fix up a document if necessary (Only fixes that require GUI).
+ */
void
-InkscapeApplication::fix_document(SPDocument* document)
+InkscapeApplication::document_fix(InkscapeWindow* window)
{
- // TODO
+ // Most fixes are handled when document is opened in SPDocument::createDoc().
+ // But some require the GUI to be present. These are handled here.
+
+ if (_with_gui) {
+
+ SPDocument* document = window->get_document();
+
+ // Perform a fixup pass for hrefs.
+ if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(document) ) {
+ Glib::ustring msg = _("Broken links have been changed to point to existing files.");
+ SPDesktop* desktop = window->get_desktop();
+ if (desktop != nullptr) {
+ desktop->showInfoDialog(msg);
+ }
+ }
+
+ // Fix dpi (pre-92 files).
+ if ( sp_version_inside_range( document->getRoot()->version.inkscape, 0, 1, 0, 92 ) ) {
+ sp_file_convert_dpi(document);
+ }
+
+ // Check for font substitutions, requires text to have been rendered.
+ Inkscape::UI::Dialog::FontSubstitution::getInstance().checkFontSubstitutions(document);
+ }
}
+
// Take an already open document and create a new window, adding window to document map.
-// Document fix-up should already be done.
InkscapeWindow*
-InkscapeApplication::open_window(SPDocument* document)
+InkscapeApplication::window_open(SPDocument* document)
{
InkscapeWindow* window = new InkscapeWindow(document);
// TODO Add window to application. (Instead of in InkscapeWindow constructor.)
@@ -127,33 +331,41 @@ InkscapeApplication::open_window(SPDocument* document)
if (it != _documents.end()) {
it->second.push_back(window);
} else {
- std::cerr << "ConcreteInkscapeApplication<T>::add_window: document not in map!" << std::endl;
+ std::cerr << "InkscapeApplication::open_window: Document not in map!" << std::endl;
}
+ document_fix(window); // May need flag to prevent this from being called more than once.
+
return window;
}
+// Close a window. Does not delete document.
void
-InkscapeApplication::close_window(InkscapeWindow* window)
+InkscapeApplication::window_close(InkscapeWindow* window)
{
+ // std::cout << "InkscapeApplication::close_window" << std::endl;
+ // dump();
+
if (window) {
SPDocument* document = window->get_document();
if (document) {
- // To be removed!
- INKSCAPE.remove_document(document);
+ // To be removed (remove once per window)!
+ bool last = INKSCAPE.remove_document(document);
_active_selection = nullptr;
_active_view = nullptr;
_active_document = nullptr;
+ // Remove window from document map.
auto it = _documents.find(document);
if (it != _documents.end()) {
auto it2 = std::find(it->second.begin(), it->second.end(), window);
if (it2 != it->second.end()) {
it->second.erase(it2);
+ delete window; // Results in call to SPDesktop::destroy()
} else {
std::cerr << "ConcreteInkscapeApplication<T>::close_window: window not found!" << std::endl;
}
@@ -164,11 +376,11 @@ InkscapeApplication::close_window(InkscapeWindow* window)
std::cerr << "ConcreteInkscapeApplication<T>::close_window: No document!" << std::endl;
}
- // TODO Remove window from application.
-
} else {
std::cerr << "ConcreteInkscapeApplication<T>::close_window: No window!" << std::endl;
}
+
+ // dump();
}
@@ -178,20 +390,36 @@ InkscapeApplication::close_window(InkscapeWindow* window)
* - Selection change
*/
void
-InkscapeApplication::update_windows(SPDocument* document)
+InkscapeApplication::windows_update(SPDocument* document)
{
// Find windows:
auto it = _documents.find( document );
if (it != _documents.end()) {
std::vector<InkscapeWindow*> windows = it->second;
- std::cout << "InkscapeApplication::update_windows: windows: " << windows.size() << std::endl;
+ // std::cout << "InkscapeApplication::update_windows: windows size: " << windows.size() << std::endl;
// Loop over InkscapeWindows.
// Loop over DialogWindows. TBD
} else {
- std::cout << "InkscapeApplication::update_windows: no windows found" << std::endl;
+ // std::cout << "InkscapeApplication::update_windows: no windows found" << std::endl;
}
}
+/** Debug function
+ */
+void
+InkscapeApplication::dump()
+{
+ std::cout << "InkscapeApplication::dump()" << std::endl;
+ std::cout << " Documents: " << _documents.size() << std::endl;
+ for (auto i : _documents) {
+ std::cout << " Document: " << (i.first->getDocumentName()?i.first->getDocumentName():"unnamed") << std::endl;
+ for (auto j : i.second) {
+ std::cout << " Window: " << j->get_title() << std::endl;
+ }
+ }
+}
+
+
template<class T>
ConcreteInkscapeApplication<T>&
ConcreteInkscapeApplication<T>::get_instance()
@@ -369,6 +597,177 @@ ConcreteInkscapeApplication<Gtk::Application>::on_startup2()
}
}
+/** We should not create a window if T is Gio::Applicaton.
+*/
+template<class T>
+SPDesktop*
+ConcreteInkscapeApplication<T>::create_window(const Glib::RefPtr<Gio::File>& file,
+ bool add_to_recent,
+ bool replace_empty)
+{
+ std::cerr << "ConcreteInkscapeApplication<T>::create_window: Should not be called!";
+ return nullptr;
+}
+
+
+/** Create a window given a Gio::File. This is what most functions should call.
+ The booleans are only false when opening a help file.
+*/
+template<>
+SPDesktop*
+ConcreteInkscapeApplication<Gtk::Application>::create_window(const Glib::RefPtr<Gio::File>& file,
+ bool add_to_recent,
+ bool replace_empty)
+{
+ SPDesktop* desktop = nullptr;
+
+ if (file) {
+ SPDocument* document = document_open (file);
+ if (document) {
+
+ if (add_to_recent) {
+
+ auto recentmanager = Gtk::RecentManager::get_default();
+ Gtk::RecentManager::Data data;
+ data.app_name = g_get_prgname(); // Must match Gtk::RecentFilter in menubar.cpp
+ data.mime_type = "image"; // We don't know if we opened an SVG! (image/svg+xml).
+ recentmanager->add_item (file->get_uri(), data);
+ }
+
+ // TODO Remove this code... handle document replacement elsewhere.
+ SPDocument* old_document = _active_document;
+ if (replace_empty && old_document && old_document->virgin) {
+ // virgin == true => an empty document (template).
+
+ // Is there a better place for this? It requires GUI.
+ document->ensureUpToDate(); // TODO this will trigger broken line warnings, etc.
+
+ InkscapeWindow* window = dynamic_cast<InkscapeWindow*>(get_active_window());
+ if (window) {
+ document_swap (window, document);
+
+ // Delete old document if no longer attached to any window.
+ auto it = _documents.find (old_document);
+ if (it != _documents.end()) {
+ if (it->second.size() == 0) {
+ document_close (old_document);
+ }
+ }
+
+ document->emitResizedSignal(document->getWidth().value("px"), document->getHeight().value("px"));
+ desktop = window->get_desktop();
+ } else {
+ std::cerr << "ConcreteInkscapeApplication<T>::create_window: Failed to find active window!" << std::endl;
+ }
+ } else {
+ InkscapeWindow* window = window_open (document);
+ desktop = window->get_desktop();
+ }
+
+
+ } else {
+ std::cerr << "ConcreteInkscapeApplication<T>::create_window: Failed to load: "
+ << file->get_parse_name() << std::endl;
+ }
+
+ } else {
+ std::string Template =
+ Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::TEMPLATES, "default.svg", true);
+ SPDocument* document = document_new (Template);
+ if (document) {
+ InkscapeWindow* window = window_open (document);
+ desktop = window->get_desktop();
+ } else {
+ std::cerr << "ConcreteInkscapeApplication<T>::create_window: Failed to open default template! " << Template << std::endl;
+ }
+ }
+
+ if (desktop) {
+ _active_document = desktop->getDocument();
+#ifdef WITH_DBUS
+ Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop);
+#endif
+ } else {
+ std::cerr << "ConcreteInkscapeApplication<T>::create_window: Failed to create desktop!" << std::endl;
+ }
+
+ return (desktop); // Temp: Need to track desktop for shell mode.
+}
+
+/** No need to destroy window if T is Gio::Application.
+ */
+template<class T>
+bool
+ConcreteInkscapeApplication<T>::destroy_window(InkscapeWindow* window)
+{
+ std::cerr << "ConcreteInkscapeApplication<T>::destroy_window: Should not be called!";
+ return false;
+}
+
+/** Destroy a window. Aborts if document needs saving.
+ * Returns true if window destroyed.
+ */
+template<>
+bool
+ConcreteInkscapeApplication<Gtk::Application>::destroy_window(InkscapeWindow* window)
+{
+ SPDocument* document = window->get_document();
+
+ // Remove document if no windows left.
+ if (document) {
+ auto it = _documents.find(document);
+ if (it != _documents.end()) {
+
+ // If only one window for document:
+ if (it->second.size() == 1) {
+ // Check if document needs saving.
+ bool abort = window->get_desktop_widget()->shutdown();
+ if (abort) {
+ return false;
+ }
+ }
+
+ window_close(window);
+
+ if (it->second.size() == 0) {
+ document_close (document);
+ }
+
+ } else {
+ std::cerr << "ConcreteInkscapeApplication<Gtk::Application>::destroy_window: Could not find document!" << std::endl;
+ }
+ }
+
+ // Debug
+ // auto windows = get_windows();
+ // std::cout << "destroy_windows: app windows size: " << windows.size() << std::endl;
+
+ return true;
+}
+
+/* Close all windows and exit.
+**/
+template<class T>
+void
+ConcreteInkscapeApplication<T>::destroy_all()
+{
+ std::cerr << "ConcreteInkscapeApplication<T>::destroy_all: Should not be called!";
+}
+
+template<>
+void
+ConcreteInkscapeApplication<Gtk::Application>::destroy_all()
+{
+ while (_documents.size() != 0) {
+ auto it = _documents.begin();
+ while (it->second.size() != 0) {
+ auto it2 = it->second.begin();
+ if (!destroy_window (*it2)) return; // If destroy aborted, we need to stop exit.
+ }
+ }
+}
+
+
// Open document window with default document. Either this or on_open() is called.
template<class T>
void
@@ -401,7 +800,7 @@ ConcreteInkscapeApplication<T>::on_open(const Gio::Application::type_vec_files&
for (auto file : files) {
// Open file
- SPDocument *document = open_document(file);
+ SPDocument *document = document_open (file);
if (!document) continue;
// Add to Inkscape::Application...
@@ -433,7 +832,7 @@ ConcreteInkscapeApplication<T>::on_open(const Gio::Application::type_vec_files&
// Close file
INKSCAPE.remove_document(document);
- close_document(document);
+ document_close (document);
}
}
@@ -466,7 +865,7 @@ ConcreteInkscapeApplication<Gtk::Application>::on_open(const Gio::Application::t
} else {
// Open file
- SPDocument *document = open_document(file);
+ SPDocument *document = document_open (file);
if (!document) continue;
// Add to Inkscape::Application...
@@ -498,52 +897,11 @@ ConcreteInkscapeApplication<Gtk::Application>::on_open(const Gio::Application::t
// Close file
INKSCAPE.remove_document(document);
- close_document(document);
+ document_close (document);
}
}
}
-
-
-template<class T>
-SPDesktop*
-ConcreteInkscapeApplication<T>::create_window(const Glib::RefPtr<Gio::File>& file)
-{
- SPDesktop* desktop = nullptr;
- if (file) {
- sp_file_open(file->get_parse_name(), nullptr, false, true);
- desktop = SP_ACTIVE_DESKTOP;
- } else {
- desktop = sp_file_new_default();
- }
-
- _active_document = desktop->getDocument();
- // _documents.push_back(desktop->getDocument());
-
- return (desktop); // Temp: Need to track desktop for shell mode.
-}
-
-
-// This is identical to the function above. We comment it out for now (otherwise it must be moved before on_open().
-// template<>
-// SPDesktop*
-// ConcreteInkscapeApplication<Gtk::Application>::create_window(const Glib::RefPtr<Gio::File>& file)
-// {
-// SPDesktop* desktop = nullptr;
-// if (file) {
-// sp_file_open(file->get_parse_name(), nullptr, false, true);
-// desktop = SP_ACTIVE_DESKTOP;
-// } else {
-// desktop = sp_file_new_default();
-// }
-
-// _active_document = desktop->getDocument();
-// // _documents.push_back(desktop->getDocument());
-
-// return (desktop); // Temp: Need to track desktop for shell mode.
-// }
-
-
template<class T>
void
ConcreteInkscapeApplication<T>::parse_actions(const Glib::ustring& input, action_vector_t& action_vector)
diff --git a/src/inkscape-application.h b/src/inkscape-application.h
index 7c53b2795..05fbafb89 100644
--- a/src/inkscape-application.h
+++ b/src/inkscape-application.h
@@ -59,22 +59,34 @@ public:
Inkscape::UI::View::View* get_active_view() { return _active_view; }
void set_active_view(Inkscape::UI::View::View* view) { _active_view = view; }
- SPDocument* open_document(const Glib::RefPtr<Gio::File>& file);
- void close_document(SPDocument* document);
+ /****** Document ******/
+ /* Except for document_fix(), these should not require a GUI! */
+ void document_add(SPDocument* document);
- void fix_document(SPDocument* document);
+ SPDocument* document_new(const std::string &Template);
+ SPDocument* document_open(const Glib::RefPtr<Gio::File>& file);
+ bool document_swap(InkscapeWindow* window, SPDocument* document);
+ bool document_revert(SPDocument* document);
+ void document_close(SPDocument* document);
+ unsigned document_window_count(SPDocument* document);
- InkscapeWindow* open_window(SPDocument* document);
- void close_window(InkscapeWindow* window);
+ void document_fix(InkscapeWindow* window);
+
+ /******* Window *******/
+ InkscapeWindow* window_open(SPDocument* document);
+ void window_close(InkscapeWindow* window);
// Update all windows connected to a document.
- void update_windows(SPDocument* document);
+ void windows_update(SPDocument* document);
+
+ /******* Debug ********/
+ void dump();
// These are needed to cast Glib::RefPtr<Gtk::Application> to Glib::RefPtr<InkscapeApplication>,
// Presumably, Gtk/Gio::Application takes care of ref counting in ConcreteInkscapeApplication
// so we just provide dummies (and there is only one application in the application!).
- void reference() { /*printf("reference()\n" );*/ }
- void unreference() { /*printf("unreference()\n");*/ }
+ // void reference() { /*printf("reference()\n" );*/ }
+ // void unreference() { /*printf("unreference()\n");*/ }
protected:
bool _with_gui;
@@ -111,13 +123,16 @@ private:
public:
InkFileExportCmd* file_export() override { return &_file_export; }
+ SPDesktop* create_window(const Glib::RefPtr<Gio::File>& file = Glib::RefPtr<Gio::File>(),
+ bool add_to_recent = true, bool replace_empty = true);
+ bool destroy_window(InkscapeWindow* window);
+ void destroy_all();
protected:
void on_startup() override;
void on_startup2() override;
void on_activate() override;
void on_open(const Gio::Application::type_vec_files& files, const Glib::ustring& hint) override;
- SPDesktop* create_window(const Glib::RefPtr<Gio::File>& file = Glib::RefPtr<Gio::File>());
void parse_actions(const Glib::ustring& input, action_vector_t& action_vector);
private:
diff --git a/src/inkscape-window.cpp b/src/inkscape-window.cpp
index bcf10cedd..eb11199db 100644
--- a/src/inkscape-window.cpp
+++ b/src/inkscape-window.cpp
@@ -99,6 +99,11 @@ InkscapeWindow::InkscapeWindow(SPDocument* document)
sp_namedview_zoom_and_view_from_document(_desktop);
sp_namedview_update_layers_from_document(_desktop);
+ SPNamedView *nv = _desktop->namedview;
+ if (nv && nv->lockguides) {
+ nv->lockGuides();
+ }
+
}
// Change a document, leaving desktop/view the same. (Eventually move all code here.)
@@ -133,7 +138,7 @@ InkscapeWindow::on_focus_in_event(GdkEventFocus* event)
_app->set_active_document(_document);
_app->set_active_view(_desktop);
_app->set_active_selection(_desktop->selection);
- // _app->update_windows(_document);
+ _app->windows_update(_document);
} else {
std::cerr << "Inkscapewindow::on_focus_in_event: app is nullptr!" << std::endl;
}
diff --git a/src/io/file.cpp b/src/io/file.cpp
index 5877e2727..294707464 100644
--- a/src/io/file.cpp
+++ b/src/io/file.cpp
@@ -2,7 +2,7 @@
/*
* File operations (independent of GUI)
*
- * Copyright (C) 2018 Tavmjong Bah
+ * Copyright (C) 2018, 2019 Tavmjong Bah
*
* The contents of this file may be used under the GNU General Public License Version 2 or later.
*
@@ -14,6 +14,7 @@
#include "file.h"
#include "document.h"
+#include "document-undo.h"
#include "extension/system.h" // Extension::open()
#include "extension/extension.h"
@@ -23,58 +24,86 @@
#include "object/sp-root.h"
-// SPDocument*
-// ink_file_new(const std::string &Template)
-// {
-// SPDocument *doc = SPDocument::createNewDoc( Template, true, true );
-// return doc;
-// }
+/**
+ * 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 = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo");
+ if (nodeToRemove != nullptr) {
+ Inkscape::DocumentUndo::ScopedInsensitive no_undo(doc);
+ sp_repr_unparent(nodeToRemove);
+ delete nodeToRemove;
+ }
+ } else {
+ std::cout << "ink_file_new: Did not create new document!" << std::endl;
+ }
+
+ return doc;
+}
SPDocument*
ink_file_open(const Glib::RefPtr<Gio::File>& file, bool &cancelled)
{
- cancelled = false;
+ cancelled = false;
- SPDocument *doc = nullptr;
+ SPDocument *doc = nullptr;
- std::string path = file->get_path();
+ std::string path = file->get_path();
- 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.
- if (doc == nullptr && !cancelled) {
try {
- doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), path.c_str());
+ doc = Inkscape::Extension::open(nullptr, path.c_str());
} catch (Inkscape::Extension::Input::no_extension_found &e) {
- doc = nullptr;
+ doc = nullptr;
} catch (Inkscape::Extension::Input::open_failed &e) {
- doc = nullptr;
+ doc = nullptr;
} catch (Inkscape::Extension::Input::open_cancelled &e) {
- cancelled = true;
- doc = nullptr;
+ cancelled = true;
+ doc = nullptr;
}
- }
- if (doc == nullptr) {
- std::cerr << "ink_file_open: '" << path << "' cannot be opened!" << std::endl;
- } else {
+ // Try to open explicitly as SVG.
+ 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;
+ }
+ }
- // 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;
- }
+ if (doc == nullptr) {
+ std::cerr << "ink_file_open: '" << path << "' cannot be opened!" << std::endl;
+ } else {
- return doc;
+ // 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;
}
+/*
+ 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 :
diff --git a/src/io/file.h b/src/io/file.h
index b911563b7..3e1c8ca65 100644
--- a/src/io/file.h
+++ b/src/io/file.h
@@ -13,7 +13,7 @@
class SPDocument;
-//SPDocument* ink_file_new(const std::string &template = nullptr);
+SPDocument* ink_file_new(const std::string &Template = nullptr);
SPDocument* ink_file_open(const Glib::RefPtr<Gio::File>& file, bool &cancelled);
// To do:
diff --git a/src/io/resource-manager.cpp b/src/io/resource-manager.cpp
index fc742cb80..308aca8a9 100644
--- a/src/io/resource-manager.cpp
+++ b/src/io/resource-manager.cpp
@@ -338,7 +338,12 @@ bool ResourceManagerImpl::fixupBrokenLinks(SPDocument *doc)
}
}
- std::map<Glib::ustring, Glib::ustring> mapping = locateLinks(doc->getDocumentBase(), brokenHrefs);
+ Glib::ustring base;
+ if (doc->getDocumentBase()) {
+ base = doc->getDocumentBase();
+ }
+
+ std::map<Glib::ustring, Glib::ustring> mapping = locateLinks(base, brokenHrefs);
for ( std::map<Glib::ustring, Glib::ustring>::iterator it = mapping.begin(); it != mapping.end(); ++it )
{
// TODO debug g_message(" [%s] ==> {%s}", it->first.c_str(), it->second.c_str());
diff --git a/src/ui/desktop/menubar.cpp b/src/ui/desktop/menubar.cpp
index e9ef9e897..7300e8c3b 100644
--- a/src/ui/desktop/menubar.cpp
+++ b/src/ui/desktop/menubar.cpp
@@ -24,7 +24,8 @@
#include <iostream>
#include "inkscape.h"
-#include "file.h" // sp_file_open
+#include "inkscape-application.h" // Open recent
+
#include "message-context.h"
#include "shortcuts.h"
@@ -322,9 +323,9 @@ sp_recent_open(Gtk::RecentChooser* recentchooser)
Glib::RefPtr<Gio::File> file = Gio::File::create_for_uri(uri);
- // To do: change sp_file_open to use Gio::File.
- // To do: get rid of sp_file_open
- sp_file_open(file->get_parse_name(), nullptr);
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
+ app->create_window(file);
}
// =================== Main Menu ================
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 2e7d44bf8..1b977999e 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -63,7 +63,9 @@ sp_ui_new_view()
document = SP_ACTIVE_DOCUMENT;
if (!document) return;
- auto win = new InkscapeWindow(document);
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
+ InkscapeWindow* win = app->window_open (document);
}
void
@@ -79,45 +81,46 @@ sp_ui_close_view(GtkWidget */*widget*/)
return; // Shutdown operation has been canceled, so do nothing
}
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
+ InkscapeWindow* window = SP_ACTIVE_DESKTOP->getInkscapeWindow();
+
// If closing the last document, open a new document so Inkscape doesn't quit.
std::list<SPDesktop *> desktops;
INKSCAPE.get_all_desktops(desktops);
if (desktops.size() == 1) {
- Glib::ustring templateUri = sp_file_default_template_uri();
- SPDocument *doc = SPDocument::createNewDoc( templateUri.empty() ? nullptr : templateUri.c_str(), TRUE, true );
- // Set viewBox if it doesn't exist
- if (!doc->getRoot()->viewBox_set) {
- doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit())));
+
+ SPDocument* old_document = window->get_document();
+
+ Glib::ustring template_path = sp_file_default_template_uri();
+ SPDocument *doc = app->document_new (template_path);
+
+ app->document_swap (window, doc);
+
+ if (app->document_window_count(old_document) == 0) {
+ app->document_close(old_document);
}
- dt->change_document(doc);
+
+ // Are these necessary?
sp_namedview_window_from_document(dt);
sp_namedview_update_layers_from_document(dt);
- return;
- }
- // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP,
- // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad)
- dt->destroyWidget();
+ } else {
+
+ app->destroy_window (window);
+ }
}
unsigned int
sp_ui_close_all()
{
- /* Iterate through all the windows, destroying each in the order they
- become active */
- while (SP_ACTIVE_DESKTOP) {
- SPDesktop *dt = SP_ACTIVE_DESKTOP;
- if (dt->shutdown()) {
- /* The user canceled the operation, so end doing the close */
- return FALSE;
- }
- // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP,
- // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad)
- dt->destroyWidget();
- }
- return TRUE;
+ ConcreteInkscapeApplication<Gtk::Application>* app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+
+ app->destroy_all();
+
+ return true;
}
diff --git a/src/ui/view/view.cpp b/src/ui/view/view.cpp
index 4395357e0..3b2b7f229 100644
--- a/src/ui/view/view.cpp
+++ b/src/ui/view/view.cpp
@@ -84,7 +84,7 @@ void View::_close() {
_document_resized_connection.disconnect();
if (INKSCAPE.remove_document(_doc)) {
// this was the last view of this document, so delete it
- delete _doc;
+ // delete _doc; Delete now handled in Inkscape::Application
}
_doc = nullptr;
}
@@ -110,7 +110,7 @@ void View::setDocument(SPDocument *doc) {
_document_resized_connection.disconnect();
if (INKSCAPE.remove_document(_doc)) {
// this was the last view of this document, so delete it
- delete _doc;
+ // delete _doc; Delete now handled in Inkscape::Application
}
}