X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FGuiView.cpp;h=791a2c2b42a52bc34d29c82eb02425608deb904f;hb=d4324034300f73f76e5ac34fb1e7653fa6e2ddf5;hp=7dd05f06aa13aaf5934e37fad0473f3b9077fb3e;hpb=934c6480c0cdbeb6e3abbef0bba72dd3d191b11d;p=features.git diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp index 7dd05f06aa..791a2c2b42 100644 --- a/src/frontends/qt/GuiView.cpp +++ b/src/frontends/qt/GuiView.cpp @@ -96,7 +96,6 @@ #include #include #include -#include #include #include #include @@ -111,6 +110,8 @@ #include #include #include +#include +#include // sync with GuiAlert.cpp @@ -208,7 +209,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,20 +612,19 @@ 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()); @@ -650,14 +649,19 @@ GuiView::GuiView(int id) zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust.")); // Buttons to change zoom stepwise - zoom_in_ = new QPushButton(statusBar()); +#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_->setFlat(true); - zoom_in_->setFixedSize(QSize(fm.height(), fm.height())); - zoom_out_ = new QPushButton(statusBar()); - zoom_out_->setText(QString(0x2212)); - zoom_out_->setFixedSize(QSize(fm.height(), fm.height())); - zoom_out_->setFlat(true); + 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()); @@ -672,39 +676,28 @@ GuiView::GuiView(int id) connect(zoom_in_, SIGNAL(clicked()), this, SLOT(zoomInPressed())); connect(zoom_out_, SIGNAL(clicked()), this, SLOT(zoomOutPressed())); - zoom_value_ = new QToolButton(statusBar()); - zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), zoom))); - zoom_value_->setToolButtonStyle(Qt::ToolButtonTextOnly); - zoom_value_->setAutoRaise(true); - zoom_value_->setPopupMode(QToolButton::InstantPopup); + // QPalette palette = statusBar()->palette(); + + zoom_value_ = new QLabel(statusBar()); + // 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()); - act_zoom_default_ = new QAction(toqstr(bformat(_("&Reset to default (%1$d%)"), - lyxrc.defaultZoom)), this); - act_zoom_in_ = new QAction(qt_("Zoom &in"), this); - act_zoom_out_ = new QAction(qt_("Zoom &out"), this); - act_zoom_show_ = new QAction(qt_("Show zoom slider"), this); - act_zoom_show_->setCheckable(true); - zoom_value_->addAction(act_zoom_default_); - zoom_value_->addAction(act_zoom_in_); - zoom_value_->addAction(act_zoom_out_); - zoom_value_->addAction(act_zoom_show_); - enableZoomOptions(); - connect(act_zoom_default_, SIGNAL(triggered()), - this, SLOT(resetDefaultZoom())); - connect(act_zoom_in_, SIGNAL(triggered()), - this, SLOT(zoomInPressed())); - connect(act_zoom_out_, SIGNAL(triggered()), - this, SLOT(zoomOutPressed())); - connect(act_zoom_show_, SIGNAL(triggered()), - this, SLOT(toogleZoomSlider())); + statusBar()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(statusBar(), SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(showZoomContextMenu())); + + // enable pinch to zoom + grabGesture(Qt::PinchGesture); int const iconheight = max(int(d.normalIconSize), fm.height()); QSize const iconsize(iconheight, iconheight); @@ -803,20 +796,11 @@ void GuiView::checkCancelBackground() } -void GuiView::enableZoomOptions() -{ - act_zoom_default_->setEnabled(zoom_slider_->value() != lyxrc.defaultZoom); - FuncStatus status; - act_zoom_in_->setEnabled(getStatus(FuncRequest(LFUN_BUFFER_ZOOM_IN), status)); - act_zoom_out_->setEnabled(getStatus(FuncRequest(LFUN_BUFFER_ZOOM_OUT), status)); -} - - void GuiView::zoomSliderMoved(int value) { DispatchResult dr; dispatch(FuncRequest(LFUN_BUFFER_ZOOM, convert(value)), dr); - currentWorkArea()->scheduleRedraw(true); + scheduleRedrawWorkAreas(); zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), value))); } @@ -825,7 +809,6 @@ void GuiView::zoomValueChanged(int value) { if (value != lyxrc.currentZoom) zoomSliderMoved(value); - enableZoomOptions(); } @@ -833,7 +816,7 @@ void GuiView::zoomInPressed() { DispatchResult dr; dispatch(FuncRequest(LFUN_BUFFER_ZOOM_IN), dr); - currentWorkArea()->scheduleRedraw(true); + scheduleRedrawWorkAreas(); } @@ -841,21 +824,27 @@ void GuiView::zoomOutPressed() { DispatchResult dr; dispatch(FuncRequest(LFUN_BUFFER_ZOOM_OUT), dr); - currentWorkArea()->scheduleRedraw(true); + scheduleRedrawWorkAreas(); } -void GuiView::toogleZoomSlider() +void GuiView::showZoomContextMenu() { - DispatchResult dr; - dispatch(FuncRequest(LFUN_UI_TOGGLE, "zoomslider"), dr); + QMenu * menu = guiApp->menus().menu(toqstr("context-statusbar"), * this); + if (!menu) + return; + menu->exec(QCursor::pos()); } -void GuiView::resetDefaultZoom() +void GuiView::scheduleRedrawWorkAreas() { - zoomValueChanged(lyxrc.defaultZoom); - enableZoomOptions(); + 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); + } + } } @@ -961,6 +950,7 @@ 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()); } @@ -1005,9 +995,10 @@ 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); - act_zoom_show_->setChecked(show_zoom_slider); zoom_in_->setVisible(show_zoom_slider); zoom_out_->setVisible(show_zoom_slider); @@ -1076,6 +1067,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 } @@ -1094,6 +1090,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(); } @@ -1217,7 +1215,7 @@ bool GuiView::prepareAllBuffersForLogout() // We cannot use a for loop as the buffer list cycles. Buffer * b = first; do { - if (!saveBufferIfNeeded(const_cast(*b), false)) + if (!saveBufferIfNeeded(*b, false)) return false; b = theBufferList().next(b); } while (b != first); @@ -1551,7 +1549,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) @@ -1572,7 +1570,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(); } @@ -1584,7 +1582,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) { @@ -1627,6 +1626,21 @@ bool GuiView::event(QEvent * e) return QMainWindow::event(e); } + case QEvent::Gesture: { + QGestureEvent *ge = static_cast(e); + QGesture *gp = ge->gesture(Qt::PinchGesture); + if (gp) { + QPinchGesture *pinch = static_cast(gp); + QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); + if (changeFlags & QPinchGesture::ScaleFactorChanged) { + qreal factor = lyxrc.currentZoom*pinch->scaleFactor(); + //factor = ceil(factor/20)*20; + zoomValueChanged(factor); + } + } + return QMainWindow::event(e); + } + default: return QMainWindow::event(e); } @@ -1898,6 +1912,7 @@ void GuiView::updateToolbars() void GuiView::refillToolbars() { + DynamicMenuButton::resetIconCache(); for (auto const & tb_p : d.toolbars_) tb_p.second->refill(); } @@ -2360,9 +2375,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; case LFUN_UI_TOGGLE: - if (cmd.argument() == "zoomslider") { - enable = doc_buffer; - flag.setOnOff(zoom_slider_->isVisible()); + 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; @@ -2481,7 +2497,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; @@ -2641,7 +2658,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); @@ -3200,7 +3221,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 " @@ -4517,12 +4538,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; } @@ -4865,11 +4885,12 @@ bool GuiView::lfunUiToggle(string const & ui_component) statusBar()->setVisible(!statusBar()->isVisible()); } else if (ui_component == "menubar") { menuBar()->setVisible(!menuBar()->isVisible()); + } 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()); - act_zoom_show_->setChecked(zoom_slider_->isVisible()); } else if (ui_component == "frame") { int const l = contentsMargins().left(); @@ -5158,6 +5179,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