]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt4/GuiView.cpp
s/updateLabels/updateBuffer/g, per a suggestion of Abdel's.
[features.git] / src / frontends / qt4 / GuiView.cpp
index 8923da5abe8f19e62f597cf5376f0a62e3c4153f..a59284d2565a08dc8cb169613ee37e46dfa83d59 100644 (file)
 #include "GuiView.h"
 
 #include "Dialog.h"
+#include "DispatchResult.h"
 #include "FileDialog.h"
 #include "FontLoader.h"
 #include "GuiApplication.h"
 #include "GuiCommandBuffer.h"
 #include "GuiCompleter.h"
-#include "GuiWorkArea.h"
 #include "GuiKeySymbol.h"
 #include "GuiToc.h"
 #include "GuiToolbar.h"
+#include "GuiWorkArea.h"
 #include "LayoutBox.h"
 #include "Menus.h"
 #include "TocModel.h"
@@ -38,6 +39,7 @@
 #include "BufferList.h"
 #include "BufferParams.h"
 #include "BufferView.h"
+#include "Compare.h"
 #include "Converter.h"
 #include "Cursor.h"
 #include "CutAndPaste.h"
@@ -50,7 +52,6 @@
 #include "Layout.h"
 #include "Lexer.h"
 #include "LyXAction.h"
-#include "LyXFunc.h"
 #include "LyX.h"
 #include "LyXRC.h"
 #include "LyXVC.h"
 
 #define EXPORT_in_THREAD 1
 
-
 // QtConcurrent was introduced in Qt 4.4
 #if (QT_VERSION >= 0x040400)
 #include <QFuture>
@@ -154,6 +154,7 @@ public:
                font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
                pain.setFont(font);
                pain.drawText(260, 15, text);
+               setFocusPolicy(Qt::StrongFocus);
        }
 
        void paintEvent(QPaintEvent *)
@@ -164,6 +165,18 @@ public:
                pain.drawPixmap(x, y, splash_);
        }
 
+       void keyPressEvent(QKeyEvent * ev)
+       {
+               KeySymbol sym;
+               setKeySymbol(&sym, ev);
+               if (sym.isOK()) {
+                       guiApp->processKeySym(sym, q_key_state(ev->modifiers()));
+                       ev->accept();
+               } else {
+                       ev->ignore();
+               }
+       }
+
 private:
        QPixmap splash_;
 };
@@ -248,6 +261,7 @@ struct GuiView::GuiViewPrivate
        {
                stack_widget_->setCurrentWidget(bg_widget_);
                bg_widget_->setUpdatesEnabled(true);
+               bg_widget_->setFocus();
        }
 
        TabWorkArea * tabWorkArea(int i)
@@ -274,11 +288,12 @@ struct GuiView::GuiViewPrivate
 #if (QT_VERSION >= 0x040400)
        void setPreviewFuture(QFuture<docstring> const & f)
        {
-               if (preview_watcher_.isRunning())
-                       preview_watcher_.waitForFinished();
+               if (preview_watcher_.isRunning()) {
+                       // we prefer to cancel this preview in order to keep a snappy
+                       // interface.
+                       return;
+               }
                preview_watcher_.setFuture(f);
-               connect(&preview_watcher_, SIGNAL(finished()), gv_,
-                       SLOT(threadFinished()));
        }
 #endif
 
@@ -365,14 +380,23 @@ GuiView::GuiView(int id)
        setWindowIcon(getPixmap("images/", "lyx", "png"));
 #endif
 
+#if (QT_VERSION >= 0x040300)
+       // use tabbed dock area for multiple docks
+       // (such as "source" and "messages")
+       setDockOptions(QMainWindow::ForceTabbedDocks);
+#endif
+
        // For Drag&Drop.
        setAcceptDrops(true);
 
        statusBar()->setSizeGripEnabled(true);
+       updateStatusBar();
 
 #if (QT_VERSION >= 0x040400)
        connect(&d.autosave_watcher_, SIGNAL(finished()), this,
                SLOT(threadFinished()));
+       connect(&d.preview_watcher_, SIGNAL(finished()), this,
+               SLOT(threadFinished()));
 #endif
 
        connect(this, SIGNAL(triggerShowDialog(QString const &, QString const &, Inset *)),
@@ -465,6 +489,8 @@ bool GuiView::restoreLayout()
                dialog->prepareView();
        if ((dialog = findOrBuild("view-source", true)))
                dialog->prepareView();
+       if ((dialog = findOrBuild("progress", true)))
+               dialog->prepareView();
 
        if (!restoreState(settings.value("layout").toByteArray(), 0))
                initToolbars();
@@ -480,7 +506,6 @@ GuiToolbar * GuiView::toolbar(string const & name)
                return it->second;
 
        LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name);
-       message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
        return 0;
 }
 
@@ -516,7 +541,7 @@ void GuiView::initToolbars()
                if (!tb)
                        continue;
                int const visibility = guiApp->toolbars().defaultVisibility(cit->name);
-               bool newline = true;
+               bool newline = !(visibility & Toolbars::SAMEROW);
                tb->setVisible(false);
                tb->setVisibility(visibility);
 
@@ -529,7 +554,8 @@ void GuiView::initToolbars()
                if (visibility & Toolbars::BOTTOM) {
                        // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
 #if (QT_VERSION >= 0x040202)
-                       addToolBarBreak(Qt::BottomToolBarArea);
+                       if (newline)
+                               addToolBarBreak(Qt::BottomToolBarArea);
 #endif
                        addToolBar(Qt::BottomToolBarArea, tb);
                }
@@ -537,7 +563,8 @@ void GuiView::initToolbars()
                if (visibility & Toolbars::LEFT) {
                        // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
 #if (QT_VERSION >= 0x040202)
-                       addToolBarBreak(Qt::LeftToolBarArea);
+                       if (newline)
+                               addToolBarBreak(Qt::LeftToolBarArea);
 #endif
                        addToolBar(Qt::LeftToolBarArea, tb);
                }
@@ -545,7 +572,8 @@ void GuiView::initToolbars()
                if (visibility & Toolbars::RIGHT) {
                        // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
 #if (QT_VERSION >= 0x040202)
-                       addToolBarBreak(Qt::RightToolBarArea);
+                       if (newline)
+                               addToolBarBreak(Qt::RightToolBarArea);
 #endif
                        addToolBar(Qt::RightToolBarArea, tb);
                }
@@ -565,11 +593,22 @@ TocModels & GuiView::tocModels()
 void GuiView::setFocus()
 {
        LYXERR(Debug::DEBUG, "GuiView::setFocus()" << this);
-       // Make sure LyXFunc points to the correct view.
-       guiApp->setCurrentView(this);
        QMainWindow::setFocus();
-       if (d.current_work_area_)
-               d.current_work_area_->setFocus();
+}
+
+
+void GuiView::focusInEvent(QFocusEvent * e)
+{
+       LYXERR(Debug::DEBUG, "GuiView::focusInEvent()" << this);
+       QMainWindow::focusInEvent(e);
+       // Make sure guiApp points to the correct view.
+       guiApp->setCurrentView(this);
+       if (currentMainWorkArea())
+               currentMainWorkArea()->setFocus();
+       else if (currentWorkArea())
+               currentWorkArea()->setFocus();
+       else
+               d.bg_widget_->setFocus();
 }
 
 
@@ -694,7 +733,7 @@ void GuiView::dropEvent(QDropEvent * event)
                        cmd = FuncRequest(LFUN_FILE_OPEN, file);
                }
 
-               // Asynchronously post the event. DropEvent usually come
+               // Asynchronously post the event. DropEvent usually comes
                // from the BufferView. But reloading a file might close
                // the BufferView from within its own event handler.
                guiApp->dispatchDelayed(cmd);
@@ -741,8 +780,11 @@ void GuiView::bigSizedIcons()
 
 void GuiView::clearMessage()
 {
-       if (!hasFocus())
-               return;
+       // FIXME: This code was introduced in r19643 to fix bug #4123. However,
+       // the hasFocus function mostly returns false, even if the focus is on
+       // a workarea in this view.
+       //if (!hasFocus())
+       //      return;
        showMessage();
        d.statusbar_timer_.stop();
 }
@@ -750,7 +792,8 @@ void GuiView::clearMessage()
 
 void GuiView::updateWindowTitle(GuiWorkArea * wa)
 {
-       if (wa != d.current_work_area_)
+       if (wa != d.current_work_area_
+           || wa->bufferView().buffer().isInternal())
                return;
        setWindowTitle(qt_("LyX: ") + wa->windowTitle());
        setWindowIconText(wa->windowIconText());
@@ -795,6 +838,7 @@ void GuiView::on_lastWorkAreaRemoved()
        updateDialogs();
 
        resetWindowTitleAndIconText();
+       updateStatusBar();
 
        if (lyxrc.open_buffers_in_tabs)
                // Nothing more to do, the window should stay open.
@@ -902,25 +946,7 @@ bool GuiView::event(QEvent * e)
                        }
                }
 #endif
-
-               if (d.current_work_area_)
-                       // Nothing special to do.
-                       return QMainWindow::event(e);
-
-               QKeyEvent * ke = static_cast<QKeyEvent*>(e);
-               // Let Qt handle menu access and the Tab keys to navigate keys to navigate
-               // between controls.
-               if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab 
-                       || ke->key() == Qt::Key_Backtab)
-                       return QMainWindow::event(e);
-
-               // Allow processing of shortcuts that are allowed even when no Buffer
-               // is viewed.
-               KeySymbol sym;
-               setKeySymbol(&sym, ke);
-               guiApp->processKeySym(sym, q_key_state(ke->modifiers()));
-               e->accept();
-               return true;
+               return QMainWindow::event(e);
        }
 
        default:
@@ -1006,16 +1032,16 @@ GuiWorkArea * GuiView::currentWorkArea()
 
 GuiWorkArea const * GuiView::currentMainWorkArea() const
 {
-       if (d.currentTabWorkArea() == NULL)
-               return NULL;
+       if (!d.currentTabWorkArea())
+               return 0;
        return d.currentTabWorkArea()->currentWorkArea();
 }
 
 
 GuiWorkArea * GuiView::currentMainWorkArea()
 {
-       if (d.currentTabWorkArea() == NULL)
-               return NULL;
+       if (!d.currentTabWorkArea())
+               return 0;
        return d.currentTabWorkArea()->currentWorkArea();
 }
 
@@ -1023,13 +1049,17 @@ GuiWorkArea * GuiView::currentMainWorkArea()
 void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
 {
        LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl);
-       if (wa == NULL) {
-               d.current_work_area_ = NULL;
+       if (!wa) {
+               d.current_work_area_ = 0;
                d.setBackground();
                return;
        }
-       GuiWorkArea * old_gwa = theGuiApp()->currentView()->currentWorkArea();
-       if (old_gwa == wa)
+
+       // FIXME: I've no clue why this is here and why it accesses
+       //  theGuiApp()->currentView, which might be 0 (bug 6464).
+       //  See also 27525 (vfr).
+       if (theGuiApp()->currentView() == this 
+                 && theGuiApp()->currentView()->currentWorkArea() == wa) 
                return;
 
        if (currentBufferView())
@@ -1146,7 +1176,7 @@ void GuiView::setBuffer(Buffer * newBuffer)
 
        GuiWorkArea * wa = workArea(*newBuffer);
        if (wa == 0) {
-               newBuffer->masterBuffer()->updateLabels();
+               newBuffer->masterBuffer()->updateBuffer();
                wa = addWorkArea(*newBuffer);
        } else {
                //Disconnect the old buffer...there's no new one.
@@ -1257,6 +1287,7 @@ BufferView const * GuiView::currentBufferView() const
 }
 
 
+#if (QT_VERSION >= 0x040400)
 static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname)
 {
        bool failed = true;
@@ -1274,6 +1305,7 @@ static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname)
                ? _("Automatic save failed!")
                : _("Automatic save done.");
 }
+#endif
 
 
 void GuiView::autoSave()
@@ -1411,10 +1443,18 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                enable = d.currentTabWorkArea();
                break;
 
-       case LFUN_TOOLBAR_TOGGLE:
-               if (GuiToolbar * t = toolbar(cmd.getArg(0)))
+       case LFUN_TOOLBAR_TOGGLE: {
+               string const name = cmd.getArg(0);
+               if (GuiToolbar * t = toolbar(name))
                        flag.setOnOff(t->isVisible());
+               else {
+                       enable = false;
+                       docstring const msg = 
+                               bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name));
+                       flag.message(msg);
+               }
                break;
+       }
 
        case LFUN_DROP_LAYOUTS_CHOICE:
                enable = buf; 
@@ -1547,7 +1587,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
        case LFUN_VC_LOCKING_TOGGLE:
                enable = doc_buffer && !doc_buffer->isReadonly()
                        && doc_buffer->lyxvc().lockingToggleEnabled();
-               flag.setOnOff(enable && !doc_buffer->lyxvc().locker().empty());
+               flag.setOnOff(enable && doc_buffer->lyxvc().locking());
                break;
        case LFUN_VC_REVERT:
                enable = doc_buffer && doc_buffer->lyxvc().inUse();
@@ -1565,6 +1605,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                        enable = false;
                break;
        }
+       case LFUN_VC_COMPARE:
+               enable = doc_buffer && !cmd.argument().empty()
+                        && doc_buffer->lyxvc().prepareFileRevisionEnabled();
+               break;
 
        case LFUN_SERVER_GOTO_FILE_ROW:
                break;
@@ -1694,7 +1738,7 @@ void GuiView::openDocument(string const & fname)
        docstring str2;
        Buffer * buf = loadDocument(fullname);
        if (buf) {
-               buf->updateLabels();
+               buf->updateBuffer();
                setBuffer(buf);
                buf->errors("Parse");
                str2 = bformat(_("Document %1$s opened."), disp_fn);
@@ -1743,7 +1787,7 @@ static bool import(GuiView * lv, FileName const & filename,
                Buffer * buf = lv->loadDocument(lyxfile);
                if (!buf)
                        return false;
-               buf->updateLabels();
+               buf->updateBuffer();
                lv->setBuffer(buf);
                buf->errors("Parse");
        } else {
@@ -2114,6 +2158,7 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa)
 bool GuiView::closeBuffer()
 {
        GuiWorkArea * wa = currentMainWorkArea();
+       setCurrentWorkArea(wa);
        Buffer & buf = wa->bufferView().buffer();
        return wa && closeWorkArea(wa, !buf.parent());
 }
@@ -2224,7 +2269,7 @@ bool GuiView::closeBuffer(Buffer & buf)
        //FIXME: we should update only the bookmarks related to this buffer!
        LYXERR(Debug::DEBUG, "GuiView::closeBuffer()");
        for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
-               theLyXFunc().gotoBookmark(i+1, false, false);
+               guiApp->gotoBookmark(i+1, false, false);
 
        if (saveBufferIfNeeded(buf, false)) {
                theBufferList().release(&buf);
@@ -2302,7 +2347,7 @@ bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding)
                buf.removeAutosaveFile();
                if (hiding)
                        // revert all changes
-                       buf.loadLyXFile(buf.fileName());
+                       buf.reload();
                buf.markClean();
                break;
        case 2:
@@ -2399,34 +2444,7 @@ static bool ensureBufferClean(Buffer * buffer)
 void GuiView::reloadBuffer()
 {
        Buffer * buf = &documentBufferView()->buffer();
-       reloadBuffer(buf);
-}
-
-
-void GuiView::reloadBuffer(Buffer * buf)
-{
-       FileName filename = buf->fileName();
-       Buffer const * master = buf->masterBuffer();
-       bool const is_child = master != buf;
-       // The user has already confirmed that the changes, if any, should
-       // be discarded. So we just release the Buffer and don't call closeBuffer();
-       theBufferList().release(buf);
-       buf = loadDocument(filename);
-       docstring const disp_fn = makeDisplayPath(filename.absFilename());
-       docstring str;
-       if (buf) {
-               // re-allocate master if necessary
-               if (is_child && theBufferList().isLoaded(master)
-                   && buf->masterBuffer() != master)
-                       buf->setParent(master);
-               buf->updateLabels();
-               setBuffer(buf);
-               buf->errors("Parse");
-               str = bformat(_("Document %1$s reloaded."), disp_fn);
-       } else {
-               str = bformat(_("Could not reload document %1$s"), disp_fn);
-       }
-       message(str);
+       buf->reload();
 }
 
 
@@ -2443,12 +2461,13 @@ void GuiView::checkExternallyModifiedBuffers()
                        int const ret = Alert::prompt(_("Reload externally changed document?"),
                                                text, 0, 1, _("&Reload"), _("&Cancel"));
                        if (!ret)
-                               reloadBuffer(*bit);
+                               (*bit)->reload();
                }
        }
 }
 
 
+//FIXME use a DispatchResult object to transmit messages
 void GuiView::dispatchVC(FuncRequest const & cmd)
 {
        // message for statusbar
@@ -2471,7 +2490,8 @@ void GuiView::dispatchVC(FuncRequest const & cmd)
                        break;
                if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
                        msg = buffer->lyxvc().checkIn();
-                       reloadBuffer();
+                       if (!msg.empty())
+                               reloadBuffer();
                }
                break;
 
@@ -2561,6 +2581,43 @@ void GuiView::dispatchVC(FuncRequest const & cmd)
 
                break;
                }
+
+       case LFUN_VC_COMPARE: {
+
+               string rev1 = cmd.getArg(0);
+               string f1, f2;
+
+               // f1
+               if (!buffer->lyxvc().prepareFileRevision(rev1, f1))
+                       break;
+
+               if (isStrInt(rev1) && convert<int>(rev1) <= 0) {
+                       f2 = buffer->absFileName();
+               } else {
+                       string rev2 = cmd.getArg(1);
+                       if (rev2.empty())
+                               break;
+                       // f2
+                       if (!buffer->lyxvc().prepareFileRevision(rev2, f2))
+                               break;
+               }
+               // FIXME We need to call comparison feature here.
+               // This is quick and dirty code for testing VC.
+               // We need that comparison feature has some LFUN_COMPARE <FLAG> file1 file1
+               // where <FLAG> specifies whether we want GUI dialog or just launch
+               // running with defaults.
+               /*
+               FileName initpath(lyxrc.document_path);
+               Buffer * dest = newUnnamedFile(initpath, to_utf8(_("differences")));
+               CompareOptions options;
+               Compare * compare = new Compare(loadIfNeeded(FileName(f1)), loadIfNeeded(FileName(f2)), dest, options);
+               compare->start(QThread::LowPriority);
+               Sleep::millisec(200);
+               lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, dest->absFileName()));
+               */
+               break;
+       }
+
        default:
                break;
        }
@@ -2593,7 +2650,7 @@ void GuiView::openChildDocument(string const & fname)
        // This makes insertion of citations and references in the child work,
        // when the target is in the parent or another child document.
        child->setParent(&buffer);
-       child->masterBuffer()->updateLabels();
+       child->masterBuffer()->updateBuffer();
        setBuffer(child);
        if (parsed)
                child->errors("Parse");
@@ -2641,7 +2698,7 @@ bool GuiView::goToFileRow(string const & argument)
                        buf = theBufferList().getBuffer(s);
                else if (s.exists()) {
                        buf = loadDocument(s);
-                       buf->updateLabels();
+                       buf->updateBuffer();
                        buf->errors("Parse");
                } else {
                        message(bformat(
@@ -2656,9 +2713,13 @@ bool GuiView::goToFileRow(string const & argument)
 }
 
 
+#if (QT_VERSION >= 0x040400)
 static docstring exportAndDestroy(Buffer * buffer, string const & format)
 {
-       bool const success = buffer->doExport(format, true);
+       bool const update_unincluded =
+                               buffer->params().maintain_unincluded_children
+                               && !buffer->params().getIncludedChildren().empty();
+       bool const success = buffer->doExport(format, true, update_unincluded);
        delete buffer;
        return success
                ? bformat(_("Successful export to format: %1$s"), from_utf8(format))
@@ -2668,30 +2729,34 @@ static docstring exportAndDestroy(Buffer * buffer, string const & format)
 
 static docstring previewAndDestroy(Buffer * buffer, string const & format)
 {
-       bool const success = buffer->preview(format);
+       bool const update_unincluded =
+                               buffer->params().maintain_unincluded_children
+                               && !buffer->params().getIncludedChildren().empty();
+       bool const success = buffer->preview(format, update_unincluded);
        delete buffer;
        return success
                ? bformat(_("Successful preview of format: %1$s"), from_utf8(format))
                : bformat(_("Error previewing format: %1$s"), from_utf8(format));
 }
+#endif
 
 
-bool GuiView::dispatch(FuncRequest const & cmd)
+void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 {
        BufferView * bv = currentBufferView();
        // By default we won't need any update.
-       if (bv)
-               bv->cursor().updateFlags(Update::None);
+       dr.update(Update::None);
+       // assume cmd will be dispatched
+       dr.dispatched(true);
 
        Buffer * doc_buffer = documentBufferView()
                ? &(documentBufferView()->buffer()) : 0;
 
-       bool dispatched = true;
-
        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);
-               return true;
+               return;
        }
 
        string const argument = to_utf8(cmd.argument());
@@ -2708,12 +2773,15 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                case LFUN_BUFFER_EXPORT: {
                        if (!doc_buffer)
                                break;
-                       if (cmd.argument() == "custom") {
-                               lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"));
+                       // GCC only sees strfwd.h when building merged
+                       if (::lyx::operator==(cmd.argument(), "custom")) {
+                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"), 
+                                        dr);
                                break;
                        }
-                       if (doc_buffer->doExport(argument, false)) {
-                               message(bformat(_("Error exporting to format: %1$s."),
+                       if (!doc_buffer->doExport(argument, false)) {
+                               dr.setError(true);
+                               dr.setMessage(bformat(_("Error exporting to format: %1$s."),
                                        cmd.argument()));
                        }
                        break;
@@ -2726,13 +2794,16 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        if (argument.empty())
                                format = doc_buffer->getDefaultOutputFormat();
 #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
-                       ProgressInterface::instance()->clearMessages();
-                       ProgressInterface::instance()->appendMessage("Exporting ...");
+                       d.progress_->clearMessages();
+                       message(_("Exporting ..."));
                        QFuture<docstring> f = QtConcurrent::run(exportAndDestroy,
                                doc_buffer->clone(), format);
                        d.setPreviewFuture(f);
 #else
-                       doc_buffer->doExport(format, true);
+                       bool const update_unincluded =
+                               doc_buffer->params().maintain_unincluded_children
+                               && !doc_buffer->params().getIncludedChildren().empty();
+                       doc_buffer->doExport(format, true, update_unincluded);
 #endif
                        break;
                }
@@ -2743,13 +2814,16 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        if (argument.empty())
                                format = doc_buffer->getDefaultOutputFormat();
 #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
-                       ProgressInterface::instance()->clearMessages();
-                       ProgressInterface::instance()->appendMessage("Previewing ...");
+                       d.progress_->clearMessages();
+                       message(_("Previewing ..."));
                        QFuture<docstring> f = QtConcurrent::run(previewAndDestroy,
                                doc_buffer->clone(), format);
                        d.setPreviewFuture(f);
 #else
-                       doc_buffer->preview(format);
+                       bool const update_unincluded =
+                               doc_buffer->params().maintain_unincluded_children
+                               && !doc_buffer->params().getIncludedChildren().empty();
+                       doc_buffer->preview(format, update_unincluded);
 #endif
                        break;
                }
@@ -2765,6 +2839,9 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                master->clone(), format);
                        d.setPreviewFuture(f);
 #else
+                       bool const update_unincluded =
+                               master->params().maintain_unincluded_children
+                               && !master->params().getIncludedChildren().empty();
                        master->doExport(format, true);
 #endif
                        break;
@@ -2789,8 +2866,10 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                        theBufferList().getBuffer(FileName(to_utf8(cmd.argument())));
                                if (buffer)
                                        setBuffer(buffer);
-                               else
-                                       message(_("Document not loaded"));
+                               else {
+                                       dr.setError(true);
+                                       dr.setMessage(_("Document not loaded"));
+                               }
                        }
                        break;
 
@@ -2872,7 +2951,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                }
                                b = theBufferList().next(b);
                        } while (b != first); 
-                       message(_("All documents saved."));
+                       dr.setMessage(_("All documents saved."));
                        break;
                }
 
@@ -2901,6 +2980,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                // FIXME: get rid of this indirection; GuiView ask the inset
                                // if he is kind enough to update itself...
                                FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
+                               //FIXME: pass DispatchResult here?
                                inset->dispatch(currentBufferView()->cursor(), fr);
                        } else if (name == "paragraph") {
                                lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
@@ -2912,9 +2992,9 @@ bool GuiView::dispatch(FuncRequest const & cmd)
 
                case LFUN_DIALOG_TOGGLE: {
                        if (isDialogVisible(cmd.getArg(0)))
-                               dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
+                               dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()), dr);
                        else
-                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
+                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()), dr);
                        break;
                }
 
@@ -2958,8 +3038,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                        showDialog("symbols", data);
                        // bug 5274
                        } else if (name == "prefs" && isFullScreen()) {
-                               FuncRequest fr(LFUN_INSET_INSERT, "fullscreen");
-                               lfunUiToggle(fr);
+                               lfunUiToggle("fullscreen");
                                showDialog("prefs", data);
                        } else
                                showDialog(name, data);
@@ -2967,14 +3046,19 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                }
 
                case LFUN_MESSAGE:
-                       message(cmd.argument());
+                       dr.setMessage(cmd.argument());
                        break;
 
-               case LFUN_UI_TOGGLE:
-                       lfunUiToggle(cmd);
+               case LFUN_UI_TOGGLE: {
+                       string arg = cmd.getArg(0);
+                       if (!lfunUiToggle(arg)) {
+                               docstring const msg = "ui-toggle " + _("%1$s unknown command!");
+                               dr.setMessage(bformat(msg, from_utf8(arg)));
+                       }
                        // Make sure the keyboard focus stays in the work area.
                        setFocus();
                        break;
+               }
 
                case LFUN_SPLIT_VIEW: {
                        LASSERT(doc_buffer, break);
@@ -3059,6 +3143,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                case LFUN_VC_REVERT:
                case LFUN_VC_UNDO_LAST:
                case LFUN_VC_COMMAND:
+               case LFUN_VC_COMPARE:
                        dispatchVC(cmd);
                        break;
 
@@ -3067,7 +3152,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        break;
 
                default:
-                       dispatched = false;
+                       dr.dispatched(false);
                        break;
        }
 
@@ -3079,14 +3164,13 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        statusBar()->hide();
        }
 
-       return dispatched;
+       return;
 }
 
 
-void GuiView::lfunUiToggle(FuncRequest const & cmd)
+bool GuiView::lfunUiToggle(string const & ui_component)
 {
-       string const arg = cmd.getArg(0);
-       if (arg == "scrollbar") {
+       if (ui_component == "scrollbar") {
                // hide() is of no help
                if (d.current_work_area_->verticalScrollBarPolicy() ==
                        Qt::ScrollBarAlwaysOff)
@@ -3096,18 +3180,13 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd)
                else
                        d.current_work_area_->setVerticalScrollBarPolicy(
                                Qt::ScrollBarAlwaysOff);
-               return;
-       }
-       if (arg == "statusbar") {
+       } else if (ui_component == "statusbar") {
                statusBar()->setVisible(!statusBar()->isVisible());
-               return;
-       }
-       if (arg == "menubar") {
+       } else if (ui_component == "menubar") {
                menuBar()->setVisible(!menuBar()->isVisible());
-               return;
-       }
+       } else
 #if QT_VERSION >= 0x040300
-       if (arg == "frame") {
+       if (ui_component == "frame") {
                int l, t, r, b;
                getContentsMargins(&l, &t, &r, &b);
                //are the frames in default state?
@@ -3117,15 +3196,13 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd)
                } else {
                        setContentsMargins(0, 0, 0, 0);
                }
-               return;
-       }
+       } else
 #endif
-       if (arg == "fullscreen") {
+       if (ui_component == "fullscreen") {
                toggleFullScreen();
-               return;
-       }
-
-       message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg)));
+       } else
+               return false;
+       return true;
 }
 
 
@@ -3241,7 +3318,7 @@ bool isValidName(string const & name)
 
 void GuiView::resetDialogs()
 {
-       // Make sure that no LFUN uses any LyXView.
+       // Make sure that no LFUN uses any GuiView.
        guiApp->setCurrentView(0);
        saveLayout();
        menuBar()->clear();
@@ -3364,20 +3441,22 @@ void GuiView::updateDialogs()
 
        for(; it != end; ++it) {
                Dialog * dialog = it->second.get();
-               if (dialog && dialog->isVisibleView())
-                       dialog->checkStatus();
+               if (dialog) {
+                       if (dialog->isBufferDependent() && !documentBufferView())
+                               hideDialog(fromqstr(dialog->name()), 0);
+                       else if (dialog->isVisibleView())
+                               dialog->checkStatus();
+               }
        }
        updateToolbars();
        updateLayoutList();
 }
 
+Dialog * createDialog(GuiView & lv, string const & name);
 
 // will be replaced by a proper factory...
 Dialog * createGuiAbout(GuiView & lv);
-Dialog * createGuiBibitem(GuiView & lv);
 Dialog * createGuiBibtex(GuiView & lv);
-Dialog * createGuiBox(GuiView & lv);
-Dialog * createGuiBranch(GuiView & lv);
 Dialog * createGuiChanges(GuiView & lv);
 Dialog * createGuiCharacter(GuiView & lv);
 Dialog * createGuiCitation(GuiView & lv);
@@ -3385,17 +3464,13 @@ Dialog * createGuiCompare(GuiView & lv);
 Dialog * createGuiDelimiter(GuiView & lv);
 Dialog * createGuiDocument(GuiView & lv);
 Dialog * createGuiErrorList(GuiView & lv);
-Dialog * createGuiERT(GuiView & lv);
 Dialog * createGuiExternal(GuiView & lv);
-Dialog * createGuiFloat(GuiView & lv);
 Dialog * createGuiGraphics(GuiView & lv);
 Dialog * createGuiInclude(GuiView & lv);
 Dialog * createGuiIndex(GuiView & lv);
-Dialog * createGuiInfo(GuiView & lv);
 Dialog * createGuiLabel(GuiView & lv);
 Dialog * createGuiListings(GuiView & lv);
 Dialog * createGuiLog(GuiView & lv);
-Dialog * createGuiMathHSpace(GuiView & lv);
 Dialog * createGuiMathMatrix(GuiView & lv);
 Dialog * createGuiNomenclature(GuiView & lv);
 Dialog * createGuiNote(GuiView & lv);
@@ -3413,13 +3488,10 @@ Dialog * createGuiShowFile(GuiView & lv);
 Dialog * createGuiSpellchecker(GuiView & lv);
 Dialog * createGuiSymbols(GuiView & lv);
 Dialog * createGuiTabularCreate(GuiView & lv);
-Dialog * createGuiTabular(GuiView & lv);
 Dialog * createGuiTexInfo(GuiView & lv);
-Dialog * createGuiTextHSpace(GuiView & lv);
 Dialog * createGuiToc(GuiView & lv);
 Dialog * createGuiThesaurus(GuiView & lv);
 Dialog * createGuiHyperlink(GuiView & lv);
-Dialog * createGuiVSpace(GuiView & lv);
 Dialog * createGuiViewSource(GuiView & lv);
 Dialog * createGuiWrap(GuiView & lv);
 Dialog * createGuiProgressView(GuiView & lv);
@@ -3430,16 +3502,14 @@ 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 == "bibitem")
-               return createGuiBibitem(*this);
        if (name == "bibtex")
                return createGuiBibtex(*this);
-       if (name == "box")
-               return createGuiBox(*this);
-       if (name == "branch")
-               return createGuiBranch(*this);
        if (name == "changes")
                return createGuiChanges(*this);
        if (name == "character")
@@ -3452,8 +3522,6 @@ Dialog * GuiView::build(string const & name)
                return createGuiDocument(*this);
        if (name == "errorlist")
                return createGuiErrorList(*this);
-       if (name == "ert")
-               return createGuiERT(*this);
        if (name == "external")
                return createGuiExternal(*this);
        if (name == "file")
@@ -3462,8 +3530,6 @@ Dialog * GuiView::build(string const & name)
                return createGuiSearch(*this);
        if (name == "findreplaceadv")
                return createGuiSearchAdv(*this);
-       if (name == "float")
-               return createGuiFloat(*this);
        if (name == "graphics")
                return createGuiGraphics(*this);
        if (name == "href")
@@ -3474,8 +3540,6 @@ Dialog * GuiView::build(string const & name)
                return createGuiIndex(*this);
        if (name == "index_print")
                return createGuiPrintindex(*this);
-       if (name == "info")
-               return createGuiInfo(*this);
        if (name == "label")
                return createGuiLabel(*this);
        if (name == "listings")
@@ -3484,8 +3548,6 @@ Dialog * GuiView::build(string const & name)
                return createGuiLog(*this);
        if (name == "mathdelimiter")
                return createGuiDelimiter(*this);
-       if (name == "mathspace")
-               return createGuiMathHSpace(*this);
        if (name == "mathmatrix")
                return createGuiMathMatrix(*this);
        if (name == "nomenclature")
@@ -3506,14 +3568,10 @@ Dialog * GuiView::build(string const & name)
                return createGuiRef(*this);
        if (name == "sendto")
                return createGuiSendTo(*this);
-       if (name == "space")
-               return createGuiTextHSpace(*this);
        if (name == "spellchecker")
                return createGuiSpellchecker(*this);
        if (name == "symbols")
                return createGuiSymbols(*this);
-       if (name == "tabular")
-               return createGuiTabular(*this);
        if (name == "tabularcreate")
                return createGuiTabularCreate(*this);
        if (name == "texinfo")
@@ -3524,8 +3582,6 @@ Dialog * GuiView::build(string const & name)
                return createGuiToc(*this);
        if (name == "view-source")
                return createGuiViewSource(*this);
-       if (name == "vspace")
-               return createGuiVSpace(*this);
        if (name == "wrap")
                return createGuiWrap(*this);
        if (name == "progress")