]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/GToolbar.C
add a const, use boost::assert
[lyx.git] / src / frontends / gtk / GToolbar.C
1 /**
2  * \file GToolbar.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Huang Ying
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "GToolbar.h"
14 #include "GView.h"
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "debug.h"
19 #include "funcrequest.h"
20 #include "FuncStatus.h"
21 #include "lyxfunc.h"
22
23 using std::string;
24
25 namespace lyx {
26 namespace frontend {
27
28 namespace {
29
30 GView::Position getPosition(ToolbarBackend::Flags const & flags)
31 {
32         if (flags & ToolbarBackend::TOP)
33                 return GView::Top;
34         if (flags & ToolbarBackend::BOTTOM)
35                 return GView::Bottom;
36         if (flags & ToolbarBackend::LEFT)
37                 return GView::Left;
38         if (flags & ToolbarBackend::RIGHT)
39                 return GView::Right;
40         return GView::Top;
41 }
42
43
44 LyXTextClass const & getTextClass(LyXView const & lv)
45 {
46         return lv.buffer()->params().getLyXTextClass();
47 }
48
49
50 void comboClear(Gtk::Combo & combo)
51 {
52         std::vector<Glib::ustring> strings;
53         strings.push_back("");
54         combo.set_popdown_strings(strings);
55 }
56
57
58 bool comboIsEmpty(Gtk::Combo & combo)
59 {
60         std::vector<Glib::ustring> strings = combo.get_popdown_strings();
61         return (strings.empty() || (strings.size() == 1 && strings[0] == ""));
62 }
63
64 char const * gToolData = "tool_data";
65
66 } // namespace anon
67
68
69 GLayoutBox::GLayoutBox(LyXView & owner,
70                        Gtk::Toolbar & toolbar,
71                        FuncRequest const & func)
72         : owner_(owner),
73           internal_(false)
74 {
75         combo_.set_value_in_list();
76         combo_.get_entry()->set_editable(false);
77         combo_.unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
78         combo_.get_entry()->unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
79         comboClear(combo_);
80
81         combo_.get_entry()->signal_changed().connect(
82                 sigc::mem_fun(*this,&GLayoutBox::selected));
83
84         combo_.show();
85
86         combo_.set_data(
87                 gToolData,
88                 reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
89
90         Gtk::ToolItem * toolitem = Gtk::manage(new Gtk::ToolItem);
91         toolitem->add(combo_);
92         toolbar.insert(*toolitem,-1);
93 }
94
95 void GLayoutBox::set(string const & layout)
96 {
97         LyXTextClass const & tc = getTextClass(owner_);
98
99         internal_ = true;
100         combo_.get_entry()->set_text(tc[layout]->name());
101         internal_ = false;
102 }
103
104
105 void GLayoutBox::update()
106 {
107         LyXTextClass const & tc = getTextClass(owner_);
108
109         std::vector<Glib::ustring> strings;
110
111         LyXTextClass::const_iterator it = tc.begin();
112         LyXTextClass::const_iterator const end = tc.end();
113         for (; it != end; ++it)
114                 if ((*it)->obsoleted_by().empty())
115                         strings.push_back(
116                                 Glib::locale_to_utf8((*it)->name()));
117         internal_ = true;
118         combo_.set_popdown_strings(strings);
119         internal_ = false;
120 }
121
122
123 void GLayoutBox::clear()
124 {
125         internal_ = true;
126         comboClear(combo_);
127         internal_ = false;
128 }
129
130
131 void GLayoutBox::open()
132 {
133         combo_.get_list()->activate();
134 }
135
136
137 void GLayoutBox::setEnabled(bool sensitive)
138 {
139         combo_.set_sensitive(sensitive);
140 }
141
142
143 void GLayoutBox::selected()
144 {
145         if (internal_)
146                 return;
147
148         string layoutGuiName = combo_.get_entry()->get_text();
149         // we get two signal, one of it is empty and useless
150         if (layoutGuiName.empty())
151                 return;
152         LyXTextClass const & tc = getTextClass(owner_);
153
154         LyXTextClass::const_iterator it = tc.begin();
155         LyXTextClass::const_iterator const end = tc.end();
156         for (; it != end; ++it) {
157                 string const & name = (*it)->name();
158                 if (name == layoutGuiName) {
159                         owner_.getLyXFunc().dispatch(
160                                 FuncRequest(LFUN_LAYOUT, name),
161                                 true);
162                         return;
163                 }
164         }
165         lyxerr << "ERROR (GLayoutBox::selected): layout not found! name: "
166                << layoutGuiName << std::endl;
167 }
168
169 } // namespace frontend
170 } // namespace lyx
171
172
173 Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
174                                   LyXView & owner)
175 {
176         using lyx::frontend::GToolbar;
177         return Toolbars::ToolbarPtr(new GToolbar(tbb, owner));
178 }
179
180 namespace lyx {
181 namespace frontend {
182
183 GToolbar::GToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & owner)
184         : owner_(dynamic_cast<GView &>(owner))
185 {
186         ToolbarBackend::item_iterator it = tbb.items.begin();
187         ToolbarBackend::item_iterator end = tbb.items.end();
188         for (; it != end; ++it)
189                 add(it->first, it->second);
190
191         toolbar_.set_toolbar_style(Gtk::TOOLBAR_ICONS);
192         toolbar_.show_all();
193
194         GView::Position const position = getPosition(tbb.flags);
195
196         if (position == GView::Left || position == GView::Right)
197                 toolbar_.set_orientation(Gtk::ORIENTATION_VERTICAL);
198
199         owner_.getBox(position).children().push_back(
200                 Gtk::Box_Helpers::Element(toolbar_, Gtk::PACK_SHRINK));
201
202         tooltips_.enable();
203 }
204
205 void GToolbar::add(FuncRequest const & func, string const & tooltip)
206 {
207         switch (func.action) {
208         case ToolbarBackend::SEPARATOR: {
209                 Gtk::SeparatorToolItem * space =
210                         Gtk::manage(new Gtk::SeparatorToolItem);
211                 toolbar_.insert(*space,-1);
212                 break;
213         }
214
215         case ToolbarBackend::MINIBUFFER:
216                 // Not supported yet.
217                 break;
218
219         case ToolbarBackend::LAYOUTS: {
220                 layout_.reset(new GLayoutBox(owner_, toolbar_, func));
221                 break;
222         }
223
224         default: {
225                 Glib::ustring xpmName =
226                         Glib::locale_to_utf8(toolbarbackend.getIcon(func));
227                 Glib::ustring tip = Glib::locale_to_utf8(tooltip);
228                 Gtk::ToolButton * toolbutton;
229                 if (xpmName.size() == 0) {
230                         toolbutton = Gtk::manage(new Gtk::ToolButton);
231                 } else {
232                         Gtk::Image * image = Gtk::manage(new Gtk::Image(xpmName));
233                         image->show();
234                         toolbutton = Gtk::manage(new Gtk::ToolButton(*image));
235                 }
236                 // This code is putting a function reference into the GObject data field
237                 // named gToolData.  That's how we know how to update the status of the
238                 // toolitem later.
239                 toolbutton->set_data(gToolData,
240                         reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
241                 tooltips_.set_tip(*toolbutton, tip, tip);
242                 toolbutton->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this,
243                         &GToolbar::clicked), FuncRequest(func)));
244                 toolbar_.insert(*toolbutton,-1);
245                 break;
246         }
247
248         }
249 }
250
251
252 void GToolbar::clicked(FuncRequest func)
253 {
254         owner_.getLyXFunc().dispatch(func, true);
255 }
256
257
258 void GToolbar::hide(bool)
259 {
260         toolbar_.hide();
261 }
262
263
264 void GToolbar::show(bool)
265 {
266         toolbar_.show();
267 }
268
269
270 void GToolbar::update()
271 {
272         int const items = toolbar_.get_n_items();
273
274         for (int i = 0; i < items; ++i) {
275                 Gtk::ToolItem * item = toolbar_.get_nth_item(i);
276
277                 FuncRequest const * func = reinterpret_cast<FuncRequest *>(
278                         item->get_data(gToolData));
279                 if (func) {
280                         FuncStatus const status = owner_.getLyXFunc().getStatus(*func);
281                         item->set_sensitive(status.enabled());
282                 }
283         }
284 }
285
286 } // namespace frontend
287 } // namespace lyx