diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2019-01-30 14:54:01 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2019-01-30 14:54:01 +0000 |
| commit | 7531449fc6f5c3113802747db11a2bca2e308555 (patch) | |
| tree | eb1e211ef0f68674f3f929516e00b3a0c288a800 /src | |
| parent | GradientToolbar: GtkAction migration (diff) | |
| download | inkscape-7531449fc6f5c3113802747db11a2bca2e308555.tar.gz inkscape-7531449fc6f5c3113802747db11a2bca2e308555.zip | |
Allow InkscapeApplication to track current document, selection, and desktop.
Diffstat (limited to 'src')
| -rw-r--r-- | src/desktop.cpp | 1 | ||||
| -rw-r--r-- | src/helper/action-context.cpp | 5 | ||||
| -rw-r--r-- | src/helper/action-context.h | 2 | ||||
| -rw-r--r-- | src/inkscape-application.cpp | 23 | ||||
| -rw-r--r-- | src/inkscape-application.h | 30 | ||||
| -rw-r--r-- | src/inkscape-window.cpp | 36 | ||||
| -rw-r--r-- | src/inkscape-window.h | 13 |
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 |
