]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt/GuiToolbar.cpp
Implement sane UI for switching tristate toolbars (#6364)
[lyx.git] / src / frontends / qt / GuiToolbar.cpp
index 6f644192d35ccbae9f2704f42a7ba8c398f663f1..5600f4a74f7212d78d6e25e3495ee00048311755 100644 (file)
@@ -64,7 +64,7 @@ namespace frontend {
 
 GuiToolbar::GuiToolbar(ToolbarInfo const & tbinfo, GuiView & owner)
        : QToolBar(toqstr(tbinfo.gui_name), &owner), visibility_(0),
-         owner_(owner), command_buffer_(0), tbinfo_(tbinfo), filled_(false),
+         owner_(owner), command_buffer_(nullptr), tbinfo_(tbinfo), filled_(false),
          restored_(false)
 {
        setIconSize(owner.iconSize());
@@ -72,7 +72,7 @@ GuiToolbar::GuiToolbar(ToolbarInfo const & tbinfo, GuiView & owner)
                SLOT(setIconSize(QSize)));
 
        // This is used by QMainWindow::restoreState for proper main window state
-       // restauration.
+       // restoration.
        setObjectName(toqstr(tbinfo.name));
        restoreSession();
 }
@@ -84,6 +84,16 @@ void GuiToolbar::setVisible(bool visible)
        // MainWindow::restoreState and which toolbars should be initialized
        // by us (i.e., new toolbars)
        restored_ = true;
+       // Record the actual visibility in toolbar state visibility_.
+       // This is useful to restore the visibility of toolbars when
+       // returning from full-screen. Therefore the recording is disabled
+       // while LyX is in full-screen state.
+       if (!owner_.isFullScreen()) {
+               if (visible)
+                       visibility_ |= Toolbars::ON;
+               else
+                       visibility_ &= ~Toolbars::ON;
+       }
        QToolBar::setVisible(visible);
 }
 
@@ -121,17 +131,17 @@ void GuiToolbar::setVisibility(int visibility)
 
 Action * GuiToolbar::addItem(ToolbarItem const & item)
 {
-       QString text = toqstr(item.label_);
+       QString text = toqstr(item.label);
        // Get the keys bound to this action, but keep only the
        // first one later
-       KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(*item.func_);
+       KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(*item.func);
        if (!bindings.empty())
                text += " [" + toqstr(bindings.begin()->print(KeySequence::ForGui)) + "]";
 
-       Action * act = new Action(item.func_, getIcon(*item.func_, false), text,
+       Action * act = new Action(item.func, getIcon(*item.func, false), text,
                                                          text, this);
-       if (item.type_ == ToolbarItem::BIDICOMMAND)
-               act->setRtlIcon(getIcon(*item.func_, false, true));
+       if (item.type == ToolbarItem::BIDICOMMAND)
+               act->setRtlIcon(getIcon(*item.func, false, true));
 
        actions_.append(act);
        return act;
@@ -149,20 +159,20 @@ public:
        PaletteButton(GuiToolbar * bar, ToolbarItem const & item)
                : QToolButton(bar), bar_(bar), tbitem_(item), initialized_(false)
        {
-               QString const label = qt_(to_ascii(tbitem_.label_));
+               QString const label = qt_(to_ascii(tbitem_.label));
                setToolTip(label);
                setStatusTip(label);
                setText(label);
                connect(bar_, SIGNAL(iconSizeChanged(QSize)),
                        this, SLOT(setIconSize(QSize)));
                setCheckable(true);
-               ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
+               ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name);
                if (tbinfo)
                        // use the icon of first action for the toolbar button
-                       setIcon(getIcon(*tbinfo->items.begin()->func_, true));
+                       setIcon(getIcon(*tbinfo->items.begin()->func, true));
        }
 
-       void mousePressEvent(QMouseEvent * e)
+       void mousePressEvent(QMouseEvent * e) override
        {
                if (initialized_) {
                        QToolButton::mousePressEvent(e);
@@ -171,20 +181,20 @@ public:
 
                initialized_ = true;
 
-               ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
+               ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name);
                if (!tbinfo) {
-                       LYXERR0("Unknown toolbar " << tbitem_.name_);
+                       LYXERR0("Unknown toolbar " << tbitem_.name);
                        return;
                }
                IconPalette * panel = new IconPalette(this);
-               QString const label = qt_(to_ascii(tbitem_.label_));
+               QString const label = qt_(to_ascii(tbitem_.label));
                panel->setWindowTitle(label);
                connect(this, SIGNAL(clicked(bool)), panel, SLOT(setVisible(bool)));
                connect(panel, SIGNAL(visible(bool)), this, SLOT(setChecked(bool)));
                ToolbarInfo::item_iterator it = tbinfo->items.begin();
                ToolbarInfo::item_iterator const end = tbinfo->items.end();
                for (; it != end; ++it)
-                       if (!getStatus(*it->func_).unknown())
+                       if (!getStatus(*it->func).unknown())
                                panel->addButton(bar_->addItem(*it));
 
                QToolButton::mousePressEvent(e);
@@ -198,11 +208,11 @@ MenuButtonBase::MenuButtonBase(GuiToolbar * bar, ToolbarItem const & item)
        : QToolButton(bar), bar_(bar), tbitem_(item)
 {
        setPopupMode(QToolButton::InstantPopup);
-       QString const label = qt_(to_ascii(tbitem_.label_));
+       QString const label = qt_(to_ascii(tbitem_.label));
        setToolTip(label);
        setStatusTip(label);
        setText(label);
-       QString const name = toqstr(tbitem_.name_);
+       QString const name = toqstr(tbitem_.name);
        QStringList imagedirs;
        imagedirs << "images/math/" << "images/";
        for (int i = 0; i < imagedirs.size(); ++i) {
@@ -239,21 +249,21 @@ StaticMenuButton::StaticMenuButton(
 
 void StaticMenuButton::initialize()
 {
-       QString const label = qt_(to_ascii(tbitem_.label_));
+       QString const label = qt_(to_ascii(tbitem_.label));
        ButtonMenu * m = new ButtonMenu(label, this);
        m->setWindowTitle(label);
        m->setTearOffEnabled(true);
        connect(bar_, SIGNAL(updated()), m, SLOT(updateParent()));
        connect(bar_, SIGNAL(updated()), this, SLOT(updateTriggered()));
-       ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name_);
+       ToolbarInfo const * tbinfo = guiApp->toolbars().info(tbitem_.name);
        if (!tbinfo) {
-               LYXERR0("Unknown toolbar " << tbitem_.name_);
+               LYXERR0("Unknown toolbar " << tbitem_.name);
                return;
        }
        ToolbarInfo::item_iterator it = tbinfo->items.begin();
        ToolbarInfo::item_iterator const end = tbinfo->items.end();
        for (; it != end; ++it)
-               if (!getStatus(*it->func_).unknown())
+               if (!getStatus(*it->func).unknown())
                        m->add(bar_->addItem(*it));
        setMenu(m);
 }
@@ -266,8 +276,8 @@ void StaticMenuButton::updateTriggered()
 
        bool enabled = false;
        QList<QAction *> acts = menu()->actions();
-       for (int i = 0; i < acts.size(); ++i)
-               if (acts[i]->isEnabled()) {
+       for (auto const & act : acts)
+               if (act->isEnabled()) {
                        enabled = true;
                        break;
                }
@@ -287,7 +297,7 @@ class DynamicMenuButton::Private
        Private(Private const &);
        void operator=(Private const &);
 public:
-       Private() : inset_(0) {}
+       Private() : inset_(nullptr) {}
        ///
        DocumentClassConstPtr text_class_;
        ///
@@ -310,7 +320,7 @@ DynamicMenuButton::~DynamicMenuButton()
 
 void DynamicMenuButton::initialize()
 {
-       QString const label = qt_(to_ascii(tbitem_.label_));
+       QString const label = qt_(to_ascii(tbitem_.label));
        ButtonMenu * m = new ButtonMenu(label, this);
        m->setWindowTitle(label);
        m->setTearOffEnabled(true);
@@ -340,7 +350,7 @@ void DynamicMenuButton::updateTriggered()
        GuiView const & owner = bar_->owner();
        BufferView const * bv = owner.currentBufferView();
 
-       string const & menutype = tbitem_.name_;
+       string const & menutype = tbitem_.name;
        if (menutype == "dynamic-custom-insets" || menutype == "dynamic-char-styles") {
                if (!bv) {
                        m->clear();
@@ -437,12 +447,12 @@ void DynamicMenuButton::loadFlexInsets()
 {
        QMenu * m = menu();
        m->clear();
-       string const & menutype = tbitem_.name_;
-       InsetLayout::InsetLyXType ftype;
+       string const & menutype = tbitem_.name;
+       InsetLyXType ftype;
        if (menutype == "dynamic-custom-insets")
-               ftype = InsetLayout::CUSTOM;
+               ftype = InsetLyXType::CUSTOM;
        else if (menutype == "dynamic-char-styles")
-               ftype = InsetLayout::CHARSTYLE;
+               ftype = InsetLyXType::CHARSTYLE;
        else {
                // this should have been taken care of earlier
                LASSERT(false, return);
@@ -469,7 +479,7 @@ void DynamicMenuButton::loadFlexInsets()
 
 void GuiToolbar::add(ToolbarItem const & item)
 {
-       switch (item.type_) {
+       switch (item.type) {
        case ToolbarItem::SEPARATOR:
                addSeparator();
                break;
@@ -491,7 +501,7 @@ void GuiToolbar::add(ToolbarItem const & item)
                QToolButton * tb = new QToolButton;
                tb->setCheckable(true);
                tb->setIcon(getIcon(FuncRequest(LFUN_TABULAR_INSERT), true));
-               QString const label = qt_(to_ascii(item.label_));
+               QString const label = qt_(to_ascii(item.label));
                tb->setToolTip(label);
                tb->setStatusTip(label);
                tb->setText(label);
@@ -515,19 +525,19 @@ void GuiToolbar::add(ToolbarItem const & item)
                }
        case ToolbarItem::DYNAMICMENU: {
                // we only handle certain things
-               if (DynamicMenuButton::isMenuType(item.name_))
+               if (DynamicMenuButton::isMenuType(item.name))
                        addWidget(new DynamicMenuButton(this, item));
                else
-                       LYXERR0("Unknown dynamic menu type: " << item.name_);
+                       LYXERR0("Unknown dynamic menu type: " << item.name);
                break;
        }
        case ToolbarItem::BIDICOMMAND: {
-               if (!getStatus(*item.func_).unknown())
+               if (!getStatus(*item.func).unknown())
                        addAction(addItem(item));
                break;
                }
        case ToolbarItem::COMMAND: {
-               if (!getStatus(*item.func_).unknown())
+               if (!getStatus(*item.func).unknown())
                        addAction(addItem(item));
                break;
                }
@@ -551,8 +561,8 @@ void GuiToolbar::update(int context)
 
        // This is a speed bottleneck because this is called on every keypress
        // and update calls getStatus, which copies the cursor at least two times
-       for (int i = 0; i < actions_.size(); ++i)
-               actions_[i]->update();
+       for (auto const & action : actions_)
+               action->update();
 
        LayoutBox * layout = owner_.getLayoutDialog();
        if (layout)
@@ -595,36 +605,57 @@ void GuiToolbar::restoreSession()
 }
 
 
-void GuiToolbar::toggle()
+bool GuiToolbar::isVisibiltyOn() const
 {
-       docstring state;
-       if (visibility_ & Toolbars::ALLOWAUTO) {
-               if (!(visibility_ & Toolbars::AUTO)) {
+       return visibility_ & Toolbars::ON;
+}
+
+
+void GuiToolbar::setState(string const state)
+{
+       docstring newstate;
+       if (state == "auto") {
+               if (visibility_ & Toolbars::ALLOWAUTO) {
                        visibility_ |= Toolbars::AUTO;
                        hide();
-                       state = _("auto");
-               } else {
-                       visibility_ &= ~Toolbars::AUTO;
-                       if (isVisible()) {
-                               hide();
-                               state = _("off");
-                       } else {
-                               show();
-                               state = _("on");
-                       }
-               }
+                       newstate = _("auto");
+               } else
+                       owner_.message(bformat(_("Toolbar \"%1$s\" does not support state \"auto\""),
+                               qstring_to_ucs4(windowTitle())));
        } else {
-               if (isVisible()) {
+               if (visibility_ & Toolbars::AUTO)
+                       visibility_ &= ~Toolbars::AUTO;
+               if (state == "off") {
                        hide();
-                       state = _("off");
-               } else {
+                       newstate = _("off");
+               } else if (state == "on") {
                        show();
-                       state = _("on");
+                       newstate = _("on");
                }
        }
 
        owner_.message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
-               qstring_to_ucs4(windowTitle()), state));
+               qstring_to_ucs4(windowTitle()), newstate));
+}
+
+
+void GuiToolbar::toggle()
+{
+       if (visibility_ & Toolbars::ALLOWAUTO) {
+               if (!(visibility_ & Toolbars::AUTO) && !isVisibiltyOn()) {
+                       setState("auto");
+               } else {
+                       if (isVisibiltyOn())
+                               setState("off");
+                       else
+                               setState("on");
+               }
+       } else {
+               if (isVisible())
+                       setState("off");
+               else
+                       setState("on");
+       }
 }
 
 void GuiToolbar::movable(bool silent)