1 /*
2  * gnote
3  *
4  * Copyright (C) 2012-2016,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 #include <glibmm/i18n.h>
24 
25 #include "debug.hpp"
26 #include "noteaddin.hpp"
27 #include "notewindow.hpp"
28 
29 
30 namespace gnote {
31 
32   const char * NoteAddin::IFACE_NAME = "gnote::NoteAddin";
33 
initialize(IGnote & ignote,const Note::Ptr & note)34   void NoteAddin::initialize(IGnote & ignote, const Note::Ptr & note)
35   {
36     AbstractAddin::initialize(ignote);
37     m_note = note;
38     m_note_opened_cid = m_note->signal_opened().connect(
39       sigc::mem_fun(*this, &NoteAddin::on_note_opened_event));
40     initialize();
41     if(m_note->is_opened()) {
42       NoteWindow * window = get_window();
43 
44       on_note_opened();
45       /* Connect these two signals here, because signal_opened won't emit for
46        * opening already opened notes. */
47       window->signal_foregrounded.connect(sigc::mem_fun(*this, &NoteAddin::on_note_foregrounded));
48       window->signal_backgrounded.connect(sigc::mem_fun(*this, &NoteAddin::on_note_backgrounded));
49     }
50   }
51 
52 
dispose(bool disposing)53   void NoteAddin::dispose(bool disposing)
54   {
55     if (disposing) {
56       for (auto & iter : m_text_menu_items) {
57         delete iter;
58       }
59 
60       for(ToolItemMap::const_iterator iter = m_toolbar_items.begin();
61                iter != m_toolbar_items.end(); ++iter) {
62         delete iter->first;
63       }
64 
65       shutdown ();
66     }
67 
68     m_note_opened_cid.disconnect();
69     m_note = Note::Ptr();
70   }
71 
on_note_opened_event(Note &)72   void NoteAddin::on_note_opened_event(Note & )
73   {
74     on_note_opened();
75     NoteWindow * window = get_window();
76 
77     window->signal_foregrounded.connect(sigc::mem_fun(*this, &NoteAddin::on_note_foregrounded));
78     window->signal_backgrounded.connect(sigc::mem_fun(*this, &NoteAddin::on_note_backgrounded));
79 
80     for(auto & item : m_text_menu_items) {
81       if ((item->get_parent() == NULL) ||
82           (item->get_parent() != window->text_menu())) {
83         append_text_item(window->text_menu(), *item);
84       }
85     }
86 
87     for(ToolItemMap::const_iterator iter = m_toolbar_items.begin();
88         iter != m_toolbar_items.end(); ++iter) {
89       if ((iter->first->get_parent() == NULL) ||
90           (iter->first->get_parent() != window->embeddable_toolbar())) {
91         Gtk::Grid *grid = window->embeddable_toolbar();
92         grid->insert_column(iter->second);
93         grid->attach(*iter->first, iter->second, 0, 1, 1);
94       }
95     }
96   }
97 
append_text_item(Gtk::Widget * text_menu,Gtk::Widget & item)98   void NoteAddin::append_text_item(Gtk::Widget *text_menu, Gtk::Widget & item)
99   {
100     NoteTextMenu *txt_menu = dynamic_cast<NoteTextMenu*>(text_menu);
101     for(auto child : dynamic_cast<Gtk::Container*>(txt_menu->get_children().front())->get_children()) {
102       if(child->get_name() == "formatting") {
103         Gtk::Box *box = dynamic_cast<Gtk::Box*>(child);
104         box->add(item);
105       }
106     }
107   }
108 
on_note_foregrounded()109   void NoteAddin::on_note_foregrounded()
110   {
111     auto host = get_window()->host();
112     if(!host) {
113       return;
114     }
115 
116     for(auto & callback : m_action_callbacks) {
117       auto action = host->find_action(callback.first);
118       if(action) {
119         m_action_callbacks_cids.push_back(action->signal_activate().connect(callback.second));
120       }
121       else {
122         ERR_OUT("Action %s not found!", callback.first.c_str());
123       }
124     }
125   }
126 
on_note_backgrounded()127   void NoteAddin::on_note_backgrounded()
128   {
129     for(auto cid : m_action_callbacks_cids) {
130       cid.disconnect();
131     }
132     m_action_callbacks_cids.clear();
133   }
134 
add_tool_item(Gtk::ToolItem * item,int position)135   void NoteAddin::add_tool_item (Gtk::ToolItem *item, int position)
136   {
137     if (is_disposing())
138       throw sharp::Exception(_("Plugin is disposing already"));
139 
140     m_toolbar_items [item] = position;
141 
142     if (m_note->is_opened()) {
143       Gtk::Grid *grid = get_window()->embeddable_toolbar();
144       grid->insert_column(position);
145       grid->attach(*item, position, 0, 1, 1);
146     }
147   }
148 
add_text_menu_item(Gtk::Widget * item)149   void NoteAddin::add_text_menu_item(Gtk::Widget *item)
150   {
151     if (is_disposing())
152       throw sharp::Exception(_("Plugin is disposing already"));
153 
154     m_text_menu_items.push_back(item);
155 
156     if (m_note->is_opened()) {
157       append_text_item(get_window()->text_menu(), *item);
158     }
159   }
160 
get_host_window() const161   Gtk::Window *NoteAddin::get_host_window() const
162   {
163     if(is_disposing() && !has_buffer()) {
164       throw sharp::Exception(_("Plugin is disposing already"));
165     }
166     NoteWindow *note_window = m_note->get_window();
167     if(note_window == NULL || !note_window->host()) {
168       throw std::runtime_error(_("Window is not embedded"));
169     }
170     return dynamic_cast<Gtk::Window*>(note_window->host());
171   }
172 
get_actions_popover_widgets() const173   std::vector<gnote::PopoverWidget> NoteAddin::get_actions_popover_widgets() const
174   {
175     return std::vector<gnote::PopoverWidget>();
176   }
177 
register_main_window_action_callback(const Glib::ustring & action,sigc::slot<void,const Glib::VariantBase &> callback)178   void NoteAddin::register_main_window_action_callback(const Glib::ustring & action, sigc::slot<void, const Glib::VariantBase&> callback)
179   {
180     m_action_callbacks.emplace_back(action, callback);
181   }
182 
183 }
184