[gnote] Add application menu



commit 7c2f3dd87a0e0dec90e206310d943a1e036fb4bb
Author: Aurimas Äernius <aurisc4 gmail com>
Date:   Sat Oct 13 21:42:06 2012 +0300

    Add application menu
    
    * Add application menu facility to ActionManager
    * Actualy implement application menu

 src/actionmanager.cpp |   99 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/actionmanager.hpp |   48 ++++++++++++++++++++++++
 src/gnote.cpp         |   65 ++++++++++++++++++++++++++++---
 src/gnote.hpp         |   11 ++++-
 4 files changed, 213 insertions(+), 10 deletions(-)
---
diff --git a/src/actionmanager.cpp b/src/actionmanager.cpp
index d1e6bb7..63ea472 100644
--- a/src/actionmanager.cpp
+++ b/src/actionmanager.cpp
@@ -69,11 +69,19 @@
 
 namespace gnote {
 
+  const int ActionManager::APP_ACTION_NEW = 1;
+  const int ActionManager::APP_ACTION_MANAGE = 2;
+  const int ActionManager::APP_ACTION_HELP = 3;
+  const int ActionManager::APP_ACTION_LAST = 4;
+
+
   ActionManager::ActionManager()
     : m_ui(Gtk::UIManager::create())
     , m_main_window_actions(Gtk::ActionGroup::create("MainWindow"))
   {
     populate_action_groups();
+    make_app_actions();
+    make_app_menu_items();
     m_newNote = utils::get_icon("note-new", 16);
     DBG_ASSERT(m_newNote, "note-new icon not found");
   }
@@ -259,4 +267,95 @@ namespace gnote {
     return Glib::RefPtr<Gtk::Action>();      
   }
 
+  void ActionManager::make_app_actions()
+  {
+    add_app_action("new-note");
+    add_app_action("new-window");
+    add_app_action("about");
+    add_app_action("help-contents");
+    add_app_action("quit");
+  }
+
+  Glib::RefPtr<Gio::SimpleAction> ActionManager::get_app_action(const std::string & name) const
+  {
+    for(std::vector<Glib::RefPtr<Gio::SimpleAction> >::const_iterator iter = m_app_actions.begin();
+        iter != m_app_actions.end(); ++iter) {
+      if((*iter)->get_name() == name) {
+        return *iter;
+      }
+    }
+    
+    return Glib::RefPtr<Gio::SimpleAction>();
+  }
+
+  void ActionManager::add_app_action(const std::string & name)
+  {
+    m_app_actions.push_back(Gio::SimpleAction::create(name));
+  }
+
+  void ActionManager::add_app_menu_item(int section, int order, const std::string & label,
+                                        const std::string & action_def)
+  {
+    m_app_menu_items.insert(std::make_pair(section, AppMenuItem(order, label, action_def)));
+  }
+
+  void ActionManager::make_app_menu_items()
+  {
+    add_app_menu_item(APP_ACTION_NEW, 100, _("_New Note"), "app.new-note");
+    add_app_menu_item(APP_ACTION_NEW, 200, _("New _Window"), "app.new-window");
+    add_app_menu_item(APP_ACTION_HELP, 100, _("Help _Contents"), "app.help-contents");
+    add_app_menu_item(APP_ACTION_HELP, 200, _("_About"), "app.about");
+    add_app_menu_item(APP_ACTION_LAST, 100, _("_Quit"), "app.quit");
+  }
+
+  Glib::RefPtr<Gio::Menu> ActionManager::get_app_menu() const
+  {
+    Glib::RefPtr<Gio::Menu> menu = Gio::Menu::create();
+
+    int pos = 0;
+    Glib::RefPtr<Gio::Menu> section = make_app_menu_section(APP_ACTION_NEW);
+    if(section != 0) {
+      menu->insert_section(pos++, "", section);
+    }
+
+    section = make_app_menu_section(APP_ACTION_MANAGE);
+    if(section != 0) {
+      menu->insert_section(pos++, "", section);
+    }
+
+    section = make_app_menu_section(APP_ACTION_HELP);
+    if(section != 0) {
+      menu->insert_section(pos++, "", section);
+    }
+
+    section = make_app_menu_section(APP_ACTION_LAST);
+    if(section != 0) {
+      menu->insert_section(pos++, "", section);
+    }
+
+    return menu;
+  }
+
+  Glib::RefPtr<Gio::Menu> ActionManager::make_app_menu_section(int sec) const
+  {
+    std::pair<AppMenuItemMultiMap::const_iterator, AppMenuItemMultiMap::const_iterator>
+    range = m_app_menu_items.equal_range(sec);
+
+    Glib::RefPtr<Gio::Menu> section;
+    if(range.first != m_app_menu_items.end()) {
+      std::vector<const AppMenuItem*> menu_items;
+      for(AppMenuItemMultiMap::const_iterator iter = range.first; iter != range.second; ++iter) {
+        menu_items.push_back(&iter->second);
+      }
+      std::sort(menu_items.begin(), menu_items.end(), AppMenuItem::ptr_comparator());
+
+      section = Gio::Menu::create();
+      for(std::vector<const AppMenuItem*>::iterator iter = menu_items.begin(); iter != menu_items.end(); ++iter) {
+        section->append((*iter)->label, (*iter)->action_def);
+      }
+    }
+
+    return section;
+  }
+
 }
diff --git a/src/actionmanager.hpp b/src/actionmanager.hpp
index d4794c3..306e329 100644
--- a/src/actionmanager.hpp
+++ b/src/actionmanager.hpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2012 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -20,9 +21,13 @@
 #ifndef __ACTIONMANAGER_HPP_
 #define __ACTIONMANAGER_HPP_
 
+#include <map>
 #include <string>
 #include <list>
 
+#include <glibmm/variant.h>
+#include <giomm/menu.h>
+#include <giomm/simpleaction.h>
 #include <gtkmm/action.h>
 #include <gtkmm/uimanager.h>
 #include <gdkmm/pixbuf.h>
@@ -35,6 +40,11 @@ class ActionManager
   : public base::Singleton<ActionManager>
 {
 public:
+  static const int APP_ACTION_NEW;
+  static const int APP_ACTION_MANAGE;
+  static const int APP_ACTION_HELP;
+  static const int APP_ACTION_LAST;
+
   ActionManager();
 
   Glib::RefPtr<Gtk::Action> operator[](const std::string & n) const
@@ -57,10 +67,48 @@ public:
     {
       return m_newNote;
     }
+  Glib::RefPtr<Gio::SimpleAction> get_app_action(const std::string & name) const;
+  const std::vector<Glib::RefPtr<Gio::SimpleAction> > & get_app_actions() const
+    {
+      return m_app_actions;
+    }
+  void add_app_action(const std::string & name);
+  void add_app_menu_item(int section, int order, const std::string & label,
+                         const std::string & action_def);
+  Glib::RefPtr<Gio::Menu> get_app_menu() const;
 private:
+  void make_app_actions();
+  void make_app_menu_items();
+  Glib::RefPtr<Gio::Menu> make_app_menu_section(int section) const;
+
   Glib::RefPtr<Gtk::UIManager> m_ui;
   Glib::RefPtr<Gtk::ActionGroup> m_main_window_actions;
   Glib::RefPtr<Gdk::Pixbuf> m_newNote;
+
+  std::vector<Glib::RefPtr<Gio::SimpleAction> > m_app_actions;
+
+  struct AppMenuItem
+  {
+    int order;
+    std::string label;
+    std::string action_def;
+
+    AppMenuItem(int ord, const std::string & lbl, const std::string & act_def)
+      : order(ord)
+      , label(lbl)
+      , action_def(act_def)
+      {}
+
+    struct ptr_comparator
+    {
+      bool operator() (const AppMenuItem *x, const AppMenuItem *y)
+        {
+          return x->order < y->order;
+        }
+    };
+  };
+  typedef std::multimap<int, AppMenuItem> AppMenuItemMultiMap;
+  AppMenuItemMultiMap m_app_menu_items;
 };
 
 
diff --git a/src/gnote.cpp b/src/gnote.cpp
index ddc02d4..8df6787 100644
--- a/src/gnote.cpp
+++ b/src/gnote.cpp
@@ -187,6 +187,8 @@ namespace gnote {
       }
     }
 
+    make_app_actions();
+    make_app_menu();
     Glib::RefPtr<Gio::Settings> settings = Preferences::obj()
       .get_schema_settings(Preferences::SCHEMA_GNOTE);
     if(settings->get_boolean(Preferences::USE_STATUS_ICON)) {
@@ -281,13 +283,13 @@ namespace gnote {
       .connect(sigc::mem_fun(*this, &Gnote::on_new_note_action));
 #endif
     am["QuitGNoteAction"]->signal_activate()
-      .connect(sigc::mem_fun(*this, &Gnote::on_quit_gnote_action));
+      .connect(sigc::mem_fun(*this, &Gnote::quit));
     am["ShowPreferencesAction"]->signal_activate() 
       .connect(sigc::mem_fun(*this, &Gnote::on_show_preferences_action));
     am["ShowHelpAction"]->signal_activate()
-      .connect(sigc::mem_fun(*this, &Gnote::on_show_help_action));
+      .connect(boost::bind(sigc::mem_fun(*this, &Gnote::on_show_help_action), Glib::VariantBase()));
     am["ShowAboutAction"]->signal_activate()
-      .connect(sigc::mem_fun(*this, &Gnote::on_show_about_action));
+      .connect(boost::bind(sigc::mem_fun(*this, &Gnote::on_show_about_action), Glib::VariantBase()));
     am["TrayNewNoteAction"]->signal_activate()
       .connect(sigc::mem_fun(*this, &Gnote::on_new_note_action));
     am["ShowSearchAllNotesAction"]->signal_activate()
@@ -314,7 +316,7 @@ namespace gnote {
     }    
   }
 
-  void Gnote::on_quit_gnote_action()
+  void Gnote::on_quit_gnote_action(const Glib::VariantBase&)
   {
     quit();
   }
@@ -336,7 +338,7 @@ namespace gnote {
     m_prefsdlg->present();
   }
 
-  void Gnote::on_show_help_action()
+  void Gnote::on_show_help_action(const Glib::VariantBase&)
   {
     GdkScreen *cscreen = NULL;
     if(m_tray_icon) {
@@ -347,7 +349,7 @@ namespace gnote {
     utils::show_help("gnote", "", cscreen, NULL);
   }
 
-  void Gnote::on_show_about_action()
+  void Gnote::on_show_about_action(const Glib::VariantBase&)
   {
     std::vector<Glib::ustring> authors;
     authors.push_back("Aurimas Äernius <aurisc4 gmail com>");
@@ -472,6 +474,55 @@ namespace gnote {
   }
 
 
+  void Gnote::make_app_actions()
+  {
+    ActionManager & am(ActionManager::obj());
+    am.get_app_action("new-note")->signal_activate().connect(sigc::mem_fun(*this, &Gnote::on_new_note_app_action));
+    am.get_app_action("new-window")->signal_activate().connect(sigc::mem_fun(*this, &Gnote::on_new_window_action));
+    am.get_app_action("help-contents")->signal_activate().connect(sigc::mem_fun(*this, &Gnote::on_show_help_action));
+    am.get_app_action("about")->signal_activate().connect(sigc::mem_fun(*this, &Gnote::on_show_about_action));
+    am.get_app_action("quit")->signal_activate().connect(sigc::mem_fun(*this, &Gnote::on_quit_gnote_action));
+
+    add_app_actions(am.get_app_actions());
+  }
+
+
+  void Gnote::add_app_actions(const std::vector<Glib::RefPtr<Gio::SimpleAction> > & actions)
+  {
+    for(std::vector<Glib::RefPtr<Gio::SimpleAction> >::const_iterator iter = actions.begin();
+        iter != actions.end(); ++iter) {
+      add_action(*iter);
+    }
+  }
+
+
+  void Gnote::on_new_window_action(const Glib::VariantBase&)
+  {
+    new_main_window()->present();
+  }
+
+
+  void Gnote::on_new_note_app_action(const Glib::VariantBase&)
+  {
+    std::vector<Gtk::Window*> windows = Gtk::Window::list_toplevels();
+    for(std::vector<Gtk::Window*>::iterator iter = windows.begin(); iter != windows.end(); ++iter) {
+      if((*iter)->property_is_active()) {
+        NoteRecentChanges *rc = dynamic_cast<NoteRecentChanges*>(*iter);
+        rc->new_note();
+        return;
+      }
+    }
+
+    get_main_window()->new_note();
+  }
+
+
+  void Gnote::make_app_menu()
+  {
+    set_app_menu(ActionManager::obj().get_app_menu());
+  }
+
+
   std::string Gnote::cache_dir()
   {
     return Glib::get_user_cache_dir() + "/gnote";
@@ -609,7 +660,7 @@ namespace gnote {
       else {
         execute(remote);
       }
-      Gnote::obj().on_quit_gnote_action();
+      Gnote::obj().quit();
     }
     return 0;
   }
diff --git a/src/gnote.hpp b/src/gnote.hpp
index f24d41c..9335602 100644
--- a/src/gnote.hpp
+++ b/src/gnote.hpp
@@ -127,11 +127,11 @@ public:
   void start_tray_icon();
 
   void on_new_note_action();
-  void on_quit_gnote_action();
+  void on_quit_gnote_action(const Glib::VariantBase&);
   void on_preferences_response(int res);
   void on_show_preferences_action();
-  void on_show_help_action();
-  void on_show_about_action();
+  void on_show_help_action(const Glib::VariantBase&);
+  void on_show_about_action(const Glib::VariantBase&);
   NoteRecentChanges::Ptr new_main_window();
   NoteRecentChanges::Ptr get_main_window();
   NoteRecentChanges::Ptr get_window_for_note();
@@ -181,6 +181,11 @@ private:
   void end_main(bool bus_aquired, bool name_acquired);
   void on_sync_dialog_response(int response_id);
   void on_main_window_closed(std::list<NoteRecentChanges::Ptr>::iterator pos);
+  void make_app_actions();
+  void add_app_actions(const std::vector<Glib::RefPtr<Gio::SimpleAction> > & actions);
+  void make_app_menu();
+  void on_new_window_action(const Glib::VariantBase&);
+  void on_new_note_app_action(const Glib::VariantBase&);
 
   NoteManager *m_manager;
   IKeybinder  *m_keybinder;



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