]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt/GuiView.cpp
Fix use of BookmarkSection::size()
[features.git] / src / frontends / qt / GuiView.cpp
index 581967fc4d6a2f2279727e0e61855bc687f1e97d..714af17b6883c863761ad459d0c43dd200f77f1c 100644 (file)
 
 #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"
 #include <QAction>
 #include <QApplication>
 #include <QCloseEvent>
-#include <QDebug>
-#include <QDesktopWidget>
 #include <QDragEnterEvent>
 #include <QDropEvent>
 #include <QFuture>
 #include <QFutureWatcher>
+#include <QGroupBox>
 #include <QLabel>
 #include <QList>
 #include <QMenu>
 #include <QPainter>
 #include <QPixmap>
 #include <QPoint>
-#include <QPushButton>
-#include <QScrollBar>
 #include <QSettings>
 #include <QShowEvent>
 #include <QSplitter>
 #include <QStatusBar>
 #include <QSvgRenderer>
 #include <QtConcurrentRun>
-#include <QTime>
 #include <QTimer>
-#include <QToolBar>
 #include <QUrl>
-
+#include <QWindowStateChangeEvent>
 
 
 // sync with GuiAlert.cpp
@@ -209,16 +201,16 @@ 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();
+               int hline = fm.maxHeight();
                QStringList::const_iterator sit;
-               for (sit = titlesegs.constBegin(); sit != titlesegs.constEnd(); ++sit) {
-                       if (fm.width(*sit) > wline)
-                               wline = fm.width(*sit);
+               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 +227,7 @@ public:
                setFocusPolicy(Qt::StrongFocus);
        }
 
-       void paintEvent(QPaintEvent *)
+       void paintEvent(QPaintEvent *) override
        {
                int const w = width_;
                int const h = height_;
@@ -249,7 +241,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 +308,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 +472,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<class T>
+       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<GuiWorkArea*> guiWorkAreas();
+
 public:
        GuiView * gv_;
        GuiWorkArea * current_work_area_;
@@ -504,17 +519,10 @@ public:
        ///
        map<string, DialogPtr> 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 +535,15 @@ public:
        string processing_format;
 
        static QSet<Buffer const *> 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<class T>
-       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<GuiWorkArea*> guiWorkAreas();
+       /// flag against a race condition due to multiclicks, see bug #1119
+       bool in_show_;
 };
 
 QSet<Buffer const *> GuiView::GuiViewPrivate::busyBuffers;
@@ -742,7 +737,7 @@ QVector<GuiWorkArea*> 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,12 +817,11 @@ 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())));
 }
@@ -838,13 +832,11 @@ 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<string, DialogPtr>::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);
 }
 
 
@@ -853,7 +845,7 @@ 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<int>(zoom_min_))
                zoom = zoom_min_;
        lyxrc.currentZoom = zoom;
@@ -867,19 +859,20 @@ 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
+       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 +891,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 +912,7 @@ GuiToolbar * GuiView::toolbar(string const & name)
                return it->second;
 
        LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name);
-       return 0;
+       return nullptr;
 }
 
 
@@ -938,9 +929,8 @@ void GuiView::updateLockToolbars()
 
 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 +940,16 @@ 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);
 }
 
 
 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);
 }
 
 
@@ -1175,15 +1161,12 @@ void GuiView::dropEvent(QDropEvent * event)
                vector<const Format *> found_formats;
 
                // Find all formats that have the correct extension.
-               vector<const Format *> const & import_formats
-                       = theConverters().importableFormats();
-               vector<const Format *>::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 +1275,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());
@@ -1398,6 +1381,54 @@ 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->isVisibiltyOn() && 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->isVisibiltyOn() && !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) {
@@ -1496,7 +1527,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 +1538,7 @@ GuiWorkArea * GuiView::workArea(Buffer & buffer)
                return currentWorkArea();
        if (TabWorkArea * twa = d.currentTabWorkArea())
                return twa->workArea(buffer);
-       return 0;
+       return nullptr;
 }
 
 
@@ -1549,7 +1580,7 @@ GuiWorkArea * GuiView::currentWorkArea()
 GuiWorkArea const * GuiView::currentMainWorkArea() const
 {
        if (!d.currentTabWorkArea())
-               return 0;
+               return nullptr;
        return d.currentTabWorkArea()->currentWorkArea();
 }
 
@@ -1557,7 +1588,7 @@ GuiWorkArea const * GuiView::currentMainWorkArea() const
 GuiWorkArea * GuiView::currentMainWorkArea()
 {
        if (!d.currentTabWorkArea())
-               return 0;
+               return nullptr;
        return d.currentTabWorkArea()->currentWorkArea();
 }
 
@@ -1566,7 +1597,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 +1648,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 +1659,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 +1675,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 +1702,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 +1726,11 @@ 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();
 }
 
 
@@ -1710,7 +1740,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 +1771,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 +1784,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 +1848,7 @@ BufferView * GuiView::documentBufferView()
 {
        return currentMainWorkArea()
                ? &currentMainWorkArea()->bufferView()
-               : 0;
+               : nullptr;
 }
 
 
@@ -1826,19 +1856,19 @@ BufferView const * GuiView::documentBufferView() const
 {
        return currentMainWorkArea()
                ? &currentMainWorkArea()->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 +1889,7 @@ void GuiView::autoSave()
        LYXERR(Debug::INFO, "Running autoSave()");
 
        Buffer * buffer = documentBufferView()
-               ? &documentBufferView()->buffer() : 0;
+               ? &documentBufferView()->buffer() : nullptr;
        if (!buffer) {
                resetAutosaveTimers();
                return;
@@ -1884,9 +1914,9 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 {
        bool enable = true;
        Buffer * buf = currentBufferView()
-               ? &currentBufferView()->buffer() : 0;
+               ? &currentBufferView()->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 +1955,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 +1965,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 +1989,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 +2057,6 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                        break;
                }
                return doc_buffer->getStatus(cmd, flag);
-               break;
        }
 
        case LFUN_BUFFER_EXPORT_AS:
@@ -2007,7 +2067,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 +2076,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 +2117,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,7 +2187,7 @@ 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:
@@ -2133,7 +2228,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();
@@ -2279,6 +2373,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 +2388,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 +2424,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);
@@ -2436,25 +2535,23 @@ static bool import(GuiView * lv, FileName const & filename,
        string loader_format;
        vector<string> loaders = theConverters().loaders();
        if (find(loaders.begin(), loaders.end(), format) == loaders.end()) {
-               vector<string>::const_iterator it = loaders.begin();
-               vector<string>::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 +2598,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));
@@ -3036,7 +3133,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 +3172,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<int> const ids = guiApp->viewIds();
        for (int i = 0; i != ids.size(); ++i) {
@@ -3084,9 +3191,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 +3250,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 +3275,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 +3297,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 +3502,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 +3519,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 +3589,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 +3604,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 +3613,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 +3676,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 +3716,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 +3739,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 +3749,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 +3846,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 +3888,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 +3967,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<GuiToc*>(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 +4025,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 +4045,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 +4053,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: {
@@ -4136,6 +4230,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 +4270,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 +4310,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))
@@ -4264,7 +4391,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 +4400,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 +4416,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);
@@ -4334,14 +4461,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 +4476,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,7 +4538,7 @@ 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<int>(zoom_min_))
                                zoom = zoom_min_;
 
@@ -4448,10 +4575,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)
@@ -4507,6 +4640,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:
@@ -4552,13 +4695,19 @@ bool GuiView::lfunUiToggle(string const & ui_component)
                menuBar()->setVisible(!menuBar()->isVisible());
        } else
        if (ui_component == "frame") {
-               int l, t, r, b;
-               getContentsMargins(&l, &t, &r, &b);
+               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 +4721,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 +4775,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 +4800,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 +4809,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 +4823,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<string, DialogPtr>::iterator it = d.dialogs_.find(name);
 
@@ -4717,6 +4851,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)
@@ -4759,9 +4898,9 @@ void GuiView::doShowDialog(QString const & qname, QString const & qdata,
                        }
                }
        }
-       catch (ExceptionMessage const & ex) {
+       catch (ExceptionMessage const &) {
                d.in_show_ = false;
-               throw ex;
+               throw;
        }
        d.in_show_ = false;
 }
@@ -4793,7 +4932,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 +4941,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<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       map<string, DialogPtr>::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<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       map<string, DialogPtr>::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 +4967,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);
 }