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