]> git.lyx.org Git - features.git/blob - src/frontends/gtk/GToolbar.C
5d975cdaac3ca68d31de00ea0ed78a92961d6a2d
[features.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 #include <gtkmm.h>
13
14 #include "GToolbar.h"
15 #include "GView.h"
16 #include "LyXAction.h"
17 #include "lyxfunc.h"
18 #include "FuncStatus.h"
19 #include "buffer.h"
20 #include "bufferparams.h"
21 #include "funcrequest.h"
22 #include "gettext.h"
23 #include "Tooltips.h"
24 #include "support/filetools.h"
25 #include "support/lstrings.h"
26 #include "debug.h"
27
28 using std::string;
29
30
31 namespace
32 {
33
34 GView::Position getPosition(ToolbarBackend::Flags const & flags)
35  {
36         if (flags & ToolbarBackend::TOP)
37                 return GView::Top;
38         if (flags & ToolbarBackend::BOTTOM)
39                 return GView::Bottom;
40         if (flags & ToolbarBackend::LEFT)
41                 return GView::Left;
42         if (flags & ToolbarBackend::RIGHT)
43                 return GView::Right;
44         return GView::Top;
45 }
46
47
48 LyXTextClass const & getTextClass(LyXView const & lv)
49 {
50         return lv.buffer()->params().getLyXTextClass();
51 }
52
53
54 char const * gToolData = "tool_data";
55
56
57 inline void comboClear(Gtk::Combo & combo)
58 {
59         std::vector<Glib::ustring> strings;
60         strings.push_back("");
61         combo.set_popdown_strings(strings);
62 }
63
64
65 inline bool comboIsEmpty(Gtk::Combo & combo)
66 {
67         std::vector<Glib::ustring> strings = combo.get_popdown_strings();
68         return (strings.empty() || (strings.size() == 1 && strings[0] == ""));
69 }
70
71
72 }
73
74
75 GToolbar::GToolbar(LyXView * lyxView, int /*x*/, int /*y*/)
76         : view_(lyxView), internal_(false)
77 {
78         combo_.set_value_in_list();
79         combo_.get_entry()->set_editable(false);
80         combo_.unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
81         combo_.get_entry()->unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
82         comboClear(combo_);
83         combo_.get_entry()->signal_changed().connect(
84                 SigC::slot(*this,
85                            &GToolbar::onLayoutSelected));
86 }
87
88
89 GToolbar::~GToolbar()
90 {}
91
92
93 void GToolbar::add(ToolbarBackend::Toolbar const & tbb)
94 {
95         Gtk::Toolbar * toolbar = manage(new Gtk::Toolbar);
96         ToolbarBackend::item_iterator it = tbb.items.begin();
97         ToolbarBackend::item_iterator end = tbb.items.end();
98         for (; it != end; ++it)
99                 add(toolbar, *it);
100         toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS);
101
102         GView::Position const position = getPosition(tbb.flags);
103
104         if (position == GView::Left || position == GView::Right)
105                 toolbar->set_orientation(Gtk::ORIENTATION_VERTICAL);
106
107         GView * gview = static_cast<GView*>(view_);
108         gview->getBox(position).children().push_back(
109                 Gtk::Box_Helpers::Element(*toolbar, Gtk::PACK_SHRINK));
110
111         if (tbb.flags & ToolbarBackend::ON)
112                 toolbar->show();
113
114         toolbars_[tbb.name] = toolbar;
115 }
116
117
118 void GToolbar::add(Gtk::Toolbar * toolbar,
119                    ToolbarBackend::Item const & item)
120 {
121         FuncRequest const & func = item.first;
122         string const & tooltip = item.second;
123         switch (func.action) {
124         case ToolbarBackend::SEPARATOR:
125                 toolbar->tools().push_back(Gtk::Toolbar_Helpers::Space());
126                 break;
127         case ToolbarBackend::MINIBUFFER:
128                 // Not supported yet.
129                 break;
130         case ToolbarBackend::LAYOUTS:
131         {
132                 combo_.show();
133                 toolbar->tools().push_back(
134                         Gtk::Toolbar_Helpers::Element(combo_));
135                 toolbar->tools().back().get_widget()->set_data(
136                         gToolData,
137                         reinterpret_cast<void*>(&const_cast<ToolbarBackend::Item&>(item)));
138                 break;
139         }
140         default:
141         {
142                 Glib::ustring xpmName =
143                         Glib::locale_to_utf8(toolbarbackend.getIcon(func));
144                 Glib::ustring tip = Glib::locale_to_utf8(tooltip);
145                 if (xpmName.size() == 0) {
146                         toolbar->tools().push_back(
147                                 Gtk::Toolbar_Helpers::ButtonElem(
148                                         "",
149                                         SigC::bind(SigC::slot(*this, &GToolbar::onButtonClicked),
150                                                    FuncRequest(func)),
151                                         tip));
152                 } else {
153                         Gtk::Image * image =
154                                 Gtk::manage(new Gtk::Image(xpmName));
155                         image->show();
156                         toolbar->tools().push_back(
157                                 Gtk::Toolbar_Helpers::ButtonElem(
158                                         "",
159                                         *image,
160                                         SigC::bind(SigC::slot(*this, &GToolbar::onButtonClicked),
161                                                    FuncRequest(func)),
162                                         tip));
163                 }
164                 toolbar->tools().back().get_content()->set_data(
165                         gToolData,
166                         reinterpret_cast<void*>(&const_cast<ToolbarBackend::Item&>(item)));
167                 break;
168         }
169         }
170 }
171
172
173 void GToolbar::onButtonClicked(FuncRequest func)
174 {
175         view_->getLyXFunc().dispatch(func, true);
176 }
177
178
179 void GToolbar::onLayoutSelected()
180 {
181         if (internal_)
182                 return;
183         string layoutGuiName = combo_.get_entry()->get_text();
184         // we get two signal, one of it is empty and useless
185         if (layoutGuiName.empty())
186                 return;
187         LyXTextClass const & tc = getTextClass(*view_);
188
189         LyXTextClass::const_iterator end = tc.end();
190         for (LyXTextClass::const_iterator cit = tc.begin();
191              cit != end; ++cit) {
192                 if ((*cit)->name() == layoutGuiName) {
193                         view_->getLyXFunc().dispatch(
194                                 FuncRequest(LFUN_LAYOUT, (*cit)->name()),
195                                 true);
196                         return;
197                 }
198         }
199         lyxerr << "ERROR (GToolbar::layoutSelected): layout not found! name : "
200                << layoutGuiName
201                << std::endl;
202 }
203
204
205 void GToolbar::displayToolbar(ToolbarBackend::Toolbar const & tbb, bool show_it)
206 {
207         ToolbarMap::iterator it = toolbars_.find(tbb.name);
208         BOOST_ASSERT(it != toolbars_.end());
209
210         if (show_it)
211                 it->second->show();
212         else
213                 it->second->hide();
214 }
215
216
217 void GToolbar::update()
218 {
219         ToolbarMap::iterator itToolbar;
220         for (itToolbar = toolbars_.begin();
221              itToolbar != toolbars_.end(); ++itToolbar) {
222                 Gtk::Toolbar * toolbar = itToolbar->second;
223                 Gtk::Toolbar_Helpers::ToolList::iterator it;
224                 for (it = toolbar->tools().begin();
225                      it != toolbar->tools().end(); ++it) {
226                         Gtk::Widget * widget;
227                         switch (it->get_type()) {
228                         case Gtk::TOOLBAR_CHILD_WIDGET:
229                                 widget = it->get_widget();
230                                 break;
231                         case Gtk::TOOLBAR_CHILD_SPACE:
232                                 continue;
233                         default:
234                                 widget = it->get_content();
235                         }
236                         ToolbarBackend::Item * item =
237                         reinterpret_cast<ToolbarBackend::Item*>(
238                                 widget->get_data(gToolData));
239                         if (item->first.action == int(ToolbarBackend::LAYOUTS)) {
240                                 LyXFunc const & lf = view_->getLyXFunc();
241                                 bool const sensitive =
242                                         lf.getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
243                                 widget->set_sensitive(sensitive);
244                                 continue;
245                         }
246                         FuncStatus const status = view_->
247                                 getLyXFunc().getStatus(item->first);
248                         bool sensitive = status.enabled();
249                         widget->set_sensitive(sensitive);
250                         if (it->get_type() != Gtk::TOOLBAR_CHILD_BUTTON)
251                                 return;
252                         if (status.onoff(true))
253                                 static_cast<Gtk::Button*>(widget)->
254                                         set_relief(Gtk::RELIEF_NORMAL);
255                         if (status.onoff(false))
256                                 static_cast<Gtk::Button*>(widget)->
257                                         set_relief(Gtk::RELIEF_NONE);
258                 }
259         }
260 }
261
262
263 void GToolbar::setLayout(string const & layout)
264 {
265         LyXTextClass const & tc = getTextClass(*view_);
266         internal_ = true;
267         combo_.get_entry()->set_text(tc[layout]->name());
268         internal_ = false;
269 }
270
271
272 void GToolbar::updateLayoutList()
273 {
274         LyXTextClass const & tc = getTextClass(*view_);
275         LyXTextClass::const_iterator end = tc.end();
276         std::vector<Glib::ustring> strings;
277         for (LyXTextClass::const_iterator cit = tc.begin();
278              cit != end; ++cit)
279                 if ((*cit)->obsoleted_by().empty())
280                         strings.push_back(
281                                 Glib::locale_to_utf8((*cit)->name()));
282         internal_ = true;
283         combo_.set_popdown_strings(strings);
284         internal_ = false;
285 }
286
287
288 void GToolbar::openLayoutList()
289 {
290         combo_.get_list()->activate();
291 }
292
293
294 void GToolbar::clearLayoutList()
295 {
296         internal_ = true;
297         comboClear(combo_);
298         internal_ = false;
299 }