3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
14 // Too hard to make concept checks work with this file
15 #ifdef _GLIBCXX_CONCEPT_CHECKS
16 #undef _GLIBCXX_CONCEPT_CHECKS
18 #ifdef _GLIBCPP_CONCEPT_CHECKS
19 #undef _GLIBCPP_CONCEPT_CHECKS
28 #include "bufferparams.h"
30 #include "funcrequest.h"
31 #include "FuncStatus.h"
41 GView::Position getPosition(ToolbarBackend::Flags const & flags)
43 if (flags & ToolbarBackend::TOP)
45 if (flags & ToolbarBackend::BOTTOM)
47 if (flags & ToolbarBackend::LEFT)
49 if (flags & ToolbarBackend::RIGHT)
55 LyXTextClass const & getTextClass(LyXView const & lv)
57 return lv.buffer()->params().getLyXTextClass();
60 char const * gToolData = "tool_data";
65 GLayoutBox::GLayoutBox(LyXView & owner,
66 Gtk::Toolbar & toolbar,
67 FuncRequest const & func)
71 combo_.signal_changed().connect(
72 sigc::mem_fun(*this,&GLayoutBox::selected));
74 model_ = Gtk::ListStore::create(cols_);
75 combo_.set_model(model_);
76 Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
77 combo_.pack_start(*cell, true);
78 combo_.add_attribute(*cell,"text",0);
79 combo_.set_wrap_width(2);
80 // Initially there's nothing in the liststore, so set the size
81 // to avoid it jumping too much when the user does something that
82 // causes the first update()
83 combo_.set_size_request(130,-1);
87 reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
89 Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox);
90 vbox->pack_end(combo_, Gtk::PACK_EXPAND_PADDING);
92 Gtk::ToolItem * toolitem = Gtk::manage(new Gtk::ToolItem);
94 toolbar.append(*toolitem);
97 void GLayoutBox::set(string const & layout)
99 LyXTextClass const & tc = getTextClass(owner_);
100 string const target = tc[layout]->name();
103 Gtk::TreeModel::iterator it = model_->children().begin();
104 Gtk::TreeModel::iterator end = model_->children().end();
105 for (; it != end; ++it) {
106 if ((*it)[cols_.name] == target){
107 combo_.set_active(it);
114 lyxerr << "ERROR (GLayoutBox::set): layout not found! name: "
115 << target << std::endl;
119 void GLayoutBox::update()
121 int const current_selection = combo_.get_active_row_number();
124 LyXTextClass const & tc = getTextClass(owner_);
125 LyXTextClass::const_iterator it = tc.begin();
126 LyXTextClass::const_iterator const end = tc.end();
129 for (; it != end; ++it)
130 if ((*it)->obsoleted_by().empty()) {
131 Gtk::TreeModel::iterator iter = model_->append();
132 Gtk::TreeModel::Row row = *iter;
133 // ENCODING, FIXME: are the backend layout strings really
134 // in locale encoding?
135 row[cols_.name] = Glib::locale_to_utf8((*it)->name());
137 combo_.set_active(current_selection);
140 // now that we've loaded something into the combobox, forget
141 // the initial fixed size and let GTK decide.
142 combo_.set_size_request(-1,-1);
146 void GLayoutBox::clear()
154 void GLayoutBox::open()
160 void GLayoutBox::setEnabled(bool sensitive)
162 combo_.set_sensitive(sensitive);
166 void GLayoutBox::selected()
171 Glib::ustring layoutGuiName = (*(combo_.get_active()))[cols_.name];
173 // we get two signal, one of them is empty and useless
174 if (layoutGuiName.empty())
177 layoutSelected(owner_, layoutGuiName);
180 } // namespace frontend
184 Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
187 using lyx::frontend::GToolbar;
188 return Toolbars::ToolbarPtr(new GToolbar(tbb, owner));
194 GToolbar::GToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & owner)
195 : owner_(dynamic_cast<GView &>(owner))
197 ToolbarBackend::item_iterator it = tbb.items.begin();
198 ToolbarBackend::item_iterator end = tbb.items.end();
199 for (; it != end; ++it)
200 add(it->first, lyx::from_utf8(it->second));
202 toolbar_.set_toolbar_style(Gtk::TOOLBAR_ICONS);
205 GView::Position const position = getPosition(tbb.flags);
207 if (position == GView::Left || position == GView::Right)
208 toolbar_.set_orientation(Gtk::ORIENTATION_VERTICAL);
210 owner_.getBox(position).children().push_back(
211 Gtk::Box_Helpers::Element(toolbar_, Gtk::PACK_SHRINK));
213 toolbar_.set_tooltips(true);
216 void GToolbar::add(FuncRequest const & func, lyx::docstring const & tooltip)
218 switch (func.action) {
219 case ToolbarBackend::SEPARATOR: {
220 Gtk::SeparatorToolItem * space =
221 Gtk::manage(new Gtk::SeparatorToolItem);
222 toolbar_.append(*space);
226 case ToolbarBackend::MINIBUFFER:
227 // Not supported yet.
230 case ToolbarBackend::LAYOUTS: {
231 layout_.reset(new GLayoutBox(owner_, toolbar_, func));
236 Glib::ustring tip = lyx::to_utf8(tooltip);
238 Gtk::ToolButton * toolbutton;
239 Gtk::Image * image = NULL;
240 image = getGTKIcon(func, Gtk::ICON_SIZE_LARGE_TOOLBAR);
242 // ENCODING, FIXME: does Gtk::Image constructer really want
243 // filename in UTF-8 rather than filesystem encoding?
244 // This probably won't break when filenames are ASCII.
245 Glib::ustring xpmName =
246 Glib::locale_to_utf8(toolbarbackend.getIcon(func));
247 if (xpmName.find("unknown.xpm") == Glib::ustring::npos) {
248 image = Gtk::manage(new Gtk::Image(xpmName));
253 toolbutton = Gtk::manage(new Gtk::ToolButton(*image));
254 // This code is putting a function reference into the GObject data field
255 // named gToolData. That's how we know how to update the status of the
257 toolbutton->set_data(gToolData,
258 reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
260 toolbutton->set_tooltip(*toolbar_.get_tooltips_object(),tip);
262 toolbutton->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this,
263 >oolbar::clicked), FuncRequest(func)));
264 toolbar_.append(*toolbutton);
272 void GToolbar::clicked(FuncRequest func)
274 owner_.dispatch(func);
278 void GToolbar::hide(bool)
284 void GToolbar::show(bool)
290 void GToolbar::update()
292 int const items = toolbar_.get_n_items();
294 for (int i = 0; i < items; ++i) {
295 Gtk::ToolItem * item = toolbar_.get_nth_item(i);
297 FuncRequest const * func = reinterpret_cast<FuncRequest *>(
298 item->get_data(gToolData));
300 FuncStatus const status = lyx::getStatus(*func);
301 item->set_sensitive(status.enabled());
306 } // namespace frontend