From 6dfb9b4eade77ac55d11f05669c2192352b9b8fa Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 26 Jun 2014 13:49:17 -0400 Subject: 4. further refactor Application class; create proper singleton, encapsulate members, simplify signals (bzr r13341.5.6) --- src/document.cpp | 6 +- src/inkscape.cpp | 255 ++++++++++++++++----------------- src/inkscape.h | 107 +++++++------- src/inkview.cpp | 3 +- src/main.cpp | 4 +- src/ui/dialog/align-and-distribute.cpp | 4 +- src/ui/dialog/clonetiler.cpp | 4 +- src/ui/dialog/desktop-tracker.cpp | 5 +- src/ui/dialog/dialog.cpp | 8 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/grid-arrange-tab.cpp | 2 +- src/ui/dialog/panel-dialog.h | 19 ++- src/ui/dialog/transformation.cpp | 4 +- src/ui/widget/dock.cpp | 4 +- src/ui/widget/imageicon.cpp | 3 +- src/widgets/gradient-vector.cpp | 9 +- src/widgets/icon.cpp | 4 +- src/widgets/sp-widget.cpp | 40 ++++-- 18 files changed, 244 insertions(+), 239 deletions(-) diff --git a/src/document.cpp b/src/document.cpp index 26e59e610..000888772 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -463,15 +463,13 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, // reset undo key when selection changes, so that same-key actions on different objects are not coalesced document->priv->selChangeConnection = INKSCAPE->signal_selection_changed.connect( - sigc::hide( // hide unused first and second args sigc::hide(sigc::bind( sigc::ptr_fun(&DocumentUndo::resetKey), document) - ))); + )); document->priv->desktopActivatedConnection = INKSCAPE->signal_activate_desktop.connect( - sigc::hide( // hide unused first and second args sigc::hide(sigc::bind( sigc::ptr_fun(&DocumentUndo::resetKey), document) - ))); + )); document->oldSignalsConnected = true; return document; diff --git a/src/inkscape.cpp b/src/inkscape.cpp index f9a314f7e..60f950636 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -8,7 +8,8 @@ * Liam P. White * * Copyright (C) 1999-2014 authors - * g++ port Copyright (C) 2003 Nathan Hurst + * c++ port Copyright (C) 2003 Nathan Hurst + * c++ification copyright (C) 2014 Liam P. White * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -73,12 +74,14 @@ #include "ui/dialog/debug.h" #include "xml/repr.h" -static Inkscape::Application *inkscape = NULL; - /* Backbones of configuration xml data */ #include "menus-skeleton.h" -#define DESKTOP_IS_ACTIVE(d) (!inkscape->desktops->empty() && ((d) == inkscape->desktops->front())) +// Inkscape::Application static members +Inkscape::Application * Inkscape::Application::_S_inst = NULL; +bool Inkscape::Application::_crashIsHappening = false; + +#define DESKTOP_IS_ACTIVE(d) (!INKSCAPE->_desktops->empty() && ((d) == INKSCAPE->_desktops->front())) static void (* segv_handler) (int) = SIG_DFL; static void (* abrt_handler) (int) = SIG_DFL; @@ -144,51 +147,42 @@ Inkscape::Application * inkscape_unref(Inkscape::Application * in) return NULL; } +// Callback passed to g_timeout_add_seconds() +// gets the current instance and calls autosave() int inkscape_autosave(gpointer) { - g_assert(inkscape != NULL); - return inkscape->autosave(); -} - -/** - * Returns the current Inkscape::Application global object - */ -Inkscape::Application * -inkscape_get_instance() -{ - return inkscape; -} - -/* fixme: This is EVIL, and belongs to main after all */ - -static bool crashIsHappening = false; - -bool inkscapeIsCrashing() -{ - return crashIsHappening; + g_assert(INKSCAPE != NULL); + return INKSCAPE->autosave(); } +namespace Inkscape { void -inkscape_application_init (const gchar *argv0, gboolean use_gui) +Application::init (const char *argv0, bool use_gui) { - if (!inkscape) { - new Inkscape::Application(argv0, use_gui); + if (!Application::instance()) { + new Application(argv0, use_gui); } else { g_assert_not_reached(); } } -namespace Inkscape { +/** + * Returns the current Inkscape::Application global object + */ +Application * +Application::instance() +{ + return Application::_S_inst; +} /** * static gint inkscape_autosave(gpointer); * - * Callback passed to g_timeout_add_seconds() * Responsible for autosaving all open documents */ int Application::autosave() { - if (document_set.empty()) { // nothing to autosave + if (_document_set.empty()) { // nothing to autosave return TRUE; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -238,8 +232,8 @@ int Application::autosave() gint docnum = 0; SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents...")); - for (std::map::iterator iter = document_set.begin(); - iter != document_set.end(); + for (std::map::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { SPDocument *doc = iter->first; @@ -364,17 +358,17 @@ void Application::argv0(char const* argv) /* \brief Constructor for the application. * Creates a new Inkscape::Application. * - * \pre inkscape == NULL + * \pre Application::_S_inst == NULL */ Application::Application(const char* argv, bool use_gui) : + _menus(NULL), + _desktops(NULL), refCount(1), _dialogs_toggle(TRUE), _mapalt(GDK_MOD1_MASK), _trackalt(FALSE), - _use_gui(use_gui), - menus(NULL), - desktops(NULL) + _use_gui(use_gui) { /* fixme: load application defaults */ @@ -388,9 +382,9 @@ Application::Application(const char* argv, bool use_gui) : _argv0 = g_strdup(argv); - // \TODO: this belongs to inkscape_application_init but if it isn't here + // \TODO: this belongs to Application::init but if it isn't here // then the Filters and Extensions menus don't work. - inkscape = this; + _S_inst = this; /* Load the preferences and menus */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -446,15 +440,15 @@ Application::Application(const char* argv, bool use_gui) : Application::~Application() { - if (desktops) { + if (_desktops) { g_error("FATAL: desktops still in list on application destruction!"); } Inkscape::Preferences::unload(); - if (menus) { - Inkscape::GC::release(menus); - menus = NULL; + if (_menus) { + Inkscape::GC::release(_menus); + _menus = NULL; } if (_argv0) { @@ -466,7 +460,10 @@ Application::~Application() gtk_main_quit (); } -/* Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default */ +/** Sets the keyboard modifer to map to Alt. + * + * Zero switches off mapping, as does '1', which is the default. + */ void Application::mapalt(guint maskvalue) { if ( maskvalue < 2 || maskvalue > 5 ) { // MOD5 is the highest defined in gdktypes.h @@ -483,7 +480,7 @@ Application::crash_handler (int /*signum*/) using Inkscape::Debug::EventTracker; using Inkscape::Debug::Logger; - static gint recursion = FALSE; + static bool recursion = false; /* * reset all signal handlers: any further crashes should just be allowed @@ -501,9 +498,9 @@ Application::crash_handler (int /*signum*/) if (recursion) { abort (); } - recursion = TRUE; + recursion = true; - crashIsHappening = true; + _crashIsHappening = true; EventTracker > tracker("crash"); tracker.set >("emergency-save"); @@ -520,8 +517,8 @@ Application::crash_handler (int /*signum*/) gchar *inkscapedir = g_path_get_dirname(INKSCAPE->_argv0); // Needs to be freed GSList *savednames = NULL; GSList *failednames = NULL; - for (std::map::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map::iterator iter = INKSCAPE->_document_set.begin(), e = INKSCAPE->_document_set.end(); + iter != e; ++iter) { SPDocument *doc = iter->first; Inkscape::XML::Node *repr; @@ -662,10 +659,7 @@ Application::crash_handler (int /*signum*/) } *(b + pos) = '\0'; - // checking whether we have an Inkscape instance after that instance caused an exception is like - // checking if your mother existed after sitting on you and nearly hospitalizing you - - if ( inkscape_get_instance() && inkscape->use_gui() ) { + if ( instance() && instance()->use_gui() ) { GtkWidget *msgbox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", b); gtk_dialog_run (GTK_DIALOG (msgbox)); gtk_widget_destroy (msgbox); @@ -694,7 +688,7 @@ bool Application::load_menus() if ( g_file_get_contents(fn, &menus_xml, &len, NULL) ) { // load the menus_xml file - menus = sp_repr_read_mem(menus_xml, len, NULL); + _menus = sp_repr_read_mem(menus_xml, len, NULL); g_free(menus_xml); menus_xml = 0; @@ -702,11 +696,11 @@ bool Application::load_menus() g_free(fn); fn = 0; - if ( !menus ) { - menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); + if ( !_menus ) { + _menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); } - return (menus != 0); + return (_menus != 0); } @@ -716,7 +710,7 @@ Application::selection_modified (Inkscape::Selection *selection, guint flags) g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - signal_selection_modified.emit(this, selection, flags); + signal_selection_modified.emit(selection, flags); } } @@ -727,7 +721,7 @@ Application::selection_changed (Inkscape::Selection * selection) g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - signal_selection_changed.emit(this, selection); + signal_selection_changed.emit(selection); } } @@ -737,7 +731,7 @@ Application::subselection_changed (SPDesktop *desktop) g_return_if_fail (desktop != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { - signal_subselection_changed.emit(this, desktop); + signal_subselection_changed.emit(desktop); } } @@ -748,8 +742,8 @@ Application::selection_set (Inkscape::Selection * selection) g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - signal_selection_set.emit(this, selection); - signal_selection_changed.emit(this, selection); + signal_selection_set.emit(selection); + signal_selection_changed.emit(selection); } } @@ -761,7 +755,7 @@ Application::eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext) g_return_if_fail (SP_IS_EVENT_CONTEXT (eventcontext)); if (DESKTOP_IS_ACTIVE (eventcontext->desktop)) { - signal_eventcontext_set.emit(this, eventcontext); + signal_eventcontext_set.emit(eventcontext); } } @@ -770,21 +764,20 @@ void Application::add_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - if (desktops == NULL) { - desktops = new std::vector; - g_message("Creating new desktop list."); + if (_desktops == NULL) { + _desktops = new std::vector; } - if (std::find(desktops->begin(), desktops->end(), desktop) != desktops->end()) { + if (std::find(_desktops->begin(), _desktops->end(), desktop) != _desktops->end()) { g_error("Attempted to add desktop already in list."); } - desktops->insert(desktops->begin(), desktop); + _desktops->insert(_desktops->begin(), desktop); - signal_activate_desktop.emit(this, desktop); - signal_eventcontext_set.emit(this, desktop->getEventContext()); - signal_selection_set.emit(this, sp_desktop_selection(desktop)); - signal_selection_changed.emit(this, sp_desktop_selection(desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set.emit(sp_desktop_selection(desktop)); + signal_selection_changed.emit(sp_desktop_selection(desktop)); } @@ -793,38 +786,36 @@ void Application::remove_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); - if (std::find (desktops->begin(), desktops->end(), desktop) == desktops->end() ) { + if (std::find (_desktops->begin(), _desktops->end(), desktop) == _desktops->end() ) { g_error("Attempted to remove desktop not in list."); } if (DESKTOP_IS_ACTIVE (desktop)) { - signal_deactivate_desktop.emit(this, desktop); - if (desktops->size() > 1) { - SPDesktop * new_desktop = *(++desktops->begin()); - desktops->erase(std::find(desktops->begin(), desktops->end(), new_desktop)); - desktops->insert(desktops->begin(), new_desktop); + signal_deactivate_desktop.emit(desktop); + if (_desktops->size() > 1) { + SPDesktop * new_desktop = *(++_desktops->begin()); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), new_desktop)); + _desktops->insert(_desktops->begin(), new_desktop); - signal_activate_desktop.emit(this, new_desktop); - signal_eventcontext_set.emit(this, new_desktop->getEventContext()); - signal_selection_set.emit(this, sp_desktop_selection(new_desktop)); - signal_selection_changed.emit(this, sp_desktop_selection(new_desktop)); + signal_activate_desktop.emit(new_desktop); + signal_eventcontext_set.emit(new_desktop->getEventContext()); + signal_selection_set.emit(sp_desktop_selection(new_desktop)); + signal_selection_changed.emit(sp_desktop_selection(new_desktop)); } else { - signal_eventcontext_set.emit(this, NULL); + signal_eventcontext_set.emit(NULL); if (sp_desktop_selection(desktop)) sp_desktop_selection(desktop)->clear(); } } - desktops->erase(std::find(desktops->begin(), desktops->end(), desktop)); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), desktop)); // if this was the last desktop, shut down the program - if (desktops->empty()) { - g_message("Shutting down."); + if (_desktops->empty()) { this->exit(); - delete desktops; - desktops = NULL; + delete _desktops; + _desktops = NULL; } } @@ -841,21 +832,21 @@ Application::activate_desktop (SPDesktop * desktop) std::vector::iterator i; - if ((i = std::find (desktops->begin(), desktops->end(), desktop)) == desktops->end()) { + if ((i = std::find (_desktops->begin(), _desktops->end(), desktop)) == _desktops->end()) { g_error("Tried to activate desktop not added to list."); } - SPDesktop *current = desktops->front(); + SPDesktop *current = _desktops->front(); - signal_deactivate_desktop.emit(this, current); + signal_deactivate_desktop.emit(current); - desktops->erase (i); - desktops->insert (desktops->begin(), desktop); + _desktops->erase (i); + _desktops->insert (_desktops->begin(), desktop); - signal_activate_desktop.emit(this, desktop); - signal_eventcontext_set.emit(this, desktop->getEventContext()); - signal_selection_set(this, sp_desktop_selection(desktop)); - signal_selection_changed(this, sp_desktop_selection(desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set(sp_desktop_selection(desktop)); + signal_selection_changed(sp_desktop_selection(desktop)); } @@ -868,7 +859,7 @@ Application::reactivate_desktop (SPDesktop * desktop) g_return_if_fail (desktop != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { - signal_activate_desktop.emit(this, desktop); + signal_activate_desktop.emit(desktop); } } @@ -877,7 +868,7 @@ Application::reactivate_desktop (SPDesktop * desktop) SPDesktop * Application::find_desktop_by_dkey (unsigned int dkey) { - for (std::vector::iterator r = desktops->begin(), e = desktops->end(); r != e; ++r) { + for (std::vector::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { if ((*r)->dkey == dkey){ return *r; } @@ -891,7 +882,7 @@ Application::maximum_dkey() { unsigned int dkey = 0; - for (std::vector::iterator r = desktops->begin(), e = desktops->end(); r != e; ++r) { + for (std::vector::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { if ((*r)->dkey > dkey){ dkey = (*r)->dkey; } @@ -905,7 +896,7 @@ SPDesktop * Application::next_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (desktops->front())->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; if (dkey_current < maximum_dkey()) { // find next existing @@ -935,7 +926,7 @@ SPDesktop * Application::prev_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (desktops->front())->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; if (dkey_current > 0) { // find prev existing @@ -972,8 +963,8 @@ Application::switch_desktops_prev() void Application::dialogs_hide() { - signal_dialogs_hide.emit(this); - _dialogs_toggle = FALSE; + signal_dialogs_hide.emit(); + _dialogs_toggle = false; } @@ -981,8 +972,8 @@ Application::dialogs_hide() void Application::dialogs_unhide() { - signal_dialogs_unhide.emit(this); - _dialogs_toggle = TRUE; + signal_dialogs_unhide.emit(); + _dialogs_toggle = true; } @@ -1000,7 +991,7 @@ Application::dialogs_toggle() void Application::external_change() { - signal_external_change.emit(this); + signal_external_change.emit(); } /** @@ -1012,10 +1003,10 @@ Application::add_document (SPDocument *document) g_return_if_fail (document != NULL); // try to insert the pair into the list - if (!(document_set.insert(std::make_pair(document, 1)).second)) { + if (!(_document_set.insert(std::make_pair(document, 1)).second)) { //insert failed, this key (document) is already in the list - for (std::map::iterator iter = document_set.begin(); - iter != document_set.end(); + for (std::map::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, increase its count @@ -1027,8 +1018,8 @@ Application::add_document (SPDocument *document) // selection model for it, i.e. are we running without a desktop? if (!_use_gui) { // Create layer model and selection model so we can run some verbs without a GUI - g_assert(selection_models.find(document) == selection_models.end()); - selection_models[document] = new AppSelectionModel(document); + g_assert(_selection_models.find(document) == _selection_models.end()); + _selection_models[document] = new AppSelectionModel(document); } } } @@ -1040,20 +1031,20 @@ Application::remove_document (SPDocument *document) { g_return_val_if_fail (document != NULL, false); - for (std::map::iterator iter = document_set.begin(); - iter != document_set.end(); + for (std::map::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, decrease its count iter->second --; if (iter->second < 1) { // this was the last one, remove the pair from list - document_set.erase (iter); + _document_set.erase (iter); // also remove the selection model - std::map::iterator sel_iter = selection_models.find(document); - if (sel_iter != selection_models.end()) { - selection_models.erase(sel_iter); + std::map::iterator sel_iter = _selection_models.find(document); + if (sel_iter != _selection_models.end()) { + _selection_models.erase(sel_iter); } return true; @@ -1069,11 +1060,11 @@ Application::remove_document (SPDocument *document) SPDesktop * Application::active_desktop() { - if (!desktops || desktops->empty()) { + if (!_desktops || _desktops->empty()) { return NULL; } - return desktops->front(); + return _desktops->front(); } SPDocument * @@ -1081,10 +1072,10 @@ Application::active_document() { if (SP_ACTIVE_DESKTOP) { return sp_desktop_document (SP_ACTIVE_DESKTOP); - } else if (!document_set.empty()) { + } else if (!_document_set.empty()) { // If called from the command line there will be no desktop // So 'fall back' to take the first listed document in the Inkscape instance - return document_set.begin()->first; + return _document_set.begin()->first; } return NULL; @@ -1096,7 +1087,7 @@ Application::sole_desktop_for_document(SPDesktop const &desktop) { if (!document) { return false; } - for ( std::vector::iterator iter = desktops->begin(), e = desktops->end() ; iter != e; ++iter ) { + for ( std::vector::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e; ++iter ) { SPDesktop *other_desktop = *iter; SPDocument *other_document = other_desktop->doc(); if ( other_document == document && other_desktop != &desktop ) { @@ -1135,7 +1126,7 @@ Inkscape::ActionContext Application::action_context_for_document(SPDocument *doc) { // If there are desktops, check them first to see if the document is bound to one of them - for (std::vector::iterator iter = desktops->begin(), e = desktops->end() ; iter != e ; ++iter) { + for (std::vector::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e ; ++iter) { SPDesktop *desktop = *iter; if (desktop->doc() == doc) { return Inkscape::ActionContext(desktop); @@ -1143,8 +1134,8 @@ Application::action_context_for_document(SPDocument *doc) } // Document is not associated with any desktops - maybe we're in command-line mode - std::map::iterator sel_iter = selection_models.find(doc); - if (sel_iter == selection_models.end()) { + std::map::iterator sel_iter = _selection_models.find(doc); + if (sel_iter == _selection_models.end()) { return Inkscape::ActionContext(); } return Inkscape::ActionContext(sel_iter->second->getSelection()); @@ -1158,7 +1149,7 @@ Application::action_context_for_document(SPDocument *doc) void Application::refresh_display () { - for (std::vector::iterator l = desktops->begin(), e = desktops->end(); l != e; ++l) { + for (std::vector::iterator l = _desktops->begin(), e = _desktops->end(); l != e; ++l) { (*l)->requestRedraw(); } } @@ -1172,7 +1163,7 @@ void Application::exit () { //emit shutdown signal so that dialogs could remember layout - signal_shut_down.emit(this); + signal_shut_down.emit(); Inkscape::Preferences::unload(); gtk_main_quit (); @@ -1186,8 +1177,8 @@ Application::homedir_path(const char *filename) homedir = g_get_home_dir(); } if (!homedir) { - if (inkscape) { - homedir = g_path_get_dirname(inkscape->_argv0); + if (Application::instance()) { + homedir = g_path_get_dirname(Application::instance()->_argv0); } } return g_build_filename(homedir, filename, NULL); @@ -1313,7 +1304,7 @@ Application::profile_path(const char *filename) Inkscape::XML::Node * Application::get_menus() { - Inkscape::XML::Node *repr = menus->root(); + Inkscape::XML::Node *repr = _menus->root(); g_assert (!(strcmp (repr->name(), "inkscape"))); return repr->firstChild(); } @@ -1321,7 +1312,7 @@ Application::get_menus() void Application::get_all_desktops(std::list< SPDesktop* >& listbuf) { - listbuf.insert(listbuf.end(), desktops->begin(), desktops->end()); + listbuf.insert(listbuf.end(), _desktops->begin(), _desktops->end()); } } // namespace Inkscape diff --git a/src/inkscape.h b/src/inkscape.h index 4b969bddb..821970748 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -48,7 +48,7 @@ struct Document; Inkscape::Application * inkscape_ref (Inkscape::Application * in); Inkscape::Application * inkscape_unref(Inkscape::Application * in); -#define INKSCAPE inkscape_get_instance() +#define INKSCAPE (Inkscape::Application::instance()) #define SP_INKSCAPE(obj) (dynamic_cast(obj)) #define SP_IS_INKSCAPE(obj) (dynamic_cast (obj) != NULL) #define SP_ACTIVE_EVENTCONTEXT (INKSCAPE->active_event_context()) @@ -76,23 +76,15 @@ public: namespace Inkscape { class Application { -private: - unsigned refCount; - gboolean _dialogs_toggle; - guint _mapalt; - guint _trackalt; - char * _argv0; - bool _use_gui; // may want to consider a virtual function - // for overriding things like the warning dlg's +protected: + static Inkscape::Application * _S_inst; -public: Application(const char* argv0, bool use_gui); ~Application(); - Inkscape::XML::Document *menus; - std::map document_set; - std::map selection_models; - std::vector * desktops; +public: + static Application* instance(); + static void init(const char* argv0, bool use_gui); // returns the mask of the keyboard modifier to map to Alt, zero if no mapping // Needs to be a guint because gdktypes.h does not define a 'no-modifier' value @@ -110,36 +102,8 @@ public: char const* argv0() const { return _argv0; } void argv0(char const *); - // signals - - // one of selections changed - sigc::signal signal_selection_changed; - // one of subselections (text selection, gradient handle, etc) changed - sigc::signal signal_subselection_changed; - // one of selections modified - sigc::signal signal_selection_modified; - // one of selections set - sigc::signal signal_selection_set; - // tool switched - sigc::signal signal_eventcontext_set; - // some desktop got focus - sigc::signal signal_activate_desktop; - // some desktop lost focus - sigc::signal signal_deactivate_desktop; - - // probably orphaned signals - sigc::signal signal_destroy_document; - sigc::signal signal_color_set; - - // inkscape is quitting - sigc::signal signal_shut_down; - // user pressed F12 - sigc::signal signal_dialogs_hide; - // user pressed F12 - sigc::signal signal_dialogs_unhide; - // a document was changed by some external means (undo or XML editor); this - // may not be reflected by a selection change and thus needs a separate signal - sigc::signal signal_external_change; + // no setter for this -- only we can control this variable + static bool isCrashing() { return _crashIsHappening; } // useful functions void autosave_init(); @@ -207,22 +171,57 @@ public: int autosave(); + // nobody should be accessing our reference count, so it's made private. friend Application * ::inkscape_ref (Application * in); friend Application * ::inkscape_unref(Application * in); -}; -} // namespace Inkscape - -bool inkscapeIsCrashing(); + // signals + + // one of selections changed + sigc::signal signal_selection_changed; + // one of subselections (text selection, gradient handle, etc) changed + sigc::signal signal_subselection_changed; + // one of selections modified + sigc::signal signal_selection_modified; + // one of selections set + sigc::signal signal_selection_set; + // tool switched + sigc::signal signal_eventcontext_set; + // some desktop got focus + sigc::signal signal_activate_desktop; + // some desktop lost focus + sigc::signal signal_deactivate_desktop; + + // these are orphaned signals (nothing emits them and nothing connects to them) + sigc::signal signal_destroy_document; + sigc::signal signal_color_set; + + // inkscape is quitting + sigc::signal signal_shut_down; + // user pressed F12 + sigc::signal signal_dialogs_hide; + // user pressed F12 + sigc::signal signal_dialogs_unhide; + // a document was changed by some external means (undo or XML editor); this + // may not be reflected by a selection change and thus needs a separate signal + sigc::signal signal_external_change; -// gets the current instance and calls autosave() -int inkscape_autosave(gpointer unused); +private: + Inkscape::XML::Document * _menus; + std::map _document_set; + std::map _selection_models; + std::vector * _desktops; -// hmm, I wonder what this does /s -Inkscape::Application* inkscape_get_instance(); + unsigned refCount; + bool _dialogs_toggle; + guint _mapalt; + guint _trackalt; + char * _argv0; + static bool _crashIsHappening; + bool _use_gui; +}; -// only temporary until I can properly clean this up -void inkscape_application_init (const gchar *argv0, gboolean use_gui); +} // namespace Inkscape #endif diff --git a/src/inkview.cpp b/src/inkview.cpp index f1be398f7..1ec8393ba 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -232,7 +232,8 @@ main (int argc, const char **argv) ss.view = NULL; ss.fullscreen = false; - inkscape = new Inkscape::Application(argv[0], true); + Inkscape::Application::init(argv[0], true); + inkscape = Inkscape::Application::instance(); // starting at where the commandline options stopped parsing because // we want all the files to be in the list diff --git a/src/main.cpp b/src/main.cpp index 77be9a275..8d978c5ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1059,7 +1059,7 @@ sp_main_gui(int argc, char const **argv) gboolean create_new = TRUE; /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. - inkscape_application_init(argv[0], true); + Inkscape::Application::init(argv[0], true); while (fl) { if (sp_file_open((gchar *)fl->data,NULL)) { @@ -1335,7 +1335,7 @@ int sp_main_console(int argc, char const **argv) exit(0); } - inkscape_application_init(argv[0], false); + Inkscape::Application::init(argv[0], false); if (sp_shell) { int retVal = sp_main_shell(argv[0]); // Run as interactive shell diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 35a9a8376..4fd2f0f9c 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1044,10 +1044,10 @@ AlignAndDistribute::AlignAndDistribute() contents->pack_start(_nodesFrame, true, true); //Connect to the global tool change signal - _toolChangeConn = INKSCAPE->signal_eventcontext_set.connect(sigc::hide<0>(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this)))); + _toolChangeConn = INKSCAPE->signal_eventcontext_set.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this))); // Connect to the global selection change, to invalidate cached randomize_bbox - _selChangeConn = INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_selection_changed), this)))); + _selChangeConn = INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_selection_changed), this))); randomize_bbox = Geom::OptRect(); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &AlignAndDistribute::setDesktop) ); diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 4d5d50de0..84ef0b5b0 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1269,8 +1269,8 @@ CloneTiler::CloneTiler () : // connect to global selection changed signal (so we can change desktops) and // external_change (so we're not fooled by undo) - selectChangedConn = INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_change_selection), dlg))); - externChangedConn = INKSCAPE->signal_external_change.connect (sigc::hide<0>(sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_external_change), dlg))); + selectChangedConn = INKSCAPE->signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_change_selection), dlg)); + externChangedConn = INKSCAPE->signal_external_change.connect (sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_external_change), dlg)); g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), this); diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 06f0216a7..5eb9ea054 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -41,10 +41,9 @@ void DesktopTracker::connect(GtkWidget *widget) // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); inkID = INKSCAPE->signal_activate_desktop.connect( - sigc::hide<0>( sigc::bind( - sigc::ptr_fun(&DesktopTracker::activateDesktopCB), this) - )); + sigc::ptr_fun(&DesktopTracker::activateDesktopCB), this) + ); GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); if (wdgt && !base) { diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index d0da70a60..72ca117f7 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -73,10 +73,10 @@ Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_pat _behavior = behavior_factory(*this); _desktop = SP_ACTIVE_DESKTOP; - INKSCAPE->signal_activate_desktop.connect(sigc::hide<0>(sigc::mem_fun(*this, &Dialog::onDesktopActivated))); - INKSCAPE->signal_dialogs_hide.connect(sigc::hide<0>(sigc::mem_fun(*this, &Dialog::onHideF12))); - INKSCAPE->signal_dialogs_unhide.connect(sigc::hide<0>(sigc::mem_fun(*this, &Dialog::onShowF12))); - INKSCAPE->signal_shut_down.connect(sigc::hide<0>(sigc::mem_fun(*this, &Dialog::onShutdown))); + INKSCAPE->signal_activate_desktop.connect(sigc::mem_fun(*this, &Dialog::onDesktopActivated)); + INKSCAPE->signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dialog::onHideF12)); + INKSCAPE->signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dialog::onShowF12)); + INKSCAPE->signal_shut_down.connect(sigc::mem_fun(*this, &Dialog::onShutdown)); Glib::wrap(gobj())->signal_event().connect(sigc::mem_fun(*this, &Dialog::_onEvent)); Glib::wrap(gobj())->signal_key_press_event().connect(sigc::mem_fun(*this, &Dialog::_onKeyPress)); diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index c4281babc..38e359b28 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -539,7 +539,7 @@ bool SVGPreview::set(Glib::ustring &fileName, int dialogType) SVGPreview::SVGPreview() { if (!INKSCAPE) - inkscape_application_init("", false); + Inkscape::Application::init("", false); document = NULL; viewerGtk = NULL; set_size_request(150, 150); diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 028c94ec1..f7c035ebe 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -594,7 +594,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) { // Selection Change signal - INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::hide<0>(sigc::mem_fun(*this, &GridArrangeTab::updateSelection)))); + INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::mem_fun(*this, &GridArrangeTab::updateSelection))); } Gtk::Box *contents = this; diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index 470d0d1b3..b3beb73c6 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,15 +49,6 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - /*static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast(data)->_propagateDesktopDeactivated(application, desktop); - } - - static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast(data)->_propagateDesktopActivated(application, desktop); - }*/ inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *); @@ -247,8 +238,14 @@ PanelDialog *PanelDialog new PanelDialog(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel()); - INKSCAPE->signal_activate_desktop.connect (sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopActivated)); - INKSCAPE->signal_deactivate_desktop.connect(sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopDeactivated)); + INKSCAPE->signal_activate_desktop.connect( + sigc::bind<0>( + sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopActivated), INKSCAPE + )); + INKSCAPE->signal_deactivate_desktop.connect( + sigc::bind<0>( + sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopDeactivated), INKSCAPE + )); return instance; } diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 8bc9ad275..c36da373f 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -156,8 +156,8 @@ Transformation::Transformation() } // Connect to the global selection changed & modified signals - _selChangeConn = INKSCAPE->signal_selection_changed.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_selection_changed), this))); - _selModifyConn = INKSCAPE->signal_selection_modified.connect(sigc::hide<0>(sigc::hide<1>(sigc::bind(sigc::ptr_fun(&on_selection_modified), this)))); + _selChangeConn = INKSCAPE->signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&on_selection_changed), this)); + _selModifyConn = INKSCAPE->signal_selection_modified.connect(sigc::hide<1>(sigc::bind(sigc::ptr_fun(&on_selection_modified), this))); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Transformation::setDesktop) ); _deskTrack.connect(GTK_WIDGET(gobj())); diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp index 3448283b9..f23e4bcca 100644 --- a/src/ui/widget/dock.cpp +++ b/src/ui/widget/dock.cpp @@ -120,8 +120,8 @@ Dock::Dock(Gtk::Orientation orientation) gdl_dock_bar_set_style(_gdl_dock_bar, gdl_dock_bar_style); - INKSCAPE->signal_dialogs_hide.connect(sigc::hide(sigc::mem_fun(*this, &Dock::hide))); - INKSCAPE->signal_dialogs_unhide.connect(sigc::hide(sigc::mem_fun(*this, &Dock::show))); + INKSCAPE->signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dock::hide)); + INKSCAPE->signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dock::show)); g_signal_connect(_paned->gobj(), "button-press-event", G_CALLBACK(_on_paned_button_event), (void *)this); g_signal_connect(_paned->gobj(), "button-release-event", G_CALLBACK(_on_paned_button_event), (void *)this); diff --git a/src/ui/widget/imageicon.cpp b/src/ui/widget/imageicon.cpp index 22abd04ba..0ccff0c9e 100644 --- a/src/ui/widget/imageicon.cpp +++ b/src/ui/widget/imageicon.cpp @@ -88,8 +88,9 @@ ImageIcon::~ImageIcon() */ void ImageIcon::init() { + // \FIXME Why? if (!INKSCAPE) - inkscape_application_init("",false); + Inkscape::Application::init("", false); document = NULL; viewerGtkmm = NULL; //set_size_request(150,150); diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 9fb439a28..9c27da1f8 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -1033,19 +1033,18 @@ GtkWidget * sp_gradient_vector_editor_new(SPGradient *gradient, SPStop *stop) wd.win = dlg; wd.stop = 0; - INKSCAPE->signal_activate_desktop.connect(sigc::bind(sigc::ptr_fun(&sp_transientize_callback), &wd)); + INKSCAPE->signal_activate_desktop.connect(sigc::bind<0>(sigc::bind(sigc::ptr_fun(&sp_transientize_callback), &wd), INKSCAPE)); g_signal_connect(G_OBJECT(dlg), "event", G_CALLBACK(sp_dialog_event_handler), dlg); g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(sp_gradient_vector_dialog_destroy), dlg); g_signal_connect(G_OBJECT(dlg), "delete_event", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); INKSCAPE->signal_shut_down.connect( - sigc::hide<0>( sigc::hide_return( sigc::bind(sigc::ptr_fun(&sp_gradient_vector_dialog_delete), (GtkWidget *) NULL, (GdkEvent *) NULL, (GtkWidget *) NULL) - ))); - INKSCAPE->signal_dialogs_hide.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(>k_widget_hide), dlg))); - INKSCAPE->signal_dialogs_unhide.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(>k_widget_show), dlg))); + )); + INKSCAPE->signal_dialogs_hide.connect(sigc::bind(sigc::ptr_fun(>k_widget_hide), dlg)); + INKSCAPE->signal_dialogs_unhide.connect(sigc::bind(sigc::ptr_fun(>k_widget_show), dlg)); gtk_container_set_border_width(GTK_CONTAINER(dlg), PAD); diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 0814d56d6..214990b6b 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -1568,7 +1568,7 @@ void IconImpl::addPreRender( GtkIconSize lsize, gchar const *name ) } gboolean IconImpl::prerenderTask(gpointer /*data*/) { - if ( inkscapeIsCrashing() ) { + if ( Inkscape::Application::isCrashing() ) { // stop } else if (!pendingRenders.empty()) { bool workDone = false; @@ -1580,7 +1580,7 @@ gboolean IconImpl::prerenderTask(gpointer /*data*/) { } while (!pendingRenders.empty() && !workDone); } - if (!inkscapeIsCrashing() && !pendingRenders.empty()) { + if (!Inkscape::Application::isCrashing() && !pendingRenders.empty()) { return TRUE; } else { callbackHooked = false; diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index 322b444b9..08344d9b2 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -211,12 +211,21 @@ void SPWidgetImpl::show(GtkWidget *widget) if (spw->inkscape) { // Connect signals - spw->selModified = spw->inkscape->signal_selection_modified.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw)); - spw->selChanged = spw->inkscape->signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw)); - spw->selSet = spw->inkscape->signal_selection_set.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw)); - //g_signal_connect(spw->inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw); - //g_signal_connect(spw->inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw); - //g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); + spw->selModified = spw->inkscape->signal_selection_modified.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw), spw->inkscape + )); + spw->selChanged = spw->inkscape->signal_selection_changed.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw), spw->inkscape + )); + spw->selSet = spw->inkscape->signal_selection_set.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw), spw->inkscape + )); } if (reinterpret_cast(parentClass)->show) { @@ -233,7 +242,6 @@ void SPWidgetImpl::hide(GtkWidget *widget) spw->selModified.disconnect(); spw->selChanged.disconnect(); spw->selSet.disconnect(); - //sp_signal_disconnect_by_data(spw->inkscape, spw); } if (reinterpret_cast(parentClass)->hide) { @@ -311,9 +319,21 @@ GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, Inkscape::Application *i spw->inkscape = inkscape; if (gtk_widget_get_visible(GTK_WIDGET(spw))) { - spw->selModified = spw->inkscape->signal_selection_modified.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw)); - spw->selChanged = spw->inkscape->signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw)); - spw->selSet = spw->inkscape->signal_selection_set.connect(sigc::bind(sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw)); + spw->selModified = spw->inkscape->signal_selection_modified.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw), spw->inkscape + )); + spw->selChanged = spw->inkscape->signal_selection_changed.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw), spw->inkscape + )); + spw->selSet = spw->inkscape->signal_selection_set.connect( + sigc::bind<0>( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw), spw->inkscape + )); } g_signal_emit(spw, signals[CONSTRUCT], 0); -- cgit v1.2.3