[gnote] Integrate with GtkApplication



commit 06696e9e816441e50e9fe2d78aa694f8d572419a
Author: Aurimas Äernius <aurisc4 gmail com>
Date:   Sun Oct 30 00:05:33 2011 +0300

    Integrate with GtkApplication
    
    Use GtkApplication for application uniqueness and command line handling.
    Also rewrite startup code and exporting D-Bus object accordingly.
    Make Gnote run while at least one window is present.
    Also fixes bug 640430.

 src/gnote.cpp              |  162 ++++++++++++++++++++++++++++++++++++-------
 src/gnote.hpp              |   12 +++
 src/note.cpp               |   16 +++++
 src/note.hpp               |    3 +
 src/recentchanges.cpp      |   15 +++-
 src/recentchanges.hpp      |    1 +
 src/remotecontrolproxy.cpp |   13 +++-
 src/remotecontrolproxy.hpp |    2 +
 8 files changed, 190 insertions(+), 34 deletions(-)
---
diff --git a/src/gnote.cpp b/src/gnote.cpp
index 593a5e8..6edbc18 100644
--- a/src/gnote.cpp
+++ b/src/gnote.cpp
@@ -63,11 +63,57 @@
 
 namespace gnote {
 
+  namespace {
+
+    typedef GtkApplicationClass GnoteAppClass;
+
+    G_DEFINE_TYPE(GnoteApp, gnote_app, GTK_TYPE_APPLICATION)
+
+    static void gnote_app_init(GnoteApp *)
+    {}
+
+    static void gnote_app_activate(GApplication *)
+    {
+      Gnote::obj().open_search_all();
+    }
+
+    static void gnote_app_startup(GApplication *)
+    {
+      Gnote::obj().startup();
+    }
+
+    static int gnote_app_command_line(GApplication *, GApplicationCommandLine * command_line)
+    {
+      int argc;
+      char **argv = g_application_command_line_get_arguments(command_line, &argc);
+      return Gnote::obj().command_line(argc, argv);
+    }
+
+    static void gnote_app_class_init(GnoteAppClass * klass)
+    {
+      G_APPLICATION_CLASS(klass)->activate = gnote_app_activate;
+      G_APPLICATION_CLASS(klass)->startup = gnote_app_startup;
+      G_APPLICATION_CLASS(klass)->command_line = gnote_app_command_line;
+    }
+
+    GnoteApp * gnote_app_new()
+    {
+      g_type_init();
+      return static_cast<GnoteApp*>(g_object_new(gnote_app_get_type(),
+                                                 "application-id", "org.gnome.Gnote",
+                                                 "flags", G_APPLICATION_HANDLES_COMMAND_LINE,
+                                                 NULL));
+    }
+
+}
+
+
   Gnote::Gnote()
     : m_manager(NULL)
     , m_keybinder(NULL)
     , m_is_panel_applet(false)
     , m_prefsdlg(NULL)
+    , m_app(NULL)
   {
   }
 
@@ -81,54 +127,89 @@ namespace gnote {
 
   int Gnote::main(int argc, char **argv)
   {
-    cmd_line.parse(argc, argv);
-    if(cmd_line.needs_immediate_execute()) {
+    bool handle = false;
+    for(int i = 0; i < argc; ++i) {
+      if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "--version")) {
+        handle = true;
+        break;
+      }
+      else if(!strcmp(argv[i], "--panel-applet")) {
+        m_is_panel_applet = true;
+        break;
+      }
+    }
+
+    if(handle) {
+      cmd_line.parse(argc, argv);
       cmd_line.immediate_execute();
       return 0;
     }
 
-    m_is_panel_applet = cmd_line.use_panel_applet();
-    m_icon_theme = Gtk::IconTheme::get_default();
-    m_icon_theme->append_search_path(DATADIR"/icons");
-    m_icon_theme->append_search_path(DATADIR"/gnote/icons");
-
-    std::string note_path = get_note_path(cmd_line.note_path());
-    m_manager = new NoteManager(note_path, sigc::mem_fun(*this, &Gnote::start_note_created));
-    m_keybinder = new XKeybinder();
-
-    // TODO
-    // SyncManager::init()
-
-    ActionManager & am(ActionManager::obj());
-    am.load_interface();
-    register_remote_control(*m_manager, sigc::mem_fun(*this, &Gnote::end_main));
-    setup_global_actions();
-    m_manager->get_addin_manager().initialize_application_addins();
-
     if(m_is_panel_applet) {
+#if HAVE_PANELAPPLET
+      common_init();
+      ActionManager & am(ActionManager::obj());
       am["CloseWindowAction"]->set_visible(true);
       am["QuitGNoteAction"]->set_visible(false);
+      register_remote_control(*m_manager, sigc::mem_fun(*this, &Gnote::end_main));
+      panel::register_applet();
+#endif
     }
     else {
+      m_app = gnote_app_new();
+      g_application_run(G_APPLICATION(m_app), argc, argv);
+      g_object_unref(m_app);
+      m_app = NULL;
+    }
+    signal_quit();
+    return 0;
+  }
+
+
+  void Gnote::startup()
+  {
+    m_icon_theme = Gtk::IconTheme::get_default();
+    m_icon_theme->append_search_path(DATADIR"/icons");
+    m_icon_theme->append_search_path(DATADIR"/gnote/icons");
+  }
+
+
+  int Gnote::command_line(int argc, char **argv) {
+    cmd_line.parse(argc, argv);
+    if(!m_manager) {
+      common_init();
       Glib::RefPtr<Gio::Settings> settings = Preferences::obj()
         .get_schema_settings(Preferences::SCHEMA_GNOTE);
       settings->signal_changed()
         .connect(sigc::mem_fun(*this, &Gnote::on_setting_changed));
+      register_object();
     }
-
-    if(m_is_panel_applet) {
-#if HAVE_PANELAPPLET
-      panel::register_applet();
-#endif
+    else if(cmd_line.needs_execute()) {
+      cmd_line.execute();
     }
     else {
-      Gtk::Main::run();
+      ActionManager::obj()["ShowSearchAllNotesAction"]->activate();
     }
-    signal_quit();
+
     return 0;
   }
 
 
+  void Gnote::common_init()
+  {
+    std::string note_path = get_note_path(cmd_line.note_path());
+    m_manager = new NoteManager(note_path, sigc::mem_fun(*this, &Gnote::start_note_created));
+    m_keybinder = new XKeybinder();
+
+    // TODO
+    // SyncManager::init()
+
+    ActionManager::obj().load_interface();
+    setup_global_actions();
+    m_manager->get_addin_manager().initialize_application_addins();
+  }
+
+
   void Gnote::end_main(bool bus_acquired, bool name_acquired)
   {
     if(cmd_line.needs_execute()) {
@@ -202,6 +283,9 @@ namespace gnote {
 
   void Gnote::start_tray_icon()
   {
+    // Create Search All Notes window as we need it present for application to run
+    NoteRecentChanges::get_instance(default_note_manager());
+
     // Create the tray icon and run the main loop
     m_tray_icon = Glib::RefPtr<TrayIcon>(new TrayIcon(default_note_manager()));
     m_tray = m_tray_icon->tray();
@@ -238,6 +322,14 @@ namespace gnote {
   }
 
 
+  void Gnote::register_object()
+  {
+    RemoteControlProxy::register_object(Gio::DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SESSION),
+                                        Gnote::obj().default_note_manager(),
+                                        sigc::mem_fun(Gnote::obj(), &Gnote::end_main));
+  }
+
+
   void Gnote::on_setting_changed(const Glib::ustring & key)
   {
     if(key != Preferences::USE_STATUS_ICON) {
@@ -407,6 +499,22 @@ namespace gnote {
   }
 
 
+  void Gnote::add_window(Gtk::Window * window)
+  {
+    if(m_app) {
+      gtk_application_add_window(GTK_APPLICATION(m_app), GTK_WINDOW(window->gobj()));
+    }
+  }
+
+
+  void Gnote::remove_window(Gtk::Window * window)
+  {
+    if(m_app) {
+      gtk_application_remove_window(GTK_APPLICATION(m_app), GTK_WINDOW(window->gobj()));
+    }
+  }
+
+
   std::string Gnote::cache_dir()
   {
     return Glib::get_user_cache_dir() + "/gnote";
diff --git a/src/gnote.hpp b/src/gnote.hpp
index d02802a..8fb2cb0 100644
--- a/src/gnote.hpp
+++ b/src/gnote.hpp
@@ -39,6 +39,7 @@
 
 namespace gnote {
 
+typedef GtkApplication GnoteApp;
 class PreferencesDialog;
 class NoteManager;
 class RemoteControlClient;
@@ -102,6 +103,8 @@ public:
   Gnote();
   ~Gnote();
   int main(int argc, char **argv);
+  void startup();
+  int command_line(int argc, char **argv);
   NoteManager & default_note_manager()
     {
       return *m_manager;
@@ -123,6 +126,8 @@ public:
   void on_show_about_action();
   void open_search_all();
   void open_note_sync_window();
+  void add_window(Gtk::Window * window);
+  void remove_window(Gtk::Window * window);
 
   static std::string cache_dir();
   static std::string conf_dir();
@@ -138,16 +143,22 @@ public:
     {
       return m_is_panel_applet;
     }
+  bool windowed()
+    {
+      return !tray_icon_showing();
+    }
   void set_tray(const Tray::Ptr & tray)
     {
       m_tray = tray;
     }
   sigc::signal<void> signal_quit;
   static void register_remote_control(NoteManager & manager, RemoteControlProxy::slot_name_acquire_finish on_finish);
+  static void register_object();
 private:
   void start_note_created(const Note::Ptr & start_note);
   std::string get_note_path(const std::string & override_path);
   void on_setting_changed(const Glib::ustring & key);
+  void common_init();
   void end_main(bool bus_aquired, bool name_acquired);
 
   NoteManager *m_manager;
@@ -158,6 +169,7 @@ private:
   bool m_is_panel_applet;
   PreferencesDialog *m_prefsdlg;
   GnoteCommandLine cmd_line;
+  GnoteApp *m_app;
 };
 
 
diff --git a/src/note.cpp b/src/note.cpp
index 527b0b4..1e4a086 100644
--- a/src/note.cpp
+++ b/src/note.cpp
@@ -37,6 +37,7 @@
 #include <gtkmm/button.h>
 #include <gtkmm/stock.h>
 
+#include "gnote.hpp"
 #include "note.hpp"
 #include "notemanager.hpp"
 #include "noterenamedialog.hpp"
@@ -1025,6 +1026,10 @@ namespace gnote {
         sigc::mem_fun(*this, &Note::on_window_destroyed));
       m_window->signal_configure_event().connect(
         sigc::mem_fun(*this, &Note::on_window_configure), false);
+      m_window->signal_show().connect(
+        sigc::mem_fun(*this, &Note::on_window_show));
+      m_window->signal_hide().connect(
+        sigc::mem_fun(*this, &Note::on_window_hide));
 
       if (m_data.data().has_extent())
         m_window->set_default_size(m_data.data().width(),
@@ -1044,6 +1049,17 @@ namespace gnote {
     return m_window;
   }
 
+  void Note::on_window_show()
+  {
+    Gnote::obj().add_window(m_window);
+  }
+
+
+  void Note::on_window_hide()
+  {
+    Gnote::obj().remove_window(m_window);
+  }
+
 
   bool Note::is_special() const
   { 
diff --git a/src/note.hpp b/src/note.hpp
index 71ee475..62480f9 100644
--- a/src/note.hpp
+++ b/src/note.hpp
@@ -383,6 +383,9 @@ private:
 
   Note(NoteData * data, const std::string & filepath, NoteManager & manager);
 
+  void on_window_show();
+  void on_window_hide();
+
   struct ChildWidgetData
   {
     ChildWidgetData(const Glib::RefPtr<Gtk::TextChildAnchor> & _anchor,
diff --git a/src/recentchanges.cpp b/src/recentchanges.cpp
index 49b2f6d..6193719 100644
--- a/src/recentchanges.cpp
+++ b/src/recentchanges.cpp
@@ -102,6 +102,7 @@ namespace gnote {
     , m_entry_changed_timeout(NULL)
     , m_clickX(0), m_clickY(0)
   {
+    Gnote::obj().add_window(this);
     _init_static();
 //    get_window()->set_icon_name("gnote");
     set_default_size(450,400);
@@ -235,6 +236,13 @@ namespace gnote {
 
   }
 
+
+  NoteRecentChanges::~NoteRecentChanges()
+  {
+    Gnote::obj().remove_window(this);
+  }
+
+
   Gtk::MenuBar *NoteRecentChanges::create_menu_bar ()
   {
     ActionManager &am(ActionManager::obj());
@@ -1205,10 +1213,9 @@ namespace gnote {
 //    Tomboy.ExitingEvent -= OnExitingEvent;
 
     hide ();
-    delete s_instance;
-    s_instance = NULL;
-    if (Gnote::obj().tray_icon_showing() == false) {
-      ActionManager::obj()["QuitGNoteAction"]->activate();
+    if(Gnote::obj().windowed()) {
+      delete s_instance;
+      s_instance = NULL;
     }
   }
 
diff --git a/src/recentchanges.hpp b/src/recentchanges.hpp
index 2b2940b..3a296df 100644
--- a/src/recentchanges.hpp
+++ b/src/recentchanges.hpp
@@ -63,6 +63,7 @@ public:
   static NoteRecentChanges *get_instance();
   static NoteRecentChanges *get_instance(NoteManager& m);
 
+  virtual ~NoteRecentChanges();
   void set_search_text(const std::string & value);
 
 //////
diff --git a/src/remotecontrolproxy.cpp b/src/remotecontrolproxy.cpp
index ebbb068..8e761be 100644
--- a/src/remotecontrolproxy.cpp
+++ b/src/remotecontrolproxy.cpp
@@ -85,9 +85,7 @@ void RemoteControlProxy::on_name_acquired(const Glib::RefPtr<Gio::DBus::Connecti
 {
   try {
     if(s_bus_acquired) {
-      load_introspection_xml();
-      s_remote_control = new RemoteControl(conn, *s_manager, GNOTE_SERVER_PATH, GNOTE_INTERFACE_NAME, s_gnote_interface);
-      s_on_name_acquire_finish(true, true);
+      register_object(conn, *s_manager, s_on_name_acquire_finish);
       return;
     }
   }
@@ -99,6 +97,15 @@ void RemoteControlProxy::on_name_acquired(const Glib::RefPtr<Gio::DBus::Connecti
 }
 
 
+void RemoteControlProxy::register_object(const Glib::RefPtr<Gio::DBus::Connection> & conn, NoteManager & manager,
+                                         const slot_name_acquire_finish & on_finish)
+{
+  load_introspection_xml();
+  s_remote_control = new RemoteControl(conn, manager, GNOTE_SERVER_PATH, GNOTE_INTERFACE_NAME, s_gnote_interface);
+  on_finish(true, true);
+}
+
+
 void RemoteControlProxy::on_name_lost(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &)
 {
   s_on_name_acquire_finish(s_bus_acquired, false);
diff --git a/src/remotecontrolproxy.hpp b/src/remotecontrolproxy.hpp
index 0a352a9..176ce83 100644
--- a/src/remotecontrolproxy.hpp
+++ b/src/remotecontrolproxy.hpp
@@ -45,6 +45,8 @@ public:
   static Glib::RefPtr<RemoteControlClient> get_instance();
   static RemoteControl *get_remote_control();
   static void register_remote(NoteManager & manager, const slot_name_acquire_finish & on_finish);
+  static void register_object(const Glib::RefPtr<Gio::DBus::Connection> & conn, NoteManager & manager,
+                              const slot_name_acquire_finish & on_finish);
 private:
   static void on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection> & conn, const Glib::ustring & name);
   static void on_name_acquired(const Glib::RefPtr<Gio::DBus::Connection> & conn, const Glib::ustring & name);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]