X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FGuiView.cpp;h=791a2c2b42a52bc34d29c82eb02425608deb904f;hb=d4324034300f73f76e5ac34fb1e7653fa6e2ddf5;hp=6e87f007f93151b27ab99bf45d5fce837529f9a4;hpb=c293be56bd12c5dc46e5cedd2828e33918fccef7;p=features.git diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp index 6e87f007f9..791a2c2b42 100644 --- a/src/frontends/qt/GuiView.cpp +++ b/src/frontends/qt/GuiView.cpp @@ -15,13 +15,14 @@ #include "GuiView.h" +#include "DialogFactory.h" #include "DispatchResult.h" #include "FileDialog.h" #include "FontLoader.h" #include "GuiApplication.h" #include "GuiClickableLabel.h" -#include "GuiCommandBuffer.h" #include "GuiCompleter.h" +#include "GuiFontMetrics.h" #include "GuiKeySymbol.h" #include "GuiToc.h" #include "GuiToolbar.h" @@ -51,9 +52,8 @@ #include "Format.h" #include "FuncStatus.h" #include "FuncRequest.h" -#include "Intl.h" +#include "KeySymbol.h" #include "Language.h" -#include "Layout.h" #include "LayoutFile.h" #include "Lexer.h" #include "LyXAction.h" @@ -64,7 +64,6 @@ #include "SpellChecker.h" #include "Session.h" #include "TexRow.h" -#include "TextClass.h" #include "Text.h" #include "Toolbars.h" #include "version.h" @@ -73,9 +72,7 @@ #include "support/debug.h" #include "support/ExceptionMessage.h" #include "support/FileName.h" -#include "support/filetools.h" #include "support/gettext.h" -#include "support/filetools.h" #include "support/ForkedCalls.h" #include "support/lassert.h" #include "support/lstrings.h" @@ -89,35 +86,32 @@ #include #include #include -#include -#include #include #include #include #include +#include #include #include #include #include #include -#include #include #include #include -#include -#include #include #include +#include #include #include #include #include #include -#include #include -#include #include - +#include +#include +#include // sync with GuiAlert.cpp @@ -209,16 +203,15 @@ public: // Check how long the logo gets with the current font // and adapt if the font is running wider than what // we assume - QFontMetrics fm(font); + GuiFontMetrics fm(font); // Split the title into lines to measure the longest line // in the current l7n. QStringList titlesegs = htext.split('\n'); int wline = 0; - int hline = fm.height(); - QStringList::const_iterator sit; - for (sit = titlesegs.constBegin(); sit != titlesegs.constEnd(); ++sit) { - if (fm.width(*sit) > wline) - wline = fm.width(*sit); + int hline = fm.maxHeight(); + for (QString const & seg : titlesegs) { + if (fm.width(seg) > wline) + wline = fm.width(seg); } // The longest line in the reference font (for English) // is 180. Calculate scale factor from that. @@ -235,7 +228,7 @@ public: setFocusPolicy(Qt::StrongFocus); } - void paintEvent(QPaintEvent *) + void paintEvent(QPaintEvent *) override { int const w = width_; int const h = height_; @@ -249,7 +242,7 @@ public: pain.drawPixmap(x, y, w, h, splash_); } - void keyPressEvent(QKeyEvent * ev) + void keyPressEvent(QKeyEvent * ev) override { KeySymbol sym; setKeySymbol(&sym, ev); @@ -316,8 +309,8 @@ class GuiView::GuiViewPrivate void operator=(GuiViewPrivate const &); public: GuiViewPrivate(GuiView * gv) - : gv_(gv), current_work_area_(0), current_main_work_area_(0), - layout_(0), autosave_timeout_(5000), + : gv_(gv), current_work_area_(nullptr), current_main_work_area_(nullptr), + layout_(nullptr), autosave_timeout_(5000), in_show_(false) { // hardcode here the platform specific icon size @@ -480,6 +473,29 @@ public: return icon_size; } + static Buffer::ExportStatus previewAndDestroy(Buffer const * orig, + Buffer * buffer, string const & format); + static Buffer::ExportStatus exportAndDestroy(Buffer const * orig, + Buffer * buffer, string const & format); + static Buffer::ExportStatus compileAndDestroy(Buffer const * orig, + Buffer * buffer, string const & format); + static docstring autosaveAndDestroy(Buffer const * orig, Buffer * buffer); + + template + static Buffer::ExportStatus runAndDestroy(const T& func, + Buffer const * orig, Buffer * buffer, string const & format); + + // TODO syncFunc/previewFunc: use bind + bool asyncBufferProcessing(string const & argument, + Buffer const * used_buffer, + docstring const & msg, + Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &), + Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const, + Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const, + bool allow_async, bool use_tmpdir = false); + + QVector guiWorkAreas(); + public: GuiView * gv_; GuiWorkArea * current_work_area_; @@ -504,17 +520,10 @@ public: /// map dialogs_; - unsigned int smallIconSize; - unsigned int normalIconSize; - unsigned int bigIconSize; - unsigned int hugeIconSize; - unsigned int giantIconSize; /// QTimer statusbar_timer_; /// auto-saving of buffers Timeout autosave_timeout_; - /// flag against a race condition due to multiclicks, see bug #1119 - bool in_show_; /// TocModels toc_models_; @@ -527,28 +536,15 @@ public: string processing_format; static QSet busyBuffers; - static Buffer::ExportStatus previewAndDestroy(Buffer const * orig, - Buffer * buffer, string const & format); - static Buffer::ExportStatus exportAndDestroy(Buffer const * orig, - Buffer * buffer, string const & format); - static Buffer::ExportStatus compileAndDestroy(Buffer const * orig, - Buffer * buffer, string const & format); - static docstring autosaveAndDestroy(Buffer const * orig, Buffer * buffer); - template - static Buffer::ExportStatus runAndDestroy(const T& func, - Buffer const * orig, Buffer * buffer, string const & format); - - // TODO syncFunc/previewFunc: use bind - bool asyncBufferProcessing(string const & argument, - Buffer const * used_buffer, - docstring const & msg, - Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &), - Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const, - Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const, - bool allow_async); + unsigned int smallIconSize; + unsigned int normalIconSize; + unsigned int bigIconSize; + unsigned int hugeIconSize; + unsigned int giantIconSize; - QVector guiWorkAreas(); + /// flag against a race condition due to multiclicks, see bug #1119 + bool in_show_; }; QSet GuiView::GuiViewPrivate::busyBuffers; @@ -607,33 +603,108 @@ GuiView::GuiView(int id) // (such as "source" and "messages") setDockOptions(QMainWindow::ForceTabbedDocks); +#ifdef Q_OS_MAC + // use document mode tabs on docks + setDocumentMode(true); +#endif + // For Drag&Drop. 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 + zoom_slider_->setFixedWidth(fm.width('x') * 15); +#endif + // Make the defaultZoom center + zoom_slider_->setRange(10, (lyxrc.defaultZoom * 2) - 10); + // Initialize proper zoom value + QSettings settings; + zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble(); + // Actual zoom value: default zoom + fractional offset + int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); + if (zoom < static_cast(zoom_min_)) + zoom = zoom_min_; + zoom_slider_->setValue(zoom); + zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust.")); + + // 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_->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("444\%")); +#else + 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())); + + // enable pinch to zoom + grabGesture(Qt::PinchGesture); + 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 " @@ -648,7 +719,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_); @@ -693,7 +763,6 @@ GuiView::GuiView(int id) initToolbars(); // clear session data if any. - QSettings settings; settings.remove("views"); } @@ -727,6 +796,58 @@ void GuiView::checkCancelBackground() } +void GuiView::zoomSliderMoved(int value) +{ + DispatchResult dr; + dispatch(FuncRequest(LFUN_BUFFER_ZOOM, convert(value)), dr); + scheduleRedrawWorkAreas(); + zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), value))); +} + + +void GuiView::zoomValueChanged(int value) +{ + if (value != lyxrc.currentZoom) + zoomSliderMoved(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 GuiView::GuiViewPrivate::guiWorkAreas() { QVector areas; @@ -742,7 +863,7 @@ QVector GuiView::GuiViewPrivate::guiWorkAreas() static void handleExportStatus(GuiView * view, Buffer::ExportStatus status, string const & format) { - docstring const fmt = theFormats().prettyName(format); + docstring const fmt = translateIfPossible(theFormats().prettyName(format)); docstring msg; switch (status) { case Buffer::ExportSuccess: @@ -822,14 +943,15 @@ void GuiView::saveLayout() const settings.setValue("devel_mode", devel_mode_); settings.beginGroup("views"); settings.beginGroup(QString::number(id_)); -#if defined(Q_WS_X11) || defined(QPA_XCB) - settings.setValue("pos", pos()); - settings.setValue("size", size()); -#else - settings.setValue("geometry", saveGeometry()); -#endif + if (guiApp->platformName() == "qt4x11" || guiApp->platformName() == "xcb") { + settings.setValue("pos", pos()); + settings.setValue("size", size()); + } else + 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()); } @@ -838,13 +960,19 @@ void GuiView::saveUISettings() const QSettings settings; // Save the toolbar private states - ToolbarMap::iterator end = d.toolbars_.end(); - for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it) - it->second->saveSession(settings); + for (auto const & tb_p : d.toolbars_) + tb_p.second->saveSession(settings); // Now take care of all other dialogs - map::const_iterator it = d.dialogs_.begin(); - for (; it!= d.dialogs_.end(); ++it) - it->second->saveSession(settings); + for (auto const & dlg_p : d.dialogs_) + dlg_p.second->saveSession(settings); +} + + +void GuiView::setCurrentZoom(const int v) +{ + lyxrc.currentZoom = v; + zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), v))); + Q_EMIT currentZoomChanged(v); } @@ -853,10 +981,10 @@ bool GuiView::restoreLayout() QSettings settings; zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble(); // Actual zoom value: default zoom + fractional offset - int zoom = lyxrc.defaultZoom * zoom_ratio_; + int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); if (zoom < static_cast(zoom_min_)) zoom = zoom_min_; - lyxrc.currentZoom = zoom; + setCurrentZoom(zoom); devel_mode_ = settings.value("devel_mode", devel_mode_).toBool(); settings.beginGroup("views"); settings.beginGroup(QString::number(id_)); @@ -867,19 +995,27 @@ bool GuiView::restoreLayout() //code below is skipped when when ~/.config/LyX is (re)created setIconSize(d.iconSize(settings.value(icon_key).toString())); -#if defined(Q_WS_X11) || defined(QPA_XCB) - QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint(); - QSize size = settings.value("size", QSize(690, 510)).toSize(); - resize(size); - move(pos); -#else - // Work-around for bug #6034: the window ends up in an undetermined - // state when trying to restore a maximized window when it is - // already maximized. - if (!(windowState() & Qt::WindowMaximized)) - if (!restoreGeometry(settings.value("geometry").toByteArray())) - setGeometry(50, 50, 690, 510); -#endif + 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(); + resize(size); + move(pos); + } else { + // Work-around for bug #6034: the window ends up in an undetermined + // state when trying to restore a maximized window when it is + // already maximized. + if (!(windowState() & Qt::WindowMaximized)) + if (!restoreGeometry(settings.value("geometry").toByteArray())) + setGeometry(50, 50, 690, 510); + } + // Make sure layout is correctly oriented. setLayoutDirection(qApp->layoutDirection()); @@ -898,12 +1034,10 @@ bool GuiView::restoreLayout() initToolbars(); // init the toolbars that have not been restored - Toolbars::Infos::iterator cit = guiApp->toolbars().begin(); - Toolbars::Infos::iterator end = guiApp->toolbars().end(); - for (; cit != end; ++cit) { - GuiToolbar * tb = toolbar(cit->name); + for (auto const & tb_p : guiApp->toolbars()) { + GuiToolbar * tb = toolbar(tb_p.name); if (tb && !tb->isRestored()) - initToolbar(cit->name); + initToolbar(tb_p.name); } // update lock (all) toolbars positions @@ -921,7 +1055,7 @@ GuiToolbar * GuiView::toolbar(string const & name) return it->second; LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name); - return 0; + return nullptr; } @@ -933,14 +1067,18 @@ 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 } void GuiView::constructToolbars() { - ToolbarMap::iterator it = d.toolbars_.begin(); - for (; it != d.toolbars_.end(); ++it) - delete it->second; + for (auto const & tb_p : d.toolbars_) + delete tb_p.second; d.toolbars_.clear(); // I don't like doing this here, but the standard toolbar @@ -950,20 +1088,18 @@ void GuiView::constructToolbars() d.layout_->move(0,0); // extracts the toolbars from the backend - Toolbars::Infos::iterator cit = guiApp->toolbars().begin(); - Toolbars::Infos::iterator end = guiApp->toolbars().end(); - for (; cit != end; ++cit) - d.toolbars_[cit->name] = new GuiToolbar(*cit, *this); + for (ToolbarInfo const & inf : guiApp->toolbars()) + d.toolbars_[inf.name] = new GuiToolbar(inf, *this); + + DynamicMenuButton::resetIconCache(); } void GuiView::initToolbars() { // extracts the toolbars from the backend - Toolbars::Infos::iterator cit = guiApp->toolbars().begin(); - Toolbars::Infos::iterator end = guiApp->toolbars().end(); - for (; cit != end; ++cit) - initToolbar(cit->name); + for (ToolbarInfo const & inf : guiApp->toolbars()) + initToolbar(inf.name); } @@ -1079,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); @@ -1175,15 +1311,12 @@ void GuiView::dropEvent(QDropEvent * event) vector found_formats; // Find all formats that have the correct extension. - vector const & import_formats - = theConverters().importableFormats(); - vector::const_iterator it = import_formats.begin(); - for (; it != import_formats.end(); ++it) - if ((*it)->hasExtension(ext)) - found_formats.push_back(*it); + for (const Format * fmt : theConverters().importableFormats()) + if (fmt->hasExtension(ext)) + found_formats.push_back(fmt); FuncRequest cmd; - if (found_formats.size() >= 1) { + if (!found_formats.empty()) { if (found_formats.size() > 1) { //FIXME: show a dialog to choose the correct importable format LYXERR(Debug::FILES, @@ -1292,7 +1425,7 @@ void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa) { if (d.current_work_area_) // disconnect the current work area from all slots - QObject::disconnect(d.current_work_area_, 0, this, 0); + QObject::disconnect(d.current_work_area_, nullptr, this, nullptr); disconnectBuffer(); disconnectBufferView(); connectBufferView(wa->bufferView()); @@ -1316,6 +1449,10 @@ void GuiView::onBufferViewChanged() // Buffer-dependent dialogs must be updated. This is done here because // some dialogs require buffer()->text. updateDialogs(); + zoom_slider_->setEnabled(currentBufferView()); + zoom_value_->setEnabled(currentBufferView()); + zoom_in_->setEnabled(currentBufferView()); + zoom_out_->setEnabled(currentBufferView()); } @@ -1398,6 +1535,55 @@ bool GuiView::event(QEvent * e) //case QEvent::Drop: // break; + case QEvent::WindowStateChange: { + QWindowStateChangeEvent * ev = (QWindowStateChangeEvent*)e; + bool ofstate = (ev->oldState() & Qt::WindowFullScreen); + bool result = QMainWindow::event(e); + bool nfstate = (windowState() & Qt::WindowFullScreen); + if (!ofstate && nfstate) { + LYXERR(Debug::DEBUG, "GuiView: WindowStateChange(): full-screen " << nfstate); + // switch to full-screen state + if (lyxrc.full_screen_statusbar) + statusBar()->hide(); + if (lyxrc.full_screen_menubar) + menuBar()->hide(); + if (lyxrc.full_screen_toolbars) { + for (auto const & tb_p : d.toolbars_) + if (tb_p.second->isVisibilityOn() && tb_p.second->isVisible()) + tb_p.second->hide(); + } + for (int i = 0; i != d.splitter_->count(); ++i) + d.tabWorkArea(i)->setFullScreen(true); +#if QT_VERSION > 0x050903 + //Qt's 5.9.4 ba44cdae38406c safe area measures won't allow us to go negative in margins + setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false); +#endif + setContentsMargins(-2, -2, -2, -2); + // bug 5274 + hideDialogs("prefs", nullptr); + } else if (ofstate && !nfstate) { + LYXERR(Debug::DEBUG, "GuiView: WindowStateChange(): full-screen " << nfstate); + // switch back from full-screen state + if (lyxrc.full_screen_statusbar && !statusBar()->isVisible()) + statusBar()->show(); + if (lyxrc.full_screen_menubar && !menuBar()->isVisible()) + menuBar()->show(); + if (lyxrc.full_screen_toolbars) { + for (auto const & tb_p : d.toolbars_) + if (tb_p.second->isVisibilityOn() && !tb_p.second->isVisible()) + tb_p.second->show(); + //updateToolbars(); + } + for (int i = 0; i != d.splitter_->count(); ++i) + d.tabWorkArea(i)->setFullScreen(false); +#if QT_VERSION > 0x050903 + setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, true); +#endif + setContentsMargins(0, 0, 0, 0); + } + return result; + } + case QEvent::WindowActivate: { GuiView * old_view = guiApp->currentView(); if (this == old_view) { @@ -1434,6 +1620,27 @@ bool GuiView::event(QEvent * e) return QMainWindow::event(e); } + case QEvent::ApplicationPaletteChange: { + // runtime switch from/to dark mode + refillToolbars(); + 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); } @@ -1496,7 +1703,7 @@ GuiWorkArea * GuiView::workArea(int index) if (TabWorkArea * twa = d.currentTabWorkArea()) if (index < twa->count()) return twa->workArea(index); - return 0; + return nullptr; } @@ -1507,7 +1714,7 @@ GuiWorkArea * GuiView::workArea(Buffer & buffer) return currentWorkArea(); if (TabWorkArea * twa = d.currentTabWorkArea()) return twa->workArea(buffer); - return 0; + return nullptr; } @@ -1549,7 +1756,7 @@ GuiWorkArea * GuiView::currentWorkArea() GuiWorkArea const * GuiView::currentMainWorkArea() const { if (!d.currentTabWorkArea()) - return 0; + return nullptr; return d.currentTabWorkArea()->currentWorkArea(); } @@ -1557,7 +1764,7 @@ GuiWorkArea const * GuiView::currentMainWorkArea() const GuiWorkArea * GuiView::currentMainWorkArea() { if (!d.currentTabWorkArea()) - return 0; + return nullptr; return d.currentTabWorkArea()->currentWorkArea(); } @@ -1566,7 +1773,7 @@ void GuiView::setCurrentWorkArea(GuiWorkArea * wa) { LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl); if (!wa) { - d.current_work_area_ = 0; + d.current_work_area_ = nullptr; d.setBackground(); Q_EMIT bufferViewChanged(); return; @@ -1617,8 +1824,8 @@ void GuiView::removeWorkArea(GuiWorkArea * wa) if (wa == d.current_work_area_) { disconnectBuffer(); disconnectBufferView(); - d.current_work_area_ = 0; - d.current_main_work_area_ = 0; + d.current_work_area_ = nullptr; + d.current_main_work_area_ = nullptr; } bool found_twa = false; @@ -1628,7 +1835,7 @@ void GuiView::removeWorkArea(GuiWorkArea * wa) // Found in this tab group, and deleted the GuiWorkArea. found_twa = true; if (twa->count() != 0) { - if (d.current_work_area_ == 0) + if (d.current_work_area_ == nullptr) // This means that we are closing the current GuiWorkArea, so // switch to the next GuiWorkArea in the found TabWorkArea. setCurrentWorkArea(twa->currentWorkArea()); @@ -1644,13 +1851,13 @@ void GuiView::removeWorkArea(GuiWorkArea * wa) // should be deleted by other means. LASSERT(found_twa, return); - if (d.current_work_area_ == 0) { + if (d.current_work_area_ == nullptr) { if (d.splitter_->count() != 0) { TabWorkArea * twa = d.currentTabWorkArea(); setCurrentWorkArea(twa->currentWorkArea()); } else { // No more work areas, switch to the background widget. - setCurrentWorkArea(0); + setCurrentWorkArea(nullptr); } } } @@ -1671,7 +1878,6 @@ void GuiView::updateLayoutList() void GuiView::updateToolbars() { - ToolbarMap::iterator end = d.toolbars_.end(); if (d.current_work_area_) { int context = 0; if (d.current_work_area_->bufferView().cursor().inMathed() @@ -1696,11 +1902,19 @@ void GuiView::updateToolbars() minibuffer_focus_ = false; } - for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it) - it->second->update(context); + for (auto const & tb_p : d.toolbars_) + tb_p.second->update(context); } else - for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it) - it->second->update(); + for (auto const & tb_p : d.toolbars_) + tb_p.second->update(); +} + + +void GuiView::refillToolbars() +{ + DynamicMenuButton::resetIconCache(); + for (auto const & tb_p : d.toolbars_) + tb_p.second->refill(); } @@ -1710,7 +1924,7 @@ void GuiView::setBuffer(Buffer * newBuffer, bool switch_to) LASSERT(newBuffer, return); GuiWorkArea * wa = workArea(*newBuffer); - if (wa == 0) { + if (wa == nullptr) { setBusy(true); newBuffer->masterBuffer()->updateBuffer(); setBusy(false); @@ -1741,7 +1955,7 @@ void GuiView::connectBuffer(Buffer & buf) void GuiView::disconnectBuffer() { if (d.current_work_area_) - d.current_work_area_->bufferView().buffer().setGuiDelegate(0); + d.current_work_area_->bufferView().buffer().setGuiDelegate(nullptr); } @@ -1754,7 +1968,7 @@ void GuiView::connectBufferView(BufferView & bv) void GuiView::disconnectBufferView() { if (d.current_work_area_) - d.current_work_area_->bufferView().setGuiDelegate(0); + d.current_work_area_->bufferView().setGuiDelegate(nullptr); } @@ -1818,7 +2032,7 @@ BufferView * GuiView::documentBufferView() { return currentMainWorkArea() ? ¤tMainWorkArea()->bufferView() - : 0; + : nullptr; } @@ -1826,19 +2040,19 @@ BufferView const * GuiView::documentBufferView() const { return currentMainWorkArea() ? ¤tMainWorkArea()->bufferView() - : 0; + : nullptr; } BufferView * GuiView::currentBufferView() { - return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0; + return d.current_work_area_ ? &d.current_work_area_->bufferView() : nullptr; } BufferView const * GuiView::currentBufferView() const { - return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0; + return d.current_work_area_ ? &d.current_work_area_->bufferView() : nullptr; } @@ -1859,7 +2073,7 @@ void GuiView::autoSave() LYXERR(Debug::INFO, "Running autoSave()"); Buffer * buffer = documentBufferView() - ? &documentBufferView()->buffer() : 0; + ? &documentBufferView()->buffer() : nullptr; if (!buffer) { resetAutosaveTimers(); return; @@ -1884,9 +2098,9 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) { bool enable = true; Buffer * buf = currentBufferView() - ? ¤tBufferView()->buffer() : 0; + ? ¤tBufferView()->buffer() : nullptr; Buffer * doc_buffer = documentBufferView() - ? &(documentBufferView()->buffer()) : 0; + ? &(documentBufferView()->buffer()) : nullptr; #ifdef Q_OS_MAC /* In LyX/Mac, when a dialog is open, the menus of the @@ -1925,7 +2139,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_MASTER_BUFFER_EXPORT: enable = doc_buffer - && (doc_buffer->parent() != 0 + && (doc_buffer->parent() != nullptr || doc_buffer->hasChildren()) && !d.processing_thread_watcher_.isRunning() // this launches a dialog, which would be in the wrong Buffer @@ -1935,7 +2149,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_MASTER_BUFFER_UPDATE: case LFUN_MASTER_BUFFER_VIEW: enable = doc_buffer - && (doc_buffer->parent() != 0 + && (doc_buffer->parent() != nullptr || doc_buffer->hasChildren()) && !d.processing_thread_watcher_.isRunning(); break; @@ -1959,12 +2173,43 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) && (!doc_buffer->isClean() || doc_buffer->notifiesExternalModification()); break; + case LFUN_BUFFER_RESET_EXPORT: + enable = doc_buffer != nullptr; + break; + case LFUN_BUFFER_CHILD_OPEN: - enable = doc_buffer != 0; + enable = doc_buffer != nullptr; + break; + + case LFUN_MASTER_BUFFER_FORALL: { + if (doc_buffer == nullptr) { + flag.message(from_utf8(N_("Command not allowed without a buffer open"))); + enable = false; + break; + } + FuncRequest const cmdToPass = lyxaction.lookupFunc(cmd.getLongArg(0)); + if (cmdToPass.action() == LFUN_UNKNOWN_ACTION) { + flag.message(from_utf8(N_("Invalid argument of master-buffer-forall"))); + enable = false; + break; + } + enable = false; + for (Buffer * buf : doc_buffer->allRelatives()) { + GuiWorkArea * wa = workArea(*buf); + if (!wa) + continue; + if (wa->bufferView().getStatus(cmdToPass, flag)) { + enable = flag.enabled(); + break; + } + } break; + } case LFUN_BUFFER_WRITE: - enable = doc_buffer && (doc_buffer->isUnnamed() || !doc_buffer->isClean()); + enable = doc_buffer && (doc_buffer->isUnnamed() + || (!doc_buffer->isClean() + || cmd.argument() == "force")); break; //FIXME: This LFUN should be moved to GuiApplication. @@ -1996,7 +2241,6 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } return doc_buffer->getStatus(cmd, flag); - break; } case LFUN_BUFFER_EXPORT_AS: @@ -2007,7 +2251,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) // fall through case LFUN_BUFFER_WRITE_AS: case LFUN_BUFFER_WRITE_AS_TEMPLATE: - enable = doc_buffer != 0; + enable = doc_buffer != nullptr; break; case LFUN_EXPORT_CANCEL: @@ -2016,7 +2260,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_BUFFER_CLOSE: case LFUN_VIEW_CLOSE: - enable = doc_buffer != 0; + enable = doc_buffer != nullptr; break; case LFUN_BUFFER_CLOSE_ALL: @@ -2057,6 +2301,41 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) flag.setOnOff(devel_mode_); break; + case LFUN_TOOLBAR_SET: { + string const name = cmd.getArg(0); + string const state = cmd.getArg(1); + if (name.empty() || state.empty()) { + enable = false; + docstring const msg = + _("Function toolbar-set requires two arguments!"); + flag.message(msg); + break; + } + if (state != "on" && state != "off" && state != "auto") { + enable = false; + docstring const msg = + bformat(_("Invalid argument \"%1$s\" to function toolbar-set!"), + from_utf8(state)); + flag.message(msg); + break; + } + if (GuiToolbar * t = toolbar(name)) { + bool const autovis = t->visibility() & Toolbars::AUTO; + if (state == "on") + flag.setOnOff(t->isVisible() && !autovis); + else if (state == "off") + flag.setOnOff(!t->isVisible() && !autovis); + else if (state == "auto") + flag.setOnOff(autovis); + } else { + enable = false; + docstring const msg = + bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)); + flag.message(msg); + } + break; + } + case LFUN_TOOLBAR_TOGGLE: { string const name = cmd.getArg(0); if (GuiToolbar * t = toolbar(name)) @@ -2092,11 +2371,16 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; case LFUN_DROP_LAYOUTS_CHOICE: - enable = buf != 0; + enable = buf != nullptr; 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: @@ -2133,7 +2417,6 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = FileName(doc_buffer->logName()).isReadableFile(); else if (name == "spellchecker") enable = theSpellChecker() - && !doc_buffer->isReadonly() && !doc_buffer->text().empty(); else if (name == "vclog") enable = doc_buffer->lyxvc().inUse(); @@ -2214,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; @@ -2279,6 +2563,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_SERVER_GOTO_FILE_ROW: case LFUN_LYX_ACTIVATE: + case LFUN_WINDOW_RAISE: break; case LFUN_FORWARD_SEARCH: enable = !(lyxrc.forward_search_dvi.empty() && lyxrc.forward_search_pdf.empty()); @@ -2293,6 +2578,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) flag.setOnOff(lyxrc.spellcheck_continuously); break; + case LFUN_CITATION_OPEN: + enable = true; + break; + default: return false; } @@ -2325,18 +2614,18 @@ Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles) { setBusy(true); - Buffer * newBuffer = 0; + Buffer * newBuffer = nullptr; try { newBuffer = checkAndLoadLyXFile(filename); - } catch (ExceptionMessage const & e) { + } catch (ExceptionMessage const &) { setBusy(false); - throw(e); + throw; } setBusy(false); if (!newBuffer) { message(_("Document not loaded.")); - return 0; + return nullptr; } setBuffer(newBuffer); @@ -2369,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); @@ -2436,25 +2729,23 @@ static bool import(GuiView * lv, FileName const & filename, string loader_format; vector loaders = theConverters().loaders(); if (find(loaders.begin(), loaders.end(), format) == loaders.end()) { - vector::const_iterator it = loaders.begin(); - vector::const_iterator en = loaders.end(); - for (; it != en; ++it) { - if (!theConverters().isReachable(format, *it)) + for (string const & loader : loaders) { + if (!theConverters().isReachable(format, loader)) continue; string const tofile = support::changeExtension(filename.absFileName(), - theFormats().extension(*it)); - if (theConverters().convert(0, filename, FileName(tofile), - filename, format, *it, errorList) != Converters::SUCCESS) + theFormats().extension(loader)); + if (theConverters().convert(nullptr, filename, FileName(tofile), + filename, format, loader, errorList) != Converters::SUCCESS) return false; - loader_format = *it; + loader_format = loader; break; } if (loader_format.empty()) { frontend::Alert::error(_("Couldn't import file"), bformat(_("No information for importing the format %1$s."), - theFormats().prettyName(format))); + translateIfPossible(theFormats().prettyName(format)))); return false; } } else @@ -2501,13 +2792,13 @@ void GuiView::importDocument(string const & argument) } docstring const text = bformat(_("Select %1$s file to import"), - theFormats().prettyName(format)); + translateIfPossible(theFormats().prettyName(format))); FileDialog dlg(toqstr(text)); dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path)); dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path)); - docstring filter = theFormats().prettyName(format); + docstring filter = translateIfPossible(theFormats().prettyName(format)); filter += " (*.{"; // FIXME UNICODE filter += from_utf8(theFormats().extensions(format)); @@ -2619,11 +2910,11 @@ void GuiView::newDocument(string const & filename, string templatefile, } -void GuiView::insertLyXFile(docstring const & fname, bool ignorelang) +bool GuiView::insertLyXFile(docstring const & fname, bool ignorelang) { BufferView * bv = documentBufferView(); if (!bv) - return; + return false; // FIXME UNICODE FileName filename(to_utf8(fname)); @@ -2645,7 +2936,7 @@ void GuiView::insertLyXFile(docstring const & fname, bool ignorelang) QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) - return; + return false; // FIXME UNICODE filename.set(fromqstr(result.second)); @@ -2654,12 +2945,13 @@ void GuiView::insertLyXFile(docstring const & fname, bool ignorelang) if (filename.empty()) { // emit message signal. message(_("Canceled.")); - return; + return false; } } bv->insertLyXFile(filename, ignorelang); bv->buffer().errors("Parse"); + return true; } @@ -2929,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 " @@ -3036,7 +3328,9 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa) " Tools->Preferences->Look&Feel->UserInterface\n" ), file); int ret = Alert::prompt(_("Close or hide document?"), - text, 0, 1, _("&Close"), _("&Hide")); + text, 0, 2, _("&Close"), _("&Hide"), _("&Cancel")); + if (ret == 2) + return false; close_buffer = (ret == 0); } } @@ -3073,6 +3367,14 @@ void GuiView::writeSession() const { bool GuiView::closeBufferAll() { + + for (auto & buf : theBufferList()) { + if (!saveBufferIfNeeded(*buf, false)) { + // Closing has been cancelled, so abort. + return false; + } + } + // Close the workareas in all other views QList const ids = guiApp->viewIds(); for (int i = 0; i != ids.size(); ++i) { @@ -3084,9 +3386,6 @@ bool GuiView::closeBufferAll() if (!closeWorkAreaAll()) return false; - // Now close the hidden buffers. We prevent hidden buffers from being - // dirty, so we can just close them. - theBufferList().closeAll(); return true; } @@ -3146,13 +3445,9 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer) bool GuiView::closeBuffer(Buffer & buf) { bool success = true; - ListOfBuffers clist = buf.getChildren(); - ListOfBuffers::const_iterator it = clist.begin(); - ListOfBuffers::const_iterator const bend = clist.end(); - for (; it != bend; ++it) { - Buffer * child_buf = *it; + for (Buffer * child_buf : buf.getChildren()) { if (theBufferList().isOthersChild(&buf, child_buf)) { - child_buf->setParent(0); + child_buf->setParent(nullptr); continue; } @@ -3175,12 +3470,13 @@ bool GuiView::closeBuffer(Buffer & buf) // Even in this case, children can be dirty (e.g., // after a label change in the master, see #11405). // Therefore, check this - if (closing_ && (child_buf->isClean() || child_buf->paragraphs().empty())) + if (closing_ && (child_buf->isClean() || child_buf->paragraphs().empty())) { // If we are in a close_event all children will be closed in some time, // so no need to do it here. This will ensure that the children end up // in the session file in the correct order. If we close the master // buffer, we can close or release the child buffers here too. continue; + } // Save dirty buffers also if closing_! if (saveBufferIfNeeded(*child_buf, false)) { child_buf->removeAutosaveFile(); @@ -3196,9 +3492,10 @@ bool GuiView::closeBuffer(Buffer & buf) if (success) { // goto bookmark to update bookmark pit. // FIXME: we should update only the bookmarks related to this buffer! + // FIXME: this is done also in LFUN_WINDOW_CLOSE! LYXERR(Debug::DEBUG, "GuiView::closeBuffer()"); - for (size_t i = 0; i < theSession().bookmarks().size(); ++i) - guiApp->gotoBookmark(i+1, false, false); + for (unsigned int i = 1; i < theSession().bookmarks().size(); ++i) + guiApp->gotoBookmark(i, false, false); if (saveBufferIfNeeded(buf, false)) { buf.removeAutosaveFile(); @@ -3400,10 +3697,7 @@ bool GuiView::reloadBuffer(Buffer & buf) void GuiView::checkExternallyModifiedBuffers() { - BufferList::iterator bit = theBufferList().begin(); - BufferList::iterator const bend = theBufferList().end(); - for (; bit != bend; ++bit) { - Buffer * buf = *bit; + for (Buffer * buf : theBufferList()) { if (buf->fileName().exists() && buf->isChecksumModified()) { docstring text = bformat(_("Document \n%1$s\n has been externally modified." " Reload now? Any local changes will be lost."), @@ -3420,7 +3714,7 @@ void GuiView::checkExternallyModifiedBuffers() void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) { Buffer * buffer = documentBufferView() - ? &(documentBufferView()->buffer()) : 0; + ? &(documentBufferView()->buffer()) : nullptr; switch (cmd.action()) { case LFUN_VC_REGISTER: @@ -3490,8 +3784,7 @@ void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_VC_LOCKING_TOGGLE: - LASSERT(buffer, return); - if (!ensureBufferClean(buffer) || buffer->hasReadonlyFlag()) + if (!buffer || !ensureBufferClean(buffer) || buffer->hasReadonlyFlag()) break; if (buffer->lyxvc().inUse()) { string res = buffer->lyxvc().lockingToggle(); @@ -3506,7 +3799,8 @@ void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_VC_REVERT: - LASSERT(buffer, return); + if (!buffer) + break; if (buffer->lyxvc().revert()) { reloadBuffer(*buffer); dr.clearMessageUpdate(); @@ -3514,14 +3808,16 @@ void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_VC_UNDO_LAST: - LASSERT(buffer, return); + if (!buffer) + break; buffer->lyxvc().undoLast(); reloadBuffer(*buffer); dr.clearMessageUpdate(); break; case LFUN_VC_REPO_UPDATE: - LASSERT(buffer, return); + if (!buffer) + break; if (ensureBufferClean(buffer)) { dr.setMessage(buffer->lyxvc().repoUpdate()); checkExternallyModifiedBuffers(); @@ -3575,10 +3871,11 @@ void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "comparehistory")); break; } + if (!buffer) + break; string rev1 = cmd.getArg(0); string f1, f2; - LATTEST(buffer) // f1 if (!buffer->lyxvc().prepareFileRevision(rev1, f1)) @@ -3614,7 +3911,7 @@ void GuiView::openChildDocument(string const & fname) Buffer & buffer = documentBufferView()->buffer(); FileName const filename = support::makeAbsPath(fname, buffer.filePath()); documentBufferView()->saveBookmark(false); - Buffer * child = 0; + Buffer * child = nullptr; if (theBufferList().exists(filename)) { child = theBufferList().getBuffer(filename); setBuffer(child); @@ -3637,7 +3934,7 @@ bool GuiView::goToFileRow(string const & argument) int row = -1; size_t i = argument.find_last_of(' '); if (i != string::npos) { - file_name = os::internal_path(trim(argument.substr(0, i))); + file_name = os::internal_path(FileName(trim(argument.substr(0, i))).realPath()); istringstream is(argument.substr(i + 1)); is >> row; if (is.fail()) @@ -3647,21 +3944,15 @@ bool GuiView::goToFileRow(string const & argument) LYXERR0("Wrong argument: " << argument); return false; } - Buffer * buf = 0; - string const abstmp = package().temp_dir().absFileName(); + Buffer * buf = nullptr; string const realtmp = package().temp_dir().realPath(); // We have to use os::path_prefix_is() here, instead of // simply prefixIs(), because the file name comes from // an external application and may need case adjustment. - if (os::path_prefix_is(file_name, abstmp, os::CASE_ADJUSTED) - || os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) { - // Needed by inverse dvi search. If it is a file - // in tmpdir, call the apropriated function. - // If tmpdir is a symlink, we may have the real - // path passed back, so we correct for that. - if (!prefixIs(file_name, abstmp)) - file_name = subst(file_name, realtmp, abstmp); - buf = theBufferList().getBufferFromTmp(file_name); + if (os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) { + buf = theBufferList().getBufferFromTmp(file_name, true); + LYXERR(Debug::FILES, "goToFileRow: buffer lookup for " << file_name + << (buf ? " success" : " failed")); } else { // Must replace extension of the file to be .lyx // and get full path @@ -3750,14 +4041,13 @@ Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy( } -bool GuiView::GuiViewPrivate::asyncBufferProcessing( - string const & argument, +bool GuiView::GuiViewPrivate::asyncBufferProcessing(string const & argument, Buffer const * used_buffer, docstring const & msg, Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &), Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const, Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const, - bool allow_async) + bool allow_async, bool use_tmpdir) { if (!used_buffer) return false; @@ -3793,7 +4083,7 @@ bool GuiView::GuiViewPrivate::asyncBufferProcessing( } else { Buffer::ExportStatus status; if (syncFunc) { - status = (used_buffer->*syncFunc)(format, false); + status = (used_buffer->*syncFunc)(format, use_tmpdir); } else if (previewFunc) { status = (used_buffer->*previewFunc)(format); } else @@ -3872,12 +4162,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) dr.dispatched(true); Buffer * doc_buffer = documentBufferView() - ? &(documentBufferView()->buffer()) : 0; + ? &(documentBufferView()->buffer()) : nullptr; if (cmd.origin() == FuncRequest::TOC) { GuiToc * toc = static_cast(findOrBuild("toc", false)); - // FIXME: do we need to pass a DispatchResult object here? - toc->doDispatch(bv->cursor(), cmd); + toc->doDispatch(bv->cursor(), cmd, dr); return; } @@ -3931,7 +4220,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) _("Exporting ..."), &GuiViewPrivate::exportAndDestroy, &Buffer::doExport, - 0, cmd.allowAsync()); + nullptr, cmd.allowAsync()); // TODO Inform user about success break; } @@ -3951,7 +4240,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) _("Exporting ..."), &GuiViewPrivate::compileAndDestroy, &Buffer::doExport, - 0, cmd.allowAsync()); + nullptr, cmd.allowAsync(), true); break; } case LFUN_BUFFER_VIEW: { @@ -3959,25 +4248,25 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) doc_buffer, _("Previewing ..."), &GuiViewPrivate::previewAndDestroy, - 0, + nullptr, &Buffer::preview, cmd.allowAsync()); break; } case LFUN_MASTER_BUFFER_UPDATE: { d.asyncBufferProcessing(argument, - (doc_buffer ? doc_buffer->masterBuffer() : 0), + (doc_buffer ? doc_buffer->masterBuffer() : nullptr), docstring(), &GuiViewPrivate::compileAndDestroy, &Buffer::doExport, - 0, cmd.allowAsync()); + nullptr, cmd.allowAsync(), true); break; } case LFUN_MASTER_BUFFER_VIEW: { d.asyncBufferProcessing(argument, - (doc_buffer ? doc_buffer->masterBuffer() : 0), + (doc_buffer ? doc_buffer->masterBuffer() : nullptr), docstring(), &GuiViewPrivate::previewAndDestroy, - 0, &Buffer::preview, cmd.allowAsync()); + nullptr, &Buffer::preview, cmd.allowAsync()); break; } case LFUN_EXPORT_CANCEL: { @@ -4064,10 +4353,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_FILE_INSERT: { - if (cmd.getArg(1) == "ignorelang") - insertLyXFile(from_utf8(cmd.getArg(0)), true); - else - insertLyXFile(cmd.argument()); + bool const ignore_lang = cmd.getArg(1) == "ignorelang"; + if (insertLyXFile(from_utf8(cmd.getArg(0)), ignore_lang)) { + dr.forceBufferUpdate(); + dr.screenUpdate(Update::Force); + } break; } @@ -4136,6 +4426,12 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + case LFUN_BUFFER_RESET_EXPORT: + LASSERT(doc_buffer, break); + doc_buffer->requireFreshStart(true); + dr.setMessage(_("Buffer export reset.")); + break; + case LFUN_BUFFER_WRITE: LASSERT(doc_buffer, break); saveBuffer(*doc_buffer); @@ -4170,6 +4466,25 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + case LFUN_MASTER_BUFFER_FORALL: { + if (!doc_buffer) + break; + + FuncRequest funcToRun = lyxaction.lookupFunc(cmd.getLongArg(0)); + funcToRun.allowAsync(false); + + for (Buffer const * buf : doc_buffer->allRelatives()) { + // Switch to other buffer view and resend cmd + lyx::dispatch(FuncRequest( + LFUN_BUFFER_SWITCH, buf->absFileName())); + lyx::dispatch(funcToRun); + } + // switch back + lyx::dispatch(FuncRequest( + LFUN_BUFFER_SWITCH, doc_buffer->absFileName())); + break; + } + case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR: LASSERT(doc_buffer, break); doc_buffer->clearExternalModification(); @@ -4191,6 +4506,14 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) dr.setMessage(_("Developer mode is now disabled.")); break; + case LFUN_TOOLBAR_SET: { + string const name = cmd.getArg(0); + string const state = cmd.getArg(1); + if (GuiToolbar * t = toolbar(name)) + t->setState(state); + break; + } + case LFUN_TOOLBAR_TOGGLE: { string const name = cmd.getArg(0); if (GuiToolbar * t = toolbar(name)) @@ -4215,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; } @@ -4264,7 +4586,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_DIALOG_HIDE: { - guiApp->hideDialogs(to_utf8(cmd.argument()), 0); + guiApp->hideDialogs(to_utf8(cmd.argument()), nullptr); break; } @@ -4273,8 +4595,8 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) string sdata = trim(to_utf8(cmd.argument()).substr(name.size())); if (name == "latexlog") { - // gettatus checks that - LATTEST(doc_buffer); + // getStatus checks that + LASSERT(doc_buffer, break); Buffer::LogType type; string const logfile = doc_buffer->logName(&type); switch (type) { @@ -4289,7 +4611,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) showDialog("log", sdata); } else if (name == "vclog") { // getStatus checks that - LATTEST(doc_buffer); + LASSERT(doc_buffer, break); string const sdata2 = "vc " + Lexer::quoteString(doc_buffer->lyxvc().getLogFile()); showDialog("log", sdata2); @@ -4297,6 +4619,9 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) sdata = bv->cursor().getEncoding()->name(); if (!sdata.empty()) showDialog("symbols", sdata); + } else if (name == "findreplace") { + sdata = to_utf8(bv->cursor().selectionAsString(false)); + showDialog(name, sdata); // bug 5274 } else if (name == "prefs" && isFullScreen()) { lfunUiToggle("fullscreen"); @@ -4334,14 +4659,14 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) case LFUN_TAB_GROUP_CLOSE: if (TabWorkArea * twa = d.currentTabWorkArea()) { closeTabWorkArea(twa); - d.current_work_area_ = 0; + d.current_work_area_ = nullptr; twa = d.currentTabWorkArea(); // Switch to the next GuiWorkArea in the found TabWorkArea. if (twa) { // Make sure the work area is up to date. setCurrentWorkArea(twa->currentWorkArea()); } else { - setCurrentWorkArea(0); + setCurrentWorkArea(nullptr); } } break; @@ -4349,14 +4674,14 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) case LFUN_VIEW_CLOSE: if (TabWorkArea * twa = d.currentTabWorkArea()) { closeWorkArea(twa->currentWorkArea()); - d.current_work_area_ = 0; + d.current_work_area_ = nullptr; twa = d.currentTabWorkArea(); // Switch to the next GuiWorkArea in the found TabWorkArea. if (twa) { // Make sure the work area is up to date. setCurrentWorkArea(twa->currentWorkArea()); } else { - setCurrentWorkArea(0); + setCurrentWorkArea(nullptr); } } break; @@ -4411,17 +4736,17 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) } // Actual zoom value: default zoom + fractional extra value - int zoom = lyxrc.defaultZoom * zoom_ratio_; + int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); if (zoom < static_cast(zoom_min_)) zoom = zoom_min_; - lyxrc.currentZoom = zoom; + setCurrentZoom(zoom); dr.setMessage(bformat(_("Zoom level is now %1$d% (default value: %2$d%)"), lyxrc.currentZoom, lyxrc.defaultZoom)); guiApp->fontLoader().update(); - dr.screenUpdate(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::ForceAll | Update::FitCursor); break; } @@ -4448,10 +4773,16 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) activateWindow(); break; + case LFUN_WINDOW_RAISE: + raise(); + activateWindow(); + showNormal(); + break; + case LFUN_FORWARD_SEARCH: { // it seems safe to assume we have a document buffer, since // getStatus wants one. - LATTEST(doc_buffer); + LASSERT(doc_buffer, break); Buffer const * doc_master = doc_buffer->masterBuffer(); FileName const path(doc_master->temppath()); string const texname = doc_master->isChild(doc_buffer) @@ -4496,7 +4827,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) command = subst(command, "$$t", texname); command = subst(command, "$$o", outname); - PathChanger p(path); + volatile PathChanger p(path); Systemcall one; one.startscript(Systemcall::DontWait, command); break; @@ -4507,6 +4838,16 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) dr.screenUpdate(Update::Force); break; + case LFUN_CITATION_OPEN: { + string pdfv, psv; + if (theFormats().getFormat("pdf")) + pdfv = theFormats().getFormat("pdf")->viewer(); + if (theFormats().getFormat("ps")) + psv = theFormats().getFormat("ps")->viewer(); + frontend::showTarget(argument, pdfv, psv); + break; + } + default: // The LFUN must be for one of BufferView, Buffer or Cursor; // let's try that: @@ -4514,12 +4855,6 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } - // Part of automatic menu appearance feature. - if (isFullScreen()) { - if (menuBar()->isVisible() && lyxrc.full_screen_menubar) - menuBar()->hide(); - } - // Need to update bv because many LFUNs here might have destroyed it bv = currentBufferView(); @@ -4550,15 +4885,26 @@ 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") { - int l, t, r, b; - getContentsMargins(&l, &t, &r, &b); + } 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? d.current_work_area_->setFrameStyle(QFrame::NoFrame); if (l == 0) { +#if QT_VERSION > 0x050903 + setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false); +#endif setContentsMargins(-2, -2, -2, -2); } else { +#if QT_VERSION > 0x050903 + setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, true); +#endif setContentsMargins(0, 0, 0, 0); } } else @@ -4572,42 +4918,14 @@ bool GuiView::lfunUiToggle(string const & ui_component) void GuiView::toggleFullScreen() { - if (isFullScreen()) { - for (int i = 0; i != d.splitter_->count(); ++i) - d.tabWorkArea(i)->setFullScreen(false); - setContentsMargins(0, 0, 0, 0); - setWindowState(windowState() ^ Qt::WindowFullScreen); - restoreLayout(); - menuBar()->show(); - statusBar()->show(); - } else { - // bug 5274 - hideDialogs("prefs", 0); - for (int i = 0; i != d.splitter_->count(); ++i) - d.tabWorkArea(i)->setFullScreen(true); - setContentsMargins(-2, -2, -2, -2); - saveLayout(); - setWindowState(windowState() ^ Qt::WindowFullScreen); - if (lyxrc.full_screen_statusbar) - statusBar()->hide(); - if (lyxrc.full_screen_menubar) - menuBar()->hide(); - if (lyxrc.full_screen_toolbars) { - ToolbarMap::iterator end = d.toolbars_.end(); - for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it) - it->second->hide(); - } - } - - // give dialogs like the TOC a chance to adapt - updateDialogs(); + setWindowState(windowState() ^ Qt::WindowFullScreen); } Buffer const * GuiView::updateInset(Inset const * inset) { if (!inset) - return 0; + return nullptr; Buffer const * inset_buffer = &(inset->buffer()); @@ -4654,7 +4972,7 @@ namespace { char const * const dialognames[] = { "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", -"citation", "compare", "comparehistory", "document", "errorlist", "ert", +"citation", "compare", "comparehistory", "counter", "document", "errorlist", "ert", "external", "file", "findreplace", "findreplaceadv", "float", "graphics", "href", "include", "index", "index_print", "info", "listings", "label", "line", "log", "lyxfiles", "mathdelimiter", "mathmatrix", "mathspace", "nomenclature", @@ -4679,7 +4997,7 @@ private: bool isValidName(string const & name) { return find_if(dialognames, end_dialognames, - cmpCStr(name.c_str())) != end_dialognames; + cmpCStr(name.c_str())) != end_dialognames; } } // namespace @@ -4688,7 +5006,7 @@ bool isValidName(string const & name) void GuiView::resetDialogs() { // Make sure that no LFUN uses any GuiView. - guiApp->setCurrentView(0); + guiApp->setCurrentView(nullptr); saveLayout(); saveUISettings(); menuBar()->clear(); @@ -4702,10 +5020,23 @@ void GuiView::resetDialogs() } +void GuiView::flatGroupBoxes(const QObject * widget, bool flag) +{ + for (QObject * child: widget->children()) { + if (child->inherits("QGroupBox")) { + QGroupBox * box = (QGroupBox*) child; + box->setFlat(flag); + } else { + flatGroupBoxes(child, flag); + } + } +} + + Dialog * GuiView::findOrBuild(string const & name, bool hide_it) { if (!isValidName(name)) - return 0; + return nullptr; map::iterator it = d.dialogs_.find(name); @@ -4717,6 +5048,11 @@ Dialog * GuiView::findOrBuild(string const & name, bool hide_it) Dialog * dialog = build(name); d.dialogs_[name].reset(dialog); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + // Force a uniform style for group boxes + // On Mac non-flat works better, on Linux flat is standard + flatGroupBoxes(dialog->asQWidget(), guiApp->platformName() != "cocoa"); +#endif if (lyxrc.allow_geometry_session) dialog->restoreSession(); if (hide_it) @@ -4755,13 +5091,14 @@ void GuiView::doShowDialog(QString const & qname, QString const & qdata, // activateWindow is needed for floating dockviews dialog->asQWidget()->raise(); dialog->asQWidget()->activateWindow(); - dialog->asQWidget()->setFocus(); + if (dialog->wantInitialFocus()) + dialog->asQWidget()->setFocus(); } } } - catch (ExceptionMessage const & ex) { + catch (ExceptionMessage const &) { d.in_show_ = false; - throw ex; + throw; } d.in_show_ = false; } @@ -4793,7 +5130,7 @@ void GuiView::hideDialog(string const & name, Inset * inset) if (dialog->isVisibleView()) dialog->hideView(); if (currentBufferView()) - currentBufferView()->editInset(name, 0); + currentBufferView()->editInset(name, nullptr); } @@ -4802,30 +5139,24 @@ void GuiView::disconnectDialog(string const & name) if (!isValidName(name)) return; if (currentBufferView()) - currentBufferView()->editInset(name, 0); + currentBufferView()->editInset(name, nullptr); } void GuiView::hideAll() const { - map::const_iterator it = d.dialogs_.begin(); - map::const_iterator end = d.dialogs_.end(); - - for(; it != end; ++it) - it->second->hideView(); + for(auto const & dlg_p : d.dialogs_) + dlg_p.second->hideView(); } void GuiView::updateDialogs() { - map::const_iterator it = d.dialogs_.begin(); - map::const_iterator end = d.dialogs_.end(); - - for(; it != end; ++it) { - Dialog * dialog = it->second.get(); + for(auto const & dlg_p : d.dialogs_) { + Dialog * dialog = dlg_p.second.get(); if (dialog) { if (dialog->needBufferOpen() && !documentBufferView()) - hideDialog(fromqstr(dialog->name()), 0); + hideDialog(fromqstr(dialog->name()), nullptr); else if (dialog->isVisibleView()) dialog->checkStatus(); } @@ -4834,134 +5165,10 @@ void GuiView::updateDialogs() updateLayoutList(); } -Dialog * createDialog(GuiView & lv, string const & name); - -// will be replaced by a proper factory... -Dialog * createGuiAbout(GuiView & lv); -Dialog * createGuiBibtex(GuiView & lv); -Dialog * createGuiChanges(GuiView & lv); -Dialog * createGuiCharacter(GuiView & lv); -Dialog * createGuiCitation(GuiView & lv); -Dialog * createGuiCompare(GuiView & lv); -Dialog * createGuiCompareHistory(GuiView & lv); -Dialog * createGuiDelimiter(GuiView & lv); -Dialog * createGuiDocument(GuiView & lv); -Dialog * createGuiErrorList(GuiView & lv); -Dialog * createGuiExternal(GuiView & lv); -Dialog * createGuiGraphics(GuiView & lv); -Dialog * createGuiInclude(GuiView & lv); -Dialog * createGuiIndex(GuiView & lv); -Dialog * createGuiListings(GuiView & lv); -Dialog * createGuiLog(GuiView & lv); -Dialog * createGuiLyXFiles(GuiView & lv); -Dialog * createGuiMathMatrix(GuiView & lv); -Dialog * createGuiNote(GuiView & lv); -Dialog * createGuiParagraph(GuiView & lv); -Dialog * createGuiPhantom(GuiView & lv); -Dialog * createGuiPreferences(GuiView & lv); -Dialog * createGuiPrint(GuiView & lv); -Dialog * createGuiPrintindex(GuiView & lv); -Dialog * createGuiRef(GuiView & lv); -Dialog * createGuiSearch(GuiView & lv); -Dialog * createGuiSearchAdv(GuiView & lv); -Dialog * createGuiSendTo(GuiView & lv); -Dialog * createGuiShowFile(GuiView & lv); -Dialog * createGuiSpellchecker(GuiView & lv); -Dialog * createGuiSymbols(GuiView & lv); -Dialog * createGuiTabularCreate(GuiView & lv); -Dialog * createGuiTexInfo(GuiView & lv); -Dialog * createGuiToc(GuiView & lv); -Dialog * createGuiThesaurus(GuiView & lv); -Dialog * createGuiViewSource(GuiView & lv); -Dialog * createGuiWrap(GuiView & lv); -Dialog * createGuiProgressView(GuiView & lv); - - Dialog * GuiView::build(string const & name) { - LASSERT(isValidName(name), return 0); - - Dialog * dialog = createDialog(*this, name); - if (dialog) - return dialog; - - if (name == "aboutlyx") - return createGuiAbout(*this); - if (name == "bibtex") - return createGuiBibtex(*this); - if (name == "changes") - return createGuiChanges(*this); - if (name == "character") - return createGuiCharacter(*this); - if (name == "citation") - return createGuiCitation(*this); - if (name == "compare") - return createGuiCompare(*this); - if (name == "comparehistory") - return createGuiCompareHistory(*this); - if (name == "document") - return createGuiDocument(*this); - if (name == "errorlist") - return createGuiErrorList(*this); - if (name == "external") - return createGuiExternal(*this); - if (name == "file") - return createGuiShowFile(*this); - if (name == "findreplace") - return createGuiSearch(*this); - if (name == "findreplaceadv") - return createGuiSearchAdv(*this); - if (name == "graphics") - return createGuiGraphics(*this); - if (name == "include") - return createGuiInclude(*this); - if (name == "index") - return createGuiIndex(*this); - if (name == "index_print") - return createGuiPrintindex(*this); - if (name == "listings") - return createGuiListings(*this); - if (name == "log") - return createGuiLog(*this); - if (name == "lyxfiles") - return createGuiLyXFiles(*this); - if (name == "mathdelimiter") - return createGuiDelimiter(*this); - if (name == "mathmatrix") - return createGuiMathMatrix(*this); - if (name == "note") - return createGuiNote(*this); - if (name == "paragraph") - return createGuiParagraph(*this); - if (name == "phantom") - return createGuiPhantom(*this); - if (name == "prefs") - return createGuiPreferences(*this); - if (name == "ref") - return createGuiRef(*this); - if (name == "sendto") - return createGuiSendTo(*this); - if (name == "spellchecker") - return createGuiSpellchecker(*this); - if (name == "symbols") - return createGuiSymbols(*this); - if (name == "tabularcreate") - return createGuiTabularCreate(*this); - if (name == "texinfo") - return createGuiTexInfo(*this); - if (name == "thesaurus") - return createGuiThesaurus(*this); - if (name == "toc") - return createGuiToc(*this); - if (name == "view-source") - return createGuiViewSource(*this); - if (name == "wrap") - return createGuiWrap(*this); - if (name == "progress") - return createGuiProgressView(*this); - - return 0; + return createDialog(*this, name); } @@ -4972,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