OSDN Git Service

Add a menu item 'Close'.
[fukui-no-namari/dialektos.git] / src / application_framework.cxx
1 /*
2  * Copyright (C) 2009 by Aiwota Programmer
3  * aiwotaprog@tetteke.tk
4  *
5  * This file is part of Dialektos.
6  *
7  * Dialektos 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  * Dialektos 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 Dialektos.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "application_framework.hxx"
22
23 #include <glibmm/error.h>
24 #include <glibmm/ustring.h>
25 #include <gtkmm/widget.h>
26 #include <gtkmm/main.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/menu.h>
29 #include <gtkmm/uimanager.h>
30 #include <gtkmm/actiongroup.h>
31 #include <boost/foreach.hpp>
32 #include <iostream>
33 #include "bookmark_window.hxx"
34 #include "uri_opener.hxx"
35 #include "bbs_detail_judge.hxx"
36 #include "bbs_detail_base.hxx"
37
38
39 namespace dialektos {
40
41
42 ApplicationFrameWork::ApplicationFrameWork() :
43   ApplicationWindow(),
44   vbox_(),
45   statusbar_(),
46   ui_manager_(Gtk::UIManager::create()),
47   action_group_(Gtk::ActionGroup::create()),
48   menubar_(),
49   toolbar_(),
50   popupmenu_(),
51   history_menu_() {
52
53   ApplicationWindow::add(vbox_);
54   build_menubar();
55   statusbar_.set_no_show_all(true);
56 }
57
58 ApplicationFrameWork::~ApplicationFrameWork() {}
59
60 void ApplicationFrameWork::add(Gtk::Widget& child) {
61   vbox_.pack_start(*menubar_, Gtk::PACK_SHRINK);
62   vbox_.pack_start(*toolbar_, Gtk::PACK_SHRINK);
63   vbox_.pack_start(child, true, true);
64   vbox_.pack_start(statusbar_, Gtk::PACK_SHRINK);
65 }
66 void ApplicationFrameWork::build_menubar() {
67   // File menu
68   action_group_->add(Gtk::Action::create("MenuFile", "_File"));
69   action_group_->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
70       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_file_quit));
71   action_group_->add(Gtk::Action::create("FileClose", Gtk::Stock::CLOSE),
72       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_file_close));
73
74   // Edit menu
75   action_group_->add(Gtk::Action::create("MenuEdit", "_Edit"));
76   action_group_->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY),
77       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_edit_copy));
78
79   // View menu
80   action_group_->add(Gtk::Action::create("MenuView", "_View"));
81   action_group_->add(Gtk::Action::create("ViewRefresh", Gtk::Stock::REFRESH),
82       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_view_refresh));
83   action_group_->add(Gtk::Action::create("ViewStop", Gtk::Stock::STOP),
84       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_view_stop));
85   action_group_->add(Gtk::Action::create("ViewMenubar", "Toggle _Menubar"),
86       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_view_menubar));
87   action_group_->add(Gtk::Action::create("ViewToolbar", "Toggle _Toolbar"),
88       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_view_toolbar));
89   action_group_->add(Gtk::Action::create("ViewStatusbar", "Toggle _Statusbar"),
90       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_view_statusbar));
91
92   action_group_->add(Gtk::Action::create("MenuHistory", "Hi_story"));
93
94   // Bookmark menu
95   action_group_->add(Gtk::Action::create("MenuBookmark", "_Bookmark"));
96   action_group_->add(Gtk::Action::create("BookmarkShow", "_Show Bookmarks"),
97       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_bookmark_show));
98
99   ui_manager_->insert_action_group(action_group_);
100   add_accel_group(ui_manager_->get_accel_group());
101
102   Glib::ustring ui_info =
103     "<ui>"
104     "  <menubar name='MenuBar'>"
105     "    <menu action='MenuFile'>"
106     "      <menuitem action='FileQuit'/>"
107     "      <menuitem action='FileClose'/>"
108     "    </menu>"
109     "    <menu action='MenuEdit'>"
110     "      <menuitem action='EditCopy'/>"
111     "    </menu>"
112     "    <menu action='MenuView'>"
113     "      <menuitem action='ViewRefresh'/>"
114     "      <menuitem action='ViewStop'/>"
115     "      <separator/>"
116     "      <menuitem action='ViewMenubar'/>"
117     "      <menuitem action='ViewToolbar'/>"
118     "      <menuitem action='ViewStatusbar'/>"
119     "    </menu>"
120     "    <menu action='MenuHistory'/>"
121     "    <menu action='MenuBookmark'>"
122     "      <menuitem action='BookmarkShow'/>"
123     "    </menu>"
124     "  </menubar>"
125     "  <toolbar name='ToolBar'>"
126     "    <toolitem action='ViewRefresh'/>"
127     "    <toolitem action='ViewStop'/>"
128     "  </toolbar>"
129     "  <popup name='MenuPopup'>"
130     "    <menuitem action='ViewRefresh'/>"
131     "    <menuitem action='ViewStop'/>"
132     "    <menuitem action='EditCopy'/>"
133     "    <separator/>"
134     "    <menuitem action='ViewMenubar'/>"
135     "  </popup>"
136     "</ui>";
137
138   ui_manager_->add_ui_from_string(ui_info);
139
140   menubar_ = ui_manager_->get_widget("/MenuBar");
141   menubar_->set_no_show_all(true);
142   menubar_->hide();
143   toolbar_ = ui_manager_->get_widget("/ToolBar");
144   toolbar_->set_no_show_all(true);
145   toolbar_->hide();
146   popupmenu_ =
147     dynamic_cast<Gtk::Menu*>(ui_manager_->get_widget("/MenuPopup"));
148
149   history_menu_ = dynamic_cast<Gtk::MenuItem*>(
150       ui_manager_->get_widget("/MenuBar/MenuHistory"));
151   history_menu_->show();
152   history_menu_->get_submenu()->signal_show().connect(
153       sigc::mem_fun(*this, &ApplicationFrameWork::set_history_menus));
154 }
155
156 void ApplicationFrameWork::on_action_file_quit() {
157   save();
158   BOOST_FOREACH(const ApplicationWindow& window, windows)
159     window.save_state();
160   windows.clear();
161   Gtk::Main::quit();
162 }
163
164 void ApplicationFrameWork::on_action_file_close() {
165   std::vector<ApplicationWindow*> closes;
166   closes.push_back(this);
167   close_windows(closes);
168 }
169
170 void ApplicationFrameWork::on_action_edit_copy() {
171   std::cout << "edit copy activated" << std::endl;
172 }
173
174 void ApplicationFrameWork::on_action_view_refresh() {
175   std::cout << "view refresh activated" << std::endl;
176 }
177
178 void ApplicationFrameWork::on_action_view_stop() {
179   std::cout << "view refresh stop" << std::endl;
180 }
181
182 void ApplicationFrameWork::on_action_view_menubar() {
183   if (menubar_->is_visible()) menubar_->hide(); else menubar_->show();
184 }
185
186 void ApplicationFrameWork::on_action_view_toolbar() {
187   if (toolbar_->is_visible()) toolbar_->hide(); else toolbar_->show();
188 }
189
190 void ApplicationFrameWork::on_action_view_statusbar() {
191   if (statusbar_.is_visible()) statusbar_.hide(); else statusbar_.show();
192 }
193
194 void ApplicationFrameWork::on_action_bookmark_show() {
195   BookmarkWindow::create();
196 }
197
198 void ApplicationFrameWork::on_child_button_press(GdkEventButton* event) {
199   if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
200     popupmenu_->popup(event->button, event->time);
201   }
202 }
203
204 void ApplicationFrameWork::on_history_menu_item_activate(
205     const std::string& uri) {
206   uri_opener::open(uri);
207 }
208
209 void ApplicationFrameWork::on_history_menu_items_activate(
210     const std::vector<std::string>& uris) const {
211   BOOST_FOREACH(const std::string& uri, uris) uri_opener::open(uri);
212 }
213
214 void ApplicationFrameWork::on_history_menu_items_open_close_activate(
215     const std::vector<std::string>& uris) const {
216
217   std::vector<ApplicationWindow*> closes;
218
219   BOOST_FOREACH(ApplicationWindow& window, windows)
220     if (std::find(uris.begin(), uris.end(), window.get_uri()) == uris.end())
221       closes.push_back(&window);
222
223   on_history_menu_items_activate(uris);
224   close_windows(closes);
225 }
226
227 void ApplicationFrameWork::set_history_menus() {
228   Gtk::Menu* sub = history_menu_->get_submenu();
229   sub->items().clear();
230   std::vector<history::Item> recents = histories.get_recent();
231
232   typedef std::map<std::string, Gtk::Menu*> SubMenuType;
233   SubMenuType subs;
234
235   typedef std::map<std::string, std::vector<std::string> > UrisType;
236   UrisType uris;
237
238   BOOST_FOREACH(const history::Item& hitem, recents) {
239     std::auto_ptr<bbs_detail::Base> bbs = bbs_detail::judge(hitem.uri_);
240     if (!bbs->is_thread()) continue;
241
242     const std::string board = bbs->get_board_id();
243     SubMenuType::iterator it = subs.find(board);
244     Gtk::Menu* subsub;
245     if (it != subs.end()) {
246       subsub = it->second;
247       if (subsub->items().size() == 10) continue;
248     }
249     else {
250       Gtk::MenuItem* subitem = Gtk::manage(new Gtk::MenuItem(board));
251       sub->append(*subitem);
252       subitem->show();
253       subsub = Gtk::manage(new Gtk::Menu());
254       subitem->set_submenu(*subsub);
255       subs.insert(std::make_pair(board, subsub));
256
257       // menut item for threads list
258       Gtk::MenuItem* menuitem =
259           Gtk::manage(new Gtk::MenuItem(bbs->get_board_uri()));
260       subsub->append(*menuitem);
261       menuitem->show();
262       menuitem->signal_activate().connect(sigc::bind(
263           sigc::mem_fun(*this,
264               &ApplicationFrameWork::on_history_menu_item_activate),
265               bbs->get_board_uri()));
266     }
267
268     Glib::ustring label = hitem.name_;
269     Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem(
270         label.size() > 40 ? label.substr(0, 40) + "..." : label));
271     item->show();
272     item->signal_activate().connect(sigc::bind(
273         sigc::mem_fun(*this,
274             &ApplicationFrameWork::on_history_menu_item_activate),
275         hitem.uri_));
276     subsub->append(*item);
277     uris[board].push_back(hitem.uri_);
278   }
279
280   BOOST_FOREACH(SubMenuType::value_type pair, subs) {
281     Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem("Open All"));
282     pair.second->append(*item);
283     item->show();
284     item->signal_activate().connect(sigc::bind(
285         sigc::mem_fun(*this,
286             &ApplicationFrameWork::on_history_menu_items_activate),
287             uris[pair.first]));
288
289     item = Gtk::manage(new Gtk::MenuItem("Open All & close others"));
290     pair.second->append(*item);
291     item->show();
292     item->signal_activate().connect(sigc::bind(
293         sigc::mem_fun(*this,
294             &ApplicationFrameWork::on_history_menu_items_open_close_activate),
295             uris[pair.first]));
296   }
297 }
298
299
300 } // namespace dialektos