1 /*
2 * gnote
3 *
4 * Copyright (C) 2013-2014,2017,2019 Aurimas Cernius
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include <glibmm/i18n.h>
22 #include <gtkmm/treestore.h>
23
24 #include "debug.hpp"
25 #include "ignote.hpp"
26 #include "itagmanager.hpp"
27 #include "statisticswidget.hpp"
28 #include "notebooks/notebookmanager.hpp"
29
30
31 namespace statistics {
32
33 class StatisticsModel
34 : public Gtk::TreeStore
35 {
36 public:
37 typedef Glib::RefPtr<StatisticsModel> Ptr;
create(gnote::IGnote & g,gnote::NoteManager & nm)38 static Ptr create(gnote::IGnote & g, gnote::NoteManager & nm)
39 {
40 return Ptr(new StatisticsModel(g, nm));
41 }
42
update()43 void update()
44 {
45 if(m_active) {
46 build_stats();
47 }
48 }
49
active(bool is_active)50 void active(bool is_active)
51 {
52 m_active = is_active;
53 }
54 private:
55 class StatisticsRecord
56 : public Gtk::TreeModelColumnRecord
57 {
58 public:
StatisticsRecord()59 StatisticsRecord()
60 {
61 add(m_stat);
62 add(m_value);
63 }
64 private:
65 Gtk::TreeModelColumn<Glib::ustring> m_stat;
66 Gtk::TreeModelColumn<Glib::ustring> m_value;
67 };
68 StatisticsRecord m_columns;
69
StatisticsModel(gnote::IGnote & g,gnote::NoteManager & nm)70 StatisticsModel(gnote::IGnote & g, gnote::NoteManager & nm)
71 : m_gnote(g)
72 , m_note_manager(nm)
73 , m_active(false)
74 {
75 set_column_types(m_columns);
76 build_stats();
77 nm.signal_note_added.connect(sigc::mem_fun(*this, &StatisticsModel::on_note_list_changed));
78 nm.signal_note_deleted.connect(sigc::mem_fun(*this, &StatisticsModel::on_note_list_changed));
79 g.notebook_manager().signal_note_added_to_notebook()
80 .connect(sigc::mem_fun(*this, &StatisticsModel::on_notebook_note_list_changed));
81 g.notebook_manager().signal_note_removed_from_notebook()
82 .connect(sigc::mem_fun(*this, &StatisticsModel::on_notebook_note_list_changed));
83 }
84
build_stats()85 void build_stats()
86 {
87 clear();
88 gnote::NoteBase::List notes = m_note_manager.get_notes();
89
90 Gtk::TreeIter iter = append();
91 Glib::ustring stat = _("Total Notes:");
92 iter->set_value(0, stat);
93 iter->set_value(1, TO_STRING(notes.size()));
94
95 Glib::RefPtr<Gtk::TreeModel> notebooks = m_gnote.notebook_manager().get_notebooks();
96 iter = append();
97 stat = _("Total Notebooks:");
98 iter->set_value(0, stat);
99 iter->set_value(1, TO_STRING(notebooks->children().size()));
100
101 Gtk::TreeIter notebook = notebooks->children().begin();
102 std::map<gnote::notebooks::Notebook::Ptr, int> notebook_notes;
103 while(notebook) {
104 gnote::notebooks::Notebook::Ptr nbook;
105 notebook->get_value(0, nbook);
106 notebook_notes[nbook] = 0;
107 ++notebook;
108 }
109 gnote::Tag::Ptr template_tag = m_note_manager.tag_manager().get_or_create_system_tag(
110 gnote::ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
111 for(gnote::NoteBase::Ptr note : notes) {
112 for(std::map<gnote::notebooks::Notebook::Ptr, int>::iterator nb = notebook_notes.begin();
113 nb != notebook_notes.end(); ++nb) {
114 if(note->contains_tag(nb->first->get_tag()) && !note->contains_tag(template_tag)) {
115 ++nb->second;
116 }
117 }
118 }
119 std::map<Glib::ustring, int> notebook_stats;
120 for(std::map<gnote::notebooks::Notebook::Ptr, int>::iterator nb = notebook_notes.begin();
121 nb != notebook_notes.end(); ++nb) {
122 notebook_stats[nb->first->get_name()] = nb->second;
123 }
124 for(auto nb : notebook_stats) {
125 Gtk::TreeIter nb_stat = append(iter->children());
126 nb_stat->set_value(0, nb.first);
127 // TRANSLATORS: %1 is the format placeholder for the number of notes.
128 char *fmt = ngettext("%1 note", "%1 notes", nb.second);
129 nb_stat->set_value(1, Glib::ustring::compose(fmt, nb.second));
130 }
131
132 DBG_OUT("Statistics updated");
133 }
134
on_note_list_changed(const gnote::NoteBase::Ptr &)135 void on_note_list_changed(const gnote::NoteBase::Ptr &)
136 {
137 update();
138 }
139
on_notebook_note_list_changed(const gnote::Note &,const gnote::notebooks::Notebook::Ptr &)140 void on_notebook_note_list_changed(const gnote::Note &, const gnote::notebooks::Notebook::Ptr &)
141 {
142 update();
143 }
144
145 gnote::IGnote & m_gnote;
146 gnote::NoteManager & m_note_manager;
147 bool m_active;
148 };
149
150
StatisticsWidget(gnote::IGnote & g,gnote::NoteManager & nm)151 StatisticsWidget::StatisticsWidget(gnote::IGnote & g, gnote::NoteManager & nm)
152 : Gtk::TreeView(StatisticsModel::create(g, nm))
153 {
154 set_hexpand(true);
155 set_vexpand(true);
156 StatisticsModel::Ptr model = StatisticsModel::Ptr::cast_dynamic(get_model());
157 set_model(model);
158 set_headers_visible(false);
159
160 Gtk::CellRendererText *renderer = manage(new Gtk::CellRendererText);
161 Gtk::TreeViewColumn *column = manage(new Gtk::TreeViewColumn("", *renderer));
162 column->set_cell_data_func(*renderer, sigc::mem_fun(*this, &StatisticsWidget::col1_data_func));
163 append_column(*column);
164
165 renderer = manage(new Gtk::CellRendererText);
166 column = manage(new Gtk::TreeViewColumn("", *renderer));
167 column->set_cell_data_func(*renderer, sigc::mem_fun(*this, &StatisticsWidget::col2_data_func));
168 append_column(*column);
169 }
170
get_name() const171 Glib::ustring StatisticsWidget::get_name() const
172 {
173 return _("Statistics");
174 }
175
foreground()176 void StatisticsWidget::foreground()
177 {
178 gnote::EmbeddableWidget::foreground();
179 StatisticsModel::Ptr model = StatisticsModel::Ptr::cast_static(get_model());
180 model->active(true);
181 model->update();
182 expand_all();
183 }
184
background()185 void StatisticsWidget::background()
186 {
187 gnote::EmbeddableWidget::background();
188 StatisticsModel::Ptr::cast_static(get_model())->active(false);
189 }
190
col1_data_func(Gtk::CellRenderer * renderer,const Gtk::TreeIter & iter)191 void StatisticsWidget::col1_data_func(Gtk::CellRenderer *renderer, const Gtk::TreeIter & iter)
192 {
193 Glib::ustring val;
194 iter->get_value(0, val);
195 static_cast<Gtk::CellRendererText*>(renderer)->property_markup() = "<b>" + val + "</b>";
196 }
197
col2_data_func(Gtk::CellRenderer * renderer,const Gtk::TreeIter & iter)198 void StatisticsWidget::col2_data_func(Gtk::CellRenderer *renderer, const Gtk::TreeIter & iter)
199 {
200 Glib::ustring val;
201 iter->get_value(1, val);
202 static_cast<Gtk::CellRendererText*>(renderer)->property_text() = val;
203 }
204
205 }
206
207