2 * \file qt4/GuiToolbar.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
9 * \author Angus Leeming
10 * \author Stefan Schimanski
11 * \author Abdelrazak Younes
13 * Full author contact details are available in file CREDITS.
18 #include "GuiToolbar.h"
21 #include "GuiApplication.h"
22 #include "GuiCommandBuffer.h"
24 #include "IconPalette.h"
25 #include "InsertTableWidget.h"
26 #include "LayoutBox.h"
27 #include "qt_helpers.h"
30 #include "FuncRequest.h"
31 #include "FuncStatus.h"
37 #include "support/debug.h"
38 #include "support/gettext.h"
39 #include "support/lstrings.h"
45 #include <QToolButton>
47 #include "support/lassert.h"
50 using namespace lyx::support;
55 GuiToolbar::GuiToolbar(ToolbarInfo const & tbinfo, GuiView & owner)
56 : QToolBar(toqstr(tbinfo.gui_name), &owner), visibility_(0),
57 owner_(owner), command_buffer_(0), tbinfo_(tbinfo), filled_(false),
60 setIconSize(owner.iconSize());
61 connect(&owner, SIGNAL(iconSizeChanged(QSize)), this,
62 SLOT(setIconSize(QSize)));
64 // This is used by QMainWindow::restoreState for proper main window state
66 setObjectName(toqstr(tbinfo.name));
71 void GuiToolbar::setVisible(bool visible)
73 // This is a hack to find out which toolbars have been restored by
74 // MainWindow::restoreState and which toolbars should be initialized
75 // by us (i.e., new toolbars)
77 QToolBar::setVisible(visible);
81 bool GuiToolbar::isRestored() const
87 void GuiToolbar::fill()
91 ToolbarInfo::item_iterator it = tbinfo_.items.begin();
92 ToolbarInfo::item_iterator end = tbinfo_.items.end();
93 for (; it != end; ++it)
99 void GuiToolbar::showEvent(QShowEvent * ev)
106 void GuiToolbar::setVisibility(int visibility)
108 visibility_ = visibility;
112 Action * GuiToolbar::addItem(ToolbarItem const & item)
114 QString text = toqstr(item.label_);
115 // Get the keys bound to this action, but keep only the
117 KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(*item.func_);
118 if (!bindings.empty())
119 text += " [" + toqstr(bindings.begin()->print(KeySequence::ForGui)) + "]";
121 Action * act = new Action(item.func_, getIcon(*item.func_, false), text,
123 actions_.append(act);
129 class PaletteButton : public QToolButton
133 ToolbarItem const & tbitem_;
136 PaletteButton(GuiToolbar * bar, ToolbarItem const & item)
137 : QToolButton(bar), bar_(bar), tbitem_(item), initialized_(false)
139 QString const label = qt_(to_ascii(tbitem_.label_));
143 connect(bar_, SIGNAL(iconSizeChanged(QSize)),
144 this, SLOT(setIconSize(QSize)));
146 ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
148 // use the icon of first action for the toolbar button
149 setIcon(getIcon(*tbinfo->items.begin()->func_, true));
152 void mousePressEvent(QMouseEvent * e)
155 QToolButton::mousePressEvent(e);
161 ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
163 LYXERR0("Unknown toolbar " << tbitem_.name_);
166 IconPalette * panel = new IconPalette(this);
167 QString const label = qt_(to_ascii(tbitem_.label_));
168 panel->setWindowTitle(label);
169 connect(this, SIGNAL(clicked(bool)), panel, SLOT(setVisible(bool)));
170 connect(panel, SIGNAL(visible(bool)), this, SLOT(setChecked(bool)));
171 ToolbarInfo::item_iterator it = tbinfo->items.begin();
172 ToolbarInfo::item_iterator const end = tbinfo->items.end();
173 for (; it != end; ++it)
174 if (!getStatus(*it->func_).unknown())
175 panel->addButton(bar_->addItem(*it));
177 QToolButton::mousePressEvent(e);
184 MenuButton::MenuButton(GuiToolbar * bar, ToolbarItem const & item, bool const sticky)
185 : QToolButton(bar), bar_(bar), tbitem_(item)
187 setPopupMode(QToolButton::InstantPopup);
188 QString const label = qt_(to_ascii(tbitem_.label_));
192 QString const name = toqstr(tbitem_.name_);
193 QStringList imagedirs;
194 imagedirs << "images/math/" << "images/";
195 for (int i = 0; i < imagedirs.size(); ++i) {
196 QString imagedir = imagedirs.at(i);
197 FileName const fname = imageLibFileSearch(imagedir, name, "svgz,png",
198 theGuiApp()->imageSearchMode());
199 if (fname.exists()) {
200 setIcon(QIcon(getPixmap(imagedir, name, "svgz,png")));
205 connect(this, SIGNAL(triggered(QAction *)),
206 this, SLOT(actionTriggered(QAction *)));
207 connect(bar, SIGNAL(iconSizeChanged(QSize)),
208 this, SLOT(setIconSize(QSize)));
213 void MenuButton::initialize()
215 QString const label = qt_(to_ascii(tbitem_.label_));
216 ButtonMenu * m = new ButtonMenu(label, this);
217 m->setWindowTitle(label);
218 m->setTearOffEnabled(true);
219 connect(bar_, SIGNAL(updated()), m, SLOT(updateParent()));
220 connect(bar_, SIGNAL(updated()), this, SLOT(updateTriggered()));
221 ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
223 LYXERR0("Unknown toolbar " << tbitem_.name_);
226 ToolbarInfo::item_iterator it = tbinfo->items.begin();
227 ToolbarInfo::item_iterator const end = tbinfo->items.end();
228 for (; it != end; ++it)
229 if (!getStatus(*it->func_).unknown())
230 m->add(bar_->addItem(*it));
235 void MenuButton::actionTriggered(QAction * action)
237 QToolButton::setDefaultAction(action);
238 setPopupMode(QToolButton::DelayedPopup);
242 void MenuButton::updateTriggered()
247 bool enabled = false;
248 QList<QAction *> acts = menu()->actions();
249 for (int i = 0; i < acts.size(); ++i)
250 if (acts[i]->isEnabled()) {
254 // Enable the MenuButton if at least one menu item is enabled
256 // If a disabled item is default, switch to InstantPopup
257 // (this can happen if a user selects e.g. DVI and then
258 // turns non-TeX fonts on)
259 if (defaultAction() && !defaultAction()->isEnabled())
260 setPopupMode(QToolButton::InstantPopup);
264 void GuiToolbar::add(ToolbarItem const & item)
266 switch (item.type_) {
267 case ToolbarItem::SEPARATOR:
270 case ToolbarItem::LAYOUTS: {
271 LayoutBox * layout = owner_.getLayoutDialog();
272 QObject::connect(this, SIGNAL(iconSizeChanged(QSize)),
273 layout, SLOT(setIconSize(QSize)));
274 QAction * action = addWidget(layout);
275 action->setVisible(true);
278 case ToolbarItem::MINIBUFFER:
279 command_buffer_ = new GuiCommandBuffer(&owner_);
280 addWidget(command_buffer_);
281 /// \todo find a Qt4 equivalent to setHorizontalStretchable(true);
282 //setHorizontalStretchable(true);
284 case ToolbarItem::TABLEINSERT: {
285 QToolButton * tb = new QToolButton;
286 tb->setCheckable(true);
287 tb->setIcon(getIcon(FuncRequest(LFUN_TABULAR_INSERT), true));
288 QString const label = qt_(to_ascii(item.label_));
289 tb->setToolTip(label);
290 tb->setStatusTip(label);
292 InsertTableWidget * iv = new InsertTableWidget(tb);
293 connect(tb, SIGNAL(clicked(bool)), iv, SLOT(show(bool)));
294 connect(iv, SIGNAL(visible(bool)), tb, SLOT(setChecked(bool)));
295 connect(this, SIGNAL(updated()), iv, SLOT(updateParent()));
299 case ToolbarItem::ICONPALETTE:
300 addWidget(new PaletteButton(this, item));
303 case ToolbarItem::POPUPMENU: {
304 addWidget(new MenuButton(this, item, false));
307 case ToolbarItem::STICKYPOPUPMENU: {
308 addWidget(new MenuButton(this, item, true));
311 case ToolbarItem::COMMAND: {
312 if (!getStatus(*item.func_).unknown())
313 addAction(addItem(item));
322 void GuiToolbar::update(int context)
324 if (visibility_ & Toolbars::AUTO) {
325 setVisible(visibility_ & context & Toolbars::ALLOWAUTO);
326 if (isVisible() && commandBuffer() && (context & Toolbars::MINIBUFFER_FOCUS))
327 commandBuffer()->setFocus();
330 // update visible toolbars only
334 // This is a speed bottleneck because this is called on every keypress
335 // and update calls getStatus, which copies the cursor at least two times
336 for (int i = 0; i < actions_.size(); ++i)
337 actions_[i]->update();
339 LayoutBox * layout = owner_.getLayoutDialog();
341 layout->setEnabled(lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled());
348 QString GuiToolbar::sessionKey() const
350 return "views/" + QString::number(owner_.id()) + "/" + objectName();
354 void GuiToolbar::saveSession() const
357 settings.setValue(sessionKey() + "/visibility", visibility_);
358 settings.setValue(sessionKey() + "/movability", isMovable());
362 void GuiToolbar::restoreSession()
365 int const error_val = -1;
367 settings.value(sessionKey() + "/visibility", error_val).toInt();
368 if (visibility == error_val || visibility == 0) {
369 // This should not happen, but in case we use the defaults
370 LYXERR(Debug::GUI, "Session settings could not be found! Defaults are used instead.");
372 guiApp->toolbars().defaultVisibility(fromqstr(objectName()));
374 setVisibility(visibility);
376 int movability = settings.value(sessionKey() + "/movability", true).toBool();
377 setMovable(movability);
381 void GuiToolbar::toggle()
384 if (visibility_ & Toolbars::ALLOWAUTO) {
385 if (!(visibility_ & Toolbars::AUTO)) {
386 visibility_ |= Toolbars::AUTO;
390 visibility_ &= ~Toolbars::AUTO;
409 owner_.message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
410 qstring_to_ucs4(windowTitle()), state));
413 void GuiToolbar::movable(bool silent)
416 setMovable(!isMovable());
418 // manual update avoids bug in qt that the drag handle is not removed
419 // properly, e.g. in Windows
422 // silence for toggling of many toolbars for performance
426 state = _("movable");
428 state = _("immovable");
429 owner_.message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
430 qstring_to_ucs4(windowTitle()), state));
434 } // namespace frontend
437 #include "moc_GuiToolbar.cpp"