1 /*
2  * gnote
3  *
4  * Copyright (C) 2010-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 #include <gtkmm/modelbutton.h>
25 #include <gtkmm/separator.h>
26 
27 #include "notebooks/notebooknoteaddin.hpp"
28 #include "notebooks/notebookmanager.hpp"
29 #include "debug.hpp"
30 #include "iactionmanager.hpp"
31 #include "iconmanager.hpp"
32 #include "ignote.hpp"
33 #include "tag.hpp"
34 #include "notemanagerbase.hpp"
35 #include "notewindow.hpp"
36 
37 
38 namespace gnote {
39 namespace notebooks {
40 
41   Tag::Ptr           NotebookNoteAddin::s_templateTag;
42 
get_template_tag() const43   Tag::Ptr NotebookNoteAddin::get_template_tag() const
44   {
45     if(!s_templateTag) {
46       s_templateTag = manager().tag_manager().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
47     }
48     return s_templateTag;
49   }
50 
51 
NotebookNoteAddin()52   NotebookNoteAddin::NotebookNoteAddin()
53   {
54   }
55 
56 
create()57   NoteAddin * NotebookNoteAddin::create()
58   {
59     return new NotebookNoteAddin();
60   }
61 
62 
initialize()63   void NotebookNoteAddin::initialize ()
64   {
65   }
66 
67 
shutdown()68   void NotebookNoteAddin::shutdown ()
69   {
70   }
71 
72 
on_note_opened()73   void NotebookNoteAddin::on_note_opened()
74   {
75     auto note_win = get_window();
76     note_win->signal_foregrounded.connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_note_window_foregrounded));
77     note_win->signal_backgrounded.connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_note_window_backgrounded));
78     ignote().notebook_manager().signal_notebook_list_changed
79       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_notebooks_changed));
80   }
81 
82 
on_note_window_foregrounded()83   void NotebookNoteAddin::on_note_window_foregrounded()
84   {
85     EmbeddableWidgetHost *host = get_window()->host();
86     m_new_notebook_cid = host->find_action("new-notebook")->signal_activate()
87       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_new_notebook_menu_item));
88     Notebook::Ptr current_notebook = ignote().notebook_manager().get_notebook_from_note(get_note());
89     Glib::ustring name;
90     if(current_notebook) {
91       name = current_notebook->get_name();
92     }
93     MainWindowAction::Ptr action = host->find_action("move-to-notebook");
94     action->set_state(Glib::Variant<Glib::ustring>::create(name));
95     m_move_to_notebook_cid = action->signal_change_state()
96       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_move_to_notebook));
97   }
98 
99 
on_note_window_backgrounded()100   void NotebookNoteAddin::on_note_window_backgrounded()
101   {
102     m_new_notebook_cid.disconnect();
103     m_move_to_notebook_cid.disconnect();
104   }
105 
106 
get_actions_popover_widgets() const107   std::vector<gnote::PopoverWidget> NotebookNoteAddin::get_actions_popover_widgets() const
108   {
109     auto widgets = NoteAddin::get_actions_popover_widgets();
110     if(!get_note()->contains_tag(get_template_tag())) {
111       Gtk::Widget *notebook_button = utils::create_popover_submenu_button("notebooks-submenu", _("Notebook"));
112       widgets.push_back(gnote::PopoverWidget(gnote::NOTE_SECTION_CUSTOM_SECTIONS, gnote::NOTEBOOK_ORDER, notebook_button));
113 
114       auto submenu = utils::create_popover_submenu("notebooks-submenu");
115       update_menu(submenu);
116       widgets.push_back(gnote::PopoverWidget::create_custom_section(submenu));
117     }
118 
119     return widgets;
120   }
121 
122 
on_new_notebook_menu_item(const Glib::VariantBase &) const123   void NotebookNoteAddin::on_new_notebook_menu_item(const Glib::VariantBase&) const
124   {
125     Note::List noteList;
126     noteList.push_back(get_note());
127     NotebookManager::prompt_create_new_notebook(ignote(), dynamic_cast<Gtk::Window*>(get_window()->host()), noteList);
128     get_window()->signal_popover_widgets_changed();
129   }
130 
131 
on_move_to_notebook(const Glib::VariantBase & state)132   void NotebookNoteAddin::on_move_to_notebook(const Glib::VariantBase & state)
133   {
134     get_window()->host()->find_action("move-to-notebook")->set_state(state);
135     Glib::ustring name = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(state).get();
136     Notebook::Ptr notebook;
137     if(name.size()) {
138       notebook = ignote().notebook_manager().get_notebook(name);
139     }
140     ignote().notebook_manager().move_note_to_notebook(get_note(), notebook);
141   }
142 
143 
update_menu(Gtk::Box * menu) const144   void NotebookNoteAddin::update_menu(Gtk::Box *menu) const
145   {
146     // Add new notebook item
147     Gtk::Widget *new_notebook_item = manage(utils::create_popover_button("win.new-notebook", _("_New notebook...")));
148     menu->add(*new_notebook_item);
149     menu->add(*manage(new Gtk::Separator));
150 
151     // Add the "(no notebook)" item at the top of the list
152     Gtk::ModelButton *no_notebook_item = dynamic_cast<Gtk::ModelButton*>(manage(
153       utils::create_popover_button("win.move-to-notebook", _("No notebook"))));
154     gtk_actionable_set_action_target_value(GTK_ACTIONABLE(no_notebook_item->gobj()), g_variant_new_string(""));
155     menu->add(*no_notebook_item);
156 
157     // Add in all the real notebooks
158     auto notebook_menu_items = get_notebook_menu_items();
159     if(!notebook_menu_items.empty()) {
160       for(Gtk::ModelButton *item : notebook_menu_items) {
161         menu->add(*item);
162       }
163 
164     }
165 
166     menu->add(*manage(new Gtk::Separator));
167     Gtk::Widget *back_button = utils::create_popover_submenu_button("main", _("_Back"));
168     dynamic_cast<Gtk::ModelButton*>(back_button)->property_inverted() = true;
169     menu->add(*back_button);
170   }
171 
172 
get_notebook_menu_items() const173   std::vector<Gtk::ModelButton*> NotebookNoteAddin::get_notebook_menu_items() const
174   {
175     std::vector<Gtk::ModelButton*> items;
176     Glib::RefPtr<Gtk::TreeModel> model = ignote().notebook_manager().get_notebooks();
177     Gtk::TreeIter iter;
178 
179     iter = model->children().begin();
180     for(iter = model->children().begin(); iter != model->children().end(); ++iter) {
181       Notebook::Ptr notebook;
182       iter->get_value(0, notebook);
183       Gtk::ModelButton *item = dynamic_cast<Gtk::ModelButton*>(manage(
184         utils::create_popover_button("win.move-to-notebook", notebook->get_name())));
185       gtk_actionable_set_action_target_value(GTK_ACTIONABLE(item->gobj()), g_variant_new_string(notebook->get_name().c_str()));
186       items.push_back(item);
187     }
188 
189     return items;
190   }
191 
192 
on_notebooks_changed()193   void NotebookNoteAddin::on_notebooks_changed()
194   {
195     auto note_win = get_window();
196     if(!note_win) {
197       return;
198     }
199     auto host = dynamic_cast<HasActions*>(note_win->host());
200     if(host) {
201       host->signal_popover_widgets_changed();
202     }
203   }
204 
205 
206 }
207 }
208