1 /*
2  * gnote
3  *
4  * Copyright (C) 2011-2019 Aurimas Cernius
5  * Copyright (C) 2009 Hubert Figuiere
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 
23 /* ported from */
24 /***************************************************************************
25  *  ActionManager.cs
26  *
27  *  Copyright (C) 2005-2006 Novell, Inc.
28  *  Written by Aaron Bockover <aaron@abock.org>
29  ****************************************************************************/
30 
31 /*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW:
32  *
33  *  Permission is hereby granted, free of charge, to any person obtaining a
34  *  copy of this software and associated documentation files (the "Software"),
35  *  to deal in the Software without restriction, including without limitation
36  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
37  *  and/or sell copies of the Software, and to permit persons to whom the
38  *  Software is furnished to do so, subject to the following conditions:
39  *
40  *  The above copyright notice and this permission notice shall be included in
41  *  all copies or substantial portions of the Software.
42  *
43  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
48  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
49  *  DEALINGS IN THE SOFTWARE.
50  */
51 
52 #ifdef HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55 
56 #include <glibmm/i18n.h>
57 
58 #include "sharp/string.hpp"
59 #include "debug.hpp"
60 #include "actionmanager.hpp"
61 
62 namespace gnote {
63 
init()64   void ActionManager::init()
65   {
66     make_app_actions();
67     make_app_menu_items();
68 
69     register_main_window_action("close-window", NULL, false);
70     register_main_window_action("delete-note", NULL, false);
71     register_main_window_action("important-note", &Glib::Variant<bool>::variant_type(), false);
72     register_main_window_action("enable-spell-check", &Glib::Variant<bool>::variant_type());
73     register_main_window_action("new-notebook", NULL, false);
74     register_main_window_action("move-to-notebook", &Glib::Variant<Glib::ustring>::variant_type(), false);
75     register_main_window_action("undo", NULL, true);
76     register_main_window_action("redo", NULL, true);
77     register_main_window_action("link", NULL, true);
78     register_main_window_action("change-font-bold", &Glib::Variant<bool>::variant_type(), true);
79     register_main_window_action("change-font-italic", &Glib::Variant<bool>::variant_type(), true);
80     register_main_window_action("change-font-strikeout", &Glib::Variant<bool>::variant_type(), true);
81     register_main_window_action("change-font-highlight", &Glib::Variant<bool>::variant_type(), true);
82     register_main_window_action("change-font-size", &Glib::Variant<Glib::ustring>::variant_type(), true);
83     register_main_window_action("enable-bullets", &Glib::Variant<bool>::variant_type(), true);
84     register_main_window_action("increase-indent", NULL, true);
85     register_main_window_action("decrease-indent", NULL, true);
86 
87     signal_build_main_window_search_popover.connect(sigc::mem_fun(*this, &ActionManager::add_app_menu_items));
88   }
89 
90 
make_app_actions()91   void ActionManager::make_app_actions()
92   {
93     add_app_action("new-note");
94     add_app_action("new-window");
95     add_app_action("show-preferences");
96     add_app_action("about");
97     add_app_action("help-contents");
98     add_app_action("help-shortcuts");
99   }
100 
get_app_action(const Glib::ustring & name) const101   Glib::RefPtr<Gio::SimpleAction> ActionManager::get_app_action(const Glib::ustring & name) const
102   {
103     for(std::vector<Glib::RefPtr<Gio::SimpleAction> >::const_iterator iter = m_app_actions.begin();
104         iter != m_app_actions.end(); ++iter) {
105       if((*iter)->get_name() == name) {
106         return *iter;
107       }
108     }
109 
110     return Glib::RefPtr<Gio::SimpleAction>();
111   }
112 
add_app_action(const Glib::ustring & name)113   Glib::RefPtr<Gio::SimpleAction> ActionManager::add_app_action(const Glib::ustring & name)
114   {
115     Glib::RefPtr<Gio::SimpleAction> action = Gio::SimpleAction::create(name);
116     m_app_actions.push_back(action);
117     return action;
118   }
119 
add_app_menu_item(int section,int order,const Glib::ustring & label,const Glib::ustring & action_def)120   void ActionManager::add_app_menu_item(int section, int order, const Glib::ustring & label,
121                                         const Glib::ustring & action_def)
122   {
123     m_app_menu_items.insert(std::make_pair(section, AppMenuItem(order, label, action_def)));
124   }
125 
make_app_menu_items()126   void ActionManager::make_app_menu_items()
127   {
128     add_app_menu_item(APP_SECTION_NEW, 100, _("_New Note"), "app.new-note");
129     add_app_menu_item(APP_SECTION_NEW, 200, _("New _Window"), "app.new-window");
130     add_app_menu_item(APP_SECTION_LAST, 50, _("_Preferences"), "app.show-preferences");
131     add_app_menu_item(APP_SECTION_LAST, 100, _("_Shortcuts"), "app.help-shortcuts");
132     add_app_menu_item(APP_SECTION_LAST, 150, _("_Help"), "app.help-contents");
133     add_app_menu_item(APP_SECTION_LAST, 200, _("_About Gnote"), "app.about");
134   }
135 
register_main_window_action(const Glib::ustring & action,const Glib::VariantType * state_type,bool modifying)136   void ActionManager::register_main_window_action(const Glib::ustring & action, const Glib::VariantType *state_type, bool modifying)
137   {
138     if(m_main_window_actions.find(action) == m_main_window_actions.end()) {
139       m_main_window_actions[action] = state_type;
140       if(!modifying) {
141         m_non_modifying_actions.push_back(action);
142       }
143     }
144     else {
145       if(m_main_window_actions[action] != state_type) {
146         ERR_OUT("Action %s already registerred with different state type", action.c_str());
147       }
148     }
149   }
150 
get_main_window_actions() const151   std::map<Glib::ustring, const Glib::VariantType*> ActionManager::get_main_window_actions() const
152   {
153     return m_main_window_actions;
154   }
155 
is_modifying_main_window_action(const Glib::ustring & action) const156   bool ActionManager::is_modifying_main_window_action(const Glib::ustring & action) const
157   {
158     return std::find(m_non_modifying_actions.begin(), m_non_modifying_actions.end(), action) == m_non_modifying_actions.end();
159   }
160 
register_main_window_search_callback(const Glib::ustring & id,const Glib::ustring & action,sigc::slot<void,const Glib::VariantBase &> callback)161   void ActionManager::register_main_window_search_callback(const Glib::ustring & id, const Glib::ustring & action,
162                                                     sigc::slot<void, const Glib::VariantBase&> callback)
163   {
164     DBG_ASSERT(m_main_window_search_actions.find(id) == m_main_window_search_actions.end(), "Duplicate callback for main window search");
165 
166     m_main_window_search_actions[id] = std::make_pair(action, callback);
167     signal_main_window_search_actions_changed();
168   }
169 
unregister_main_window_search_callback(const Glib::ustring & id)170   void ActionManager::unregister_main_window_search_callback(const Glib::ustring & id)
171   {
172     m_main_window_search_actions.erase(id);
173     signal_main_window_search_actions_changed();
174   }
175 
get_main_window_search_callbacks()176   std::map<Glib::ustring, sigc::slot<void, const Glib::VariantBase&>> ActionManager::get_main_window_search_callbacks()
177   {
178     std::map<Glib::ustring, sigc::slot<void, const Glib::VariantBase&>> cbacks;
179     for(auto & iter : m_main_window_search_actions) {
180       cbacks.insert(iter.second);
181     }
182     return cbacks;
183   }
184 
add_app_menu_items(std::vector<PopoverWidget> & widgets)185   void ActionManager::add_app_menu_items(std::vector<PopoverWidget> & widgets)
186   {
187     for(auto& iter : m_app_menu_items) {
188       widgets.push_back(PopoverWidget(iter.first, iter.second.order, utils::create_popover_button(iter.second.action_def, iter.second.label)));
189     }
190   }
191 
192 }
193