summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2019-01-30 14:54:01 +0000
committerTavmjong Bah <tavmjong@free.fr>2019-01-30 14:54:01 +0000
commit7531449fc6f5c3113802747db11a2bca2e308555 (patch)
treeeb1e211ef0f68674f3f929516e00b3a0c288a800
parentGradientToolbar: GtkAction migration (diff)
downloadinkscape-7531449fc6f5c3113802747db11a2bca2e308555.tar.gz
inkscape-7531449fc6f5c3113802747db11a2bca2e308555.zip
Allow InkscapeApplication to track current document, selection, and desktop.
-rw-r--r--src/desktop.cpp1
-rw-r--r--src/helper/action-context.cpp5
-rw-r--r--src/helper/action-context.h2
-rw-r--r--src/inkscape-application.cpp23
-rw-r--r--src/inkscape-application.h30
-rw-r--r--src/inkscape-window.cpp36
-rw-r--r--src/inkscape-window.h13
7 files changed, 83 insertions, 27 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index 20c4914a4..ff40e5934 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -684,6 +684,7 @@ SPDesktop::change_document (SPDocument *theDocument)
(this can probably be done in a better way) */
InkscapeWindow *parent = this->getInkscapeWindow();
g_assert(parent != nullptr);
+ parent->change_document(theDocument);
SPDesktopWidget *dtw = parent->get_desktop_widget();
if (dtw) {
dtw->desktop = this;
diff --git a/src/helper/action-context.cpp b/src/helper/action-context.cpp
index 648101540..36b6914d6 100644
--- a/src/helper/action-context.cpp
+++ b/src/helper/action-context.cpp
@@ -62,11 +62,6 @@ UI::View::View *ActionContext::getView() const
SPDesktop *ActionContext::getDesktop() const
{
- // TODO: this slightly horrible storage of a UI::View::View*, and
- // casting to an SPDesktop*, is only done because that's what was
- // already the norm in the Inkscape codebase. This seems wrong. Surely
- // we should store an SPDesktop* in the first place? Is there a case
- // of actions being carried out on a View that is not an SPDesktop?
return static_cast<SPDesktop *>(_view);
}
diff --git a/src/helper/action-context.h b/src/helper/action-context.h
index 2660bc59c..d3468ea3e 100644
--- a/src/helper/action-context.h
+++ b/src/helper/action-context.h
@@ -37,7 +37,7 @@ class View;
used to take as parameters in their methods. Why is this? They almost
always seemed to cast straight to an SPDesktop* - so shouldn't we actually
be storing an SPDesktop*? Is there a case where a non-SPDesktop
- UI::View::View is used by the actions?
+ UI::View::View is used by the actions? YES: Command-line wihtout GUI.
ActionContext is designed to be copyable, so it may be used with stack
storage if required. */
diff --git a/src/inkscape-application.cpp b/src/inkscape-application.cpp
index cc8d2ca0f..7c36d148d 100644
--- a/src/inkscape-application.cpp
+++ b/src/inkscape-application.cpp
@@ -43,7 +43,14 @@ using Inkscape::IO::Resource::UIS;
// flags are set. If the open flag is set and the command line not, the all the remainng arguments
// after calling on_handle_local_options() are assumed to be filenames.
-InkscapeApplication::InkscapeApplication() : _with_gui(true), _batch_process(false), _use_shell(false) {}
+InkscapeApplication::InkscapeApplication()
+ : _with_gui(true)
+ , _batch_process(false)
+ , _use_shell(false)
+ , _active_document(nullptr)
+ , _active_selection(nullptr)
+ , _active_view(nullptr)
+{}
template<class T>
ConcreteInkscapeApplication<T>::ConcreteInkscapeApplication()
@@ -154,13 +161,6 @@ ConcreteInkscapeApplication<T>::ConcreteInkscapeApplication()
T::register_application();
}
-Inkscape::Selection*
-InkscapeApplication::get_active_selection()
-{
- Inkscape::ActionContext context = INKSCAPE.action_context_for_document(_active_document);
- return context.getSelection();
-}
-
template<class T>
void
ConcreteInkscapeApplication<T>::on_startup()
@@ -268,6 +268,7 @@ ConcreteInkscapeApplication<T>::on_open(const Gio::Application::type_vec_files&
}
} else {
+
// Open file
bool cancelled = false;
SPDocument *doc = ink_file_open(file, cancelled);
@@ -275,6 +276,10 @@ ConcreteInkscapeApplication<T>::on_open(const Gio::Application::type_vec_files&
// Add to Inkscape::Application...
INKSCAPE.add_document(doc);
+ // ActionContext should be removed once verbs are gone but we use it for now.
+ Inkscape::ActionContext context = INKSCAPE.action_context_for_document(doc);
+ set_active_selection(context.getSelection());
+ set_active_view( context.getView() );
doc->ensureUpToDate(); // Or queries don't work!
@@ -294,6 +299,8 @@ ConcreteInkscapeApplication<T>::on_open(const Gio::Application::type_vec_files&
}
_active_document = nullptr;
+ _active_selection = nullptr;
+ _active_view = nullptr;
// Close file
INKSCAPE.remove_document(doc);
diff --git a/src/inkscape-application.h b/src/inkscape-application.h
index f9a982207..25d1e9ace 100644
--- a/src/inkscape-application.h
+++ b/src/inkscape-application.h
@@ -43,8 +43,27 @@ public:
virtual int on_handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options) = 0;
virtual void on_new() = 0;
virtual void on_quit() = 0;
- SPDocument* get_active_document() { return _active_document; };
- Inkscape::Selection* get_active_selection(); // { return _active_selection; };
+
+ // Gio::Actions need to know what document, selection, view to work on.
+ // In headless mode, these are set for each file processed.
+ // With GUI, these are set everytime the cursor enters an InkscapeWindow.
+ SPDocument* get_active_document() { return _active_document; };
+ void set_active_document(SPDocument* document) { _active_document = document; };
+
+ Inkscape::Selection* get_active_selection() { return _active_selection; }
+ void set_active_selection(Inkscape::Selection* selection)
+ {_active_selection = selection;};
+
+ // A view should track selection and canvas to document transform matrix. This is partially
+ // redundant with the selection functions above. Maybe we should get rid of view altogether.
+ Inkscape::UI::View::View* get_active_view() { return _active_view; }
+ void set_active_view(Inkscape::UI::View::View* view) { _active_view = view; }
+
+ // 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");*/ }
protected:
bool _with_gui;
@@ -57,8 +76,9 @@ protected:
std::map<SPDocument*, std::vector<InkscapeWindow*> > _documents;
// We keep track of these things so we don't need a window to find them (for headless operation).
- SPDocument* _active_document;
- Inkscape::Selection* active_selection; // This should be a view once view doesn't depend on GUI.
+ SPDocument* _active_document;
+ Inkscape::Selection* _active_selection;
+ Inkscape::UI::View::View* _active_view;
InkFileExportCmd _file_export;
@@ -67,7 +87,7 @@ protected:
};
// T can be either:
-// Gio::Application (window server is not present) or
+// Gio::Application (window server is not present, required for CI testing) or
// Gtk::Application (window server is present).
// With Gtk::Application, one can still run "headless" by not creating any windows.
template <class T> class ConcreteInkscapeApplication : public T, public InkscapeApplication
diff --git a/src/inkscape-window.cpp b/src/inkscape-window.cpp
index bf2213a88..24718c316 100644
--- a/src/inkscape-window.cpp
+++ b/src/inkscape-window.cpp
@@ -19,6 +19,7 @@
#include "inkscape.h" // SP_ACTIVE_DESKTOP
#include "enums.h" // PREFS_WINDOW_GEOMETRY_NONE
#include "shortcuts.h"
+#include "inkscape-application.h"
#include "object/sp-namedview.h" // TODO Remove need for this!
@@ -40,11 +41,11 @@ InkscapeWindow::InkscapeWindow(SPDocument* document)
return;
}
- // Register window with application.
Glib::RefPtr<Gio::Application> gio_app = Gio::Application::get_default();
- Glib::RefPtr<Gtk::Application> app = Glib::RefPtr<Gtk::Application>::cast_dynamic(gio_app);
- if (app) {
- set_application(app); // Same as Gtk::Application::add_window()
+ Glib::RefPtr<Gtk::Application> gtk_app = Glib::RefPtr<Gtk::Application>::cast_dynamic(gio_app);
+ _app = Glib::RefPtr<InkscapeApplication>::cast_dynamic(gtk_app);
+ if (gtk_app) {
+ set_application(gtk_app); // Same as Gtk::Application::add_window()
} else {
std::cerr << "InkscapeWindow::InkscapeWindow:: Didn't get app!" << std::endl;
}
@@ -99,6 +100,19 @@ InkscapeWindow::InkscapeWindow(SPDocument* document)
}
+// Change a document, leaving desktop/view the same. (Eventually move all code here.)
+void
+InkscapeWindow::change_document(SPDocument* document)
+{
+ _document = document;
+ if (_app) {
+ _app->set_active_document(_document);
+ } else {
+ std::cerr << "Inkscapewindow::change_document: app is nullptr!" << std::endl;
+ }
+}
+
+// We don't override on_key_press() as it steals key strokes from text tool.
bool
InkscapeWindow::key_press(GdkEventKey* event)
{
@@ -106,6 +120,20 @@ InkscapeWindow::key_press(GdkEventKey* event)
return sp_shortcut_invoke (shortcut, _desktop);
}
+bool
+InkscapeWindow::on_focus_in_event(GdkEventFocus* event)
+{
+ if (_app) {
+ _app->set_active_document(_document);
+ _app->set_active_view(_desktop);
+ _app->set_active_selection(_desktop->selection);
+ } else {
+ std::cerr << "Inkscapewindow::on_focus_in_event: app is nullptr!" << std::endl;
+ }
+
+ return true;
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/inkscape-window.h b/src/inkscape-window.h
index 9fee2d991..ff78d9a8b 100644
--- a/src/inkscape-window.h
+++ b/src/inkscape-window.h
@@ -19,6 +19,7 @@
#include <gtkmm.h>
+class InkscapeApplication;
class SPDocument;
class SPDesktop;
class SPDesktopWidget;
@@ -40,16 +41,20 @@ public:
SPDesktop* get_desktop() { return _desktop; }
SPDesktopWidget* get_desktop_widget() { return _desktop_widget; }
+ void change_document(SPDocument* document);
+
private:
- SPDocument* _document;
- SPDesktop* _desktop;
- SPDesktopWidget* _desktop_widget;
+ Glib::RefPtr<InkscapeApplication> _app;
+ SPDocument* _document;
+ SPDesktop* _desktop;
+ SPDesktopWidget* _desktop_widget;
Gtk::Box* _mainbox;
Gtk::MenuBar* _menubar;
// Callbacks
- bool key_press(GdkEventKey* event);
+ bool key_press(GdkEventKey* event); // Not override!
+ bool on_focus_in_event(GdkEventFocus* event) override;
};
#endif // INKSCAPE_WINDOW_H