]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt/GuiView.cpp
Correct white space.
[features.git] / src / frontends / qt / GuiView.cpp
index e7a129b1a25fdb94dcd41aaad393a28664459334..ffcbc3d3ac8b4af44847de91bdaa8fa7d6229023 100644 (file)
@@ -96,7 +96,6 @@
 #include <QMenu>
 #include <QMenuBar>
 #include <QMimeData>
-#include <QMovie>
 #include <QPainter>
 #include <QPixmap>
 #include <QPoint>
@@ -208,7 +207,6 @@ public:
                QStringList titlesegs = htext.split('\n');
                int wline = 0;
                int hline = fm.maxHeight();
-               QStringList::const_iterator sit;
                for (QString const & seg : titlesegs) {
                        if (fm.width(seg) > wline)
                                wline = fm.width(seg);
@@ -612,24 +610,25 @@ GuiView::GuiView(int id)
        setAcceptDrops(true);
 
        // add busy indicator to statusbar
-       GuiClickableLabel * busylabel = new GuiClickableLabel(statusBar());
-       statusBar()->addPermanentWidget(busylabel);
        search_mode mode = theGuiApp()->imageSearchMode();
-       QString fn = toqstr(lyx::libFileSearch("images", "busy", "gif", mode).absFileName());
-       QMovie * busyanim = new QMovie(fn, QByteArray(), busylabel);
-       busylabel->setMovie(busyanim);
-       busyanim->start();
-       busylabel->hide();
+       QString fn = toqstr(lyx::libFileSearch("images", "busy", "svgz", mode).absFileName());
+       PressableSvgWidget * busySVG = new PressableSvgWidget(fn);
+       statusBar()->addPermanentWidget(busySVG);
+       // make busy indicator square with 5px margins
+       busySVG->setMaximumSize(busySVG->height() - 5, busySVG->height() - 5);
+       busySVG->hide();
 
        connect(&d.processing_thread_watcher_, SIGNAL(started()),
-               busylabel, SLOT(show()));
+               busySVG, SLOT(show()));
        connect(&d.processing_thread_watcher_, SIGNAL(finished()),
-               busylabel, SLOT(hide()));
-       connect(busylabel, SIGNAL(clicked()), this, SLOT(checkCancelBackground()));
+               busySVG, SLOT(hide()));
+       connect(busySVG, SIGNAL(pressed()), this, SLOT(checkCancelBackground()));
 
        QFontMetrics const fm(statusBar()->fontMetrics());
 
        zoom_slider_ = new QSlider(Qt::Horizontal, statusBar());
+       // Small size slider for macOS to prevent the status bar from enlarging
+       zoom_slider_->setAttribute(Qt::WA_MacSmallSize);
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
        zoom_slider_->setFixedWidth(fm.horizontalAdvance('x') * 15);
 #else
@@ -646,32 +645,61 @@ GuiView::GuiView(int id)
                zoom = zoom_min_;
        zoom_slider_->setValue(zoom);
        zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust."));
-       zoom_slider_->setTickPosition(QSlider::TicksBelow);
-       zoom_slider_->setTickInterval(lyxrc.defaultZoom - 10);
+
+       // Buttons to change zoom stepwise
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
+       QSize s(fm.horizontalAdvance('+'), fm.height());
+#else
+       QSize s(fm.width('+'), fm.height());
+#endif
+       zoom_in_ = new GuiClickableLabel(statusBar());
+       zoom_in_->setText("+");
+       zoom_in_->setFixedSize(s);
+       zoom_in_->setAlignment(Qt::AlignCenter);
+       zoom_out_ = new GuiClickableLabel(statusBar());
+       zoom_out_->setText(QString(QChar(0x2212)));
+       zoom_out_->setFixedSize(s);
+       zoom_out_->setAlignment(Qt::AlignCenter);
+
+       statusBar()->addPermanentWidget(zoom_out_);
+       zoom_out_->setEnabled(currentBufferView());
        statusBar()->addPermanentWidget(zoom_slider_);
        zoom_slider_->setEnabled(currentBufferView());
+       zoom_in_->setEnabled(currentBufferView());
+       statusBar()->addPermanentWidget(zoom_in_);
 
        connect(zoom_slider_, SIGNAL(sliderMoved(int)), this, SLOT(zoomSliderMoved(int)));
        connect(zoom_slider_, SIGNAL(valueChanged(int)), this, SLOT(zoomValueChanged(int)));
        connect(this, SIGNAL(currentZoomChanged(int)), zoom_slider_, SLOT(setValue(int)));
+       connect(zoom_in_, SIGNAL(clicked()), this, SLOT(zoomInPressed()));
+       connect(zoom_out_, SIGNAL(clicked()), this, SLOT(zoomOutPressed()));
+
+       // QPalette palette = statusBar()->palette();
 
        zoom_value_ = new QLabel(statusBar());
-       zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), zoom)));
+       // zoom_value_->setPalette(palette);
+       zoom_value_->setForegroundRole(statusBar()->foregroundRole());
+       zoom_value_->setFixedHeight(fm.height());
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
-       zoom_value_->setMinimumWidth(fm.horizontalAdvance("000%"));
+       zoom_value_->setMinimumWidth(fm.horizontalAdvance("444\%"));
 #else
-       zoom_value_->setMinimumWidth(fm.width("000%"));
+       zoom_value_->setMinimumWidth(fm.width("444\%"));
 #endif
+       zoom_value_->setAlignment(Qt::AlignCenter);
+       zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), zoom)));
        statusBar()->addPermanentWidget(zoom_value_);
        zoom_value_->setEnabled(currentBufferView());
 
+       statusBar()->setContextMenuPolicy(Qt::CustomContextMenu);
+       connect(statusBar(), SIGNAL(customContextMenuRequested(QPoint)),
+               this, SLOT(showZoomContextMenu()));
+
        int const iconheight = max(int(d.normalIconSize), fm.height());
        QSize const iconsize(iconheight, iconheight);
 
        QPixmap shellescape = QIcon(getPixmap("images/", "emblem-shellescape", "svgz,png")).pixmap(iconsize);
        shell_escape_ = new QLabel(statusBar());
        shell_escape_->setPixmap(shellescape);
-       shell_escape_->setScaledContents(true);
        shell_escape_->setAlignment(Qt::AlignCenter);
        shell_escape_->setContextMenuPolicy(Qt::CustomContextMenu);
        shell_escape_->setToolTip(qt_("WARNING: LaTeX is allowed to execute "
@@ -686,7 +714,6 @@ GuiView::GuiView(int id)
        QPixmap readonly = QIcon(getPixmap("images/", "emblem-readonly", "svgz,png")).pixmap(iconsize);
        read_only_ = new QLabel(statusBar());
        read_only_->setPixmap(readonly);
-       read_only_->setScaledContents(true);
        read_only_->setAlignment(Qt::AlignCenter);
        read_only_->hide();
        statusBar()->addPermanentWidget(read_only_);
@@ -768,7 +795,7 @@ void GuiView::zoomSliderMoved(int value)
 {
        DispatchResult dr;
        dispatch(FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(value)), dr);
-       currentWorkArea()->scheduleRedraw(true);
+       scheduleRedrawWorkAreas();
        zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), value)));
 }
 
@@ -780,6 +807,42 @@ void GuiView::zoomValueChanged(int value)
 }
 
 
+void GuiView::zoomInPressed()
+{
+       DispatchResult dr;
+       dispatch(FuncRequest(LFUN_BUFFER_ZOOM_IN), dr);
+       scheduleRedrawWorkAreas();
+}
+
+
+void GuiView::zoomOutPressed()
+{
+       DispatchResult dr;
+       dispatch(FuncRequest(LFUN_BUFFER_ZOOM_OUT), dr);
+       scheduleRedrawWorkAreas();
+}
+
+
+void GuiView::showZoomContextMenu()
+{
+       QMenu * menu = guiApp->menus().menu(toqstr("context-statusbar"), * this);
+       if (!menu)
+               return;
+       menu->exec(QCursor::pos());
+}
+
+
+void GuiView::scheduleRedrawWorkAreas()
+{
+       for (int i = 0; i < d.tabWorkAreaCount(); i++) {
+               TabWorkArea* ta = d.tabWorkArea(i);
+               for (int u = 0; u < ta->count(); u++) {
+                       ta->workArea(u)->scheduleRedraw(true);
+               }
+       }
+}
+
+
 QVector<GuiWorkArea*> GuiView::GuiViewPrivate::guiWorkAreas()
 {
        QVector<GuiWorkArea*> areas;
@@ -882,6 +945,8 @@ void GuiView::saveLayout() const
                settings.setValue("geometry", saveGeometry());
        settings.setValue("layout", saveState(0));
        settings.setValue("icon_size", toqstr(d.iconSize(iconSize())));
+       settings.setValue("zoom_value_visible", zoom_value_->isVisible());
+       settings.setValue("zoom_slider_visible", zoom_slider_->isVisible());
 }
 
 
@@ -925,6 +990,13 @@ bool GuiView::restoreLayout()
        //code below is skipped when when ~/.config/LyX is (re)created
        setIconSize(d.iconSize(settings.value(icon_key).toString()));
 
+       zoom_value_->setVisible(settings.value("zoom_value_visible", true).toBool());
+
+       bool const show_zoom_slider = settings.value("zoom_slider_visible", true).toBool();
+       zoom_slider_->setVisible(show_zoom_slider);
+       zoom_in_->setVisible(show_zoom_slider);
+       zoom_out_->setVisible(show_zoom_slider);
+
        if (guiApp->platformName() == "qt4x11" || guiApp->platformName() == "xcb") {
                QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
                QSize size = settings.value("size", QSize(690, 510)).toSize();
@@ -990,6 +1062,11 @@ void GuiView::updateLockToolbars()
                if (tb && tb->isMovable())
                        toolbarsMovable_ = true;
        }
+#if QT_VERSION >= 0x050200
+       // set unified mac toolbars only when not movable as recommended:
+       // https://doc.qt.io/qt-5/qmainwindow.html#unifiedTitleAndToolBarOnMac-prop
+       setUnifiedTitleAndToolBarOnMac(!toolbarsMovable_);
+#endif
 }
 
 
@@ -1008,6 +1085,8 @@ void GuiView::constructToolbars()
        // extracts the toolbars from the backend
        for (ToolbarInfo const & inf : guiApp->toolbars())
                d.toolbars_[inf.name] =  new GuiToolbar(inf, *this);
+
+       DynamicMenuButton::resetIconCache();
 }
 
 
@@ -1131,7 +1210,7 @@ bool GuiView::prepareAllBuffersForLogout()
        // We cannot use a for loop as the buffer list cycles.
        Buffer * b = first;
        do {
-               if (!saveBufferIfNeeded(const_cast<Buffer &>(*b), false))
+               if (!saveBufferIfNeeded(*b, false))
                        return false;
                b = theBufferList().next(b);
        } while (b != first);
@@ -1367,6 +1446,8 @@ void GuiView::onBufferViewChanged()
        updateDialogs();
        zoom_slider_->setEnabled(currentBufferView());
        zoom_value_->setEnabled(currentBufferView());
+       zoom_in_->setEnabled(currentBufferView());
+       zoom_out_->setEnabled(currentBufferView());
 }
 
 
@@ -1463,7 +1544,7 @@ bool GuiView::event(QEvent * e)
                                menuBar()->hide();
                        if (lyxrc.full_screen_toolbars) {
                                for (auto const & tb_p  : d.toolbars_)
-                                       if (tb_p.second->isVisibiltyOn() && tb_p.second->isVisible())
+                                       if (tb_p.second->isVisibilityOn() && tb_p.second->isVisible())
                                                tb_p.second->hide();
                        }
                        for (int i = 0; i != d.splitter_->count(); ++i)
@@ -1484,7 +1565,7 @@ bool GuiView::event(QEvent * e)
                                menuBar()->show();
                        if (lyxrc.full_screen_toolbars) {
                                for (auto const & tb_p  : d.toolbars_)
-                                       if (tb_p.second->isVisibiltyOn() && !tb_p.second->isVisible())
+                                       if (tb_p.second->isVisibilityOn() && !tb_p.second->isVisible())
                                                tb_p.second->show();
                                //updateToolbars();
                        }
@@ -1496,7 +1577,8 @@ bool GuiView::event(QEvent * e)
                        setContentsMargins(0, 0, 0, 0);
                }
                return result;
-               }
+       }
+
        case QEvent::WindowActivate: {
                GuiView * old_view = guiApp->currentView();
                if (this == old_view) {
@@ -1810,6 +1892,7 @@ void GuiView::updateToolbars()
 
 void GuiView::refillToolbars()
 {
+       DynamicMenuButton::resetIconCache();
        for (auto const & tb_p : d.toolbars_)
                tb_p.second->refill();
 }
@@ -2272,7 +2355,12 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                break;
 
        case LFUN_UI_TOGGLE:
-               flag.setOnOff(isFullScreen());
+               if (cmd.argument() == "zoom") {
+                       flag.setOnOff(zoom_value_ ? zoom_value_->isVisible() : false);
+               } else if (cmd.argument() == "zoomslider") {
+                       flag.setOnOff(zoom_slider_ ? zoom_slider_->isVisible() : false);
+               } else
+                       flag.setOnOff(isFullScreen());
                break;
 
        case LFUN_DIALOG_DISCONNECT_INSET:
@@ -2389,7 +2477,8 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                                bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
                        flag.message(msg);
                        enable = false;
-               }
+               } else if (cmd.argument().empty() && lyxrc.currentZoom == lyxrc.defaultZoom)
+                       enable = false;
                else
                        enable = doc_buffer;
                break;
@@ -2549,7 +2638,11 @@ void GuiView::openDocument(string const & fname)
                dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
                dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
 
-               QStringList const filter(qt_("LyX Documents (*.lyx)"));
+               QStringList const filter({
+                               qt_("LyX Documents (*.lyx)"),
+                               qt_("LyX Document Backups (*.lyx~)"),
+                               qt_("All Files (*.*)")
+               });
                FileDialog::Result result =
                        dlg.open(toqstr(initpath), filter);
 
@@ -3108,7 +3201,7 @@ bool GuiView::exportBufferAs(Buffer & b, docstring const & iformat)
                return false;
 
        // fname is now the new Buffer location.
-       if (FileName(fname).exists()) {
+       if (fname.exists()) {
                docstring const file = makeDisplayPath(fname.absFileName(), 30);
                docstring text = bformat(_("The document %1$s already "
                                           "exists.\n\nDo you want to "
@@ -4425,12 +4518,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                                        dr.setMessage(_("Toolbars unlocked."));
                                else
                                        dr.setMessage(_("Toolbars locked."));
-                       } else if (GuiToolbar * t = toolbar(name)) {
+                       } else if (GuiToolbar * tb = toolbar(name))
                                // toggle current toolbar movablity
-                               t->movable();
-                               // update lock (all) toolbars positions
-                               updateLockToolbars();
-                       }
+                               tb->movable();
+                       // update lock (all) toolbars positions
+                       updateLockToolbars();
                        break;
                }
 
@@ -4773,8 +4865,13 @@ bool GuiView::lfunUiToggle(string const & ui_component)
                statusBar()->setVisible(!statusBar()->isVisible());
        } else if (ui_component == "menubar") {
                menuBar()->setVisible(!menuBar()->isVisible());
-       } else
-       if (ui_component == "frame") {
+       } else if (ui_component == "zoom") {
+               zoom_value_->setVisible(!zoom_value_->isVisible());
+       } else if (ui_component == "zoomslider") {
+               zoom_slider_->setVisible(!zoom_slider_->isVisible());
+               zoom_in_->setVisible(zoom_slider_->isVisible());
+               zoom_out_->setVisible(zoom_slider_->isVisible());
+       } else if (ui_component == "frame") {
                int const l = contentsMargins().left();
 
                //are the frames in default state?
@@ -5062,6 +5159,14 @@ SEMenu::SEMenu(QWidget * parent)
                parent, SLOT(disableShellEscape()));
 }
 
+
+void PressableSvgWidget::mousePressEvent(QMouseEvent * event)
+{
+       if (event->button() == Qt::LeftButton) {
+        Q_EMIT pressed();
+    }
+}
+
 } // namespace frontend
 } // namespace lyx