]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt4/GuiView.cpp
move updateLables to buffer
[features.git] / src / frontends / qt4 / GuiView.cpp
index 06663b5d02cc6ceb1fa8e1ad63270064b16a1631..be58dc71c066165eefb330cb48ca741d3f2de46a 100644 (file)
@@ -3,10 +3,10 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
  * \author John Levon
  * \author Abdelrazak Younes
- * \author Peter Kümmel
+ * \author Peter Kümmel
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -57,6 +57,7 @@
 
 #include "support/lassert.h"
 #include "support/debug.h"
+#include "support/ExceptionMessage.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
@@ -141,6 +142,7 @@ private:
        QPixmap splash_;
 };
 
+
 /// Toolbar store providing access to individual toolbars by name.
 typedef std::map<std::string, GuiToolbar *> ToolbarMap;
 
@@ -152,13 +154,14 @@ typedef boost::shared_ptr<Dialog> DialogPtr;
 struct GuiView::GuiViewPrivate
 {
        GuiViewPrivate()
-               : current_work_area_(0), layout_(0), autosave_timeout_(5000),
+               : current_work_area_(0), current_main_work_area_(0),
+               layout_(0), autosave_timeout_(5000),
                in_show_(false)
        {
                // hardcode here the platform specific icon size
-               smallIconSize = 14;     // scaling problems
-               normalIconSize = 20;    // ok, default
-               bigIconSize = 26;               // better for some math icons
+               smallIconSize = 14;  // scaling problems
+               normalIconSize = 20; // ok, default
+               bigIconSize = 26;    // better for some math icons
 
                splitter_ = new QSplitter;
                bg_widget_ = new BackgroundWidget;
@@ -232,7 +235,7 @@ struct GuiView::GuiViewPrivate
 
                for (int i = 0; i != splitter_->count(); ++i) {
                        TabWorkArea * twa = tabWorkArea(i);
-                       if (current_work_area_ == twa->currentWorkArea())
+                       if (current_main_work_area_ == twa->currentWorkArea())
                                return twa;
                }
 
@@ -242,6 +245,7 @@ struct GuiView::GuiViewPrivate
 
 public:
        GuiWorkArea * current_work_area_;
+       GuiWorkArea * current_main_work_area_;
        QSplitter * splitter_;
        QStackedWidget * stack_widget_;
        BackgroundWidget * bg_widget_;
@@ -283,6 +287,7 @@ GuiView::GuiView(int id)
        : d(*new GuiViewPrivate), id_(id), closing_(false)
 {
        // GuiToolbars *must* be initialised before the menu bar.
+       normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge
        constructToolbars();
 
        // set ourself as the current view. This is needed for the menu bar
@@ -328,12 +333,13 @@ GuiView::GuiView(int id)
                        return;
        }
 
-       // No session handling, default to a sane size.
+       // no session handling, default to a sane size.
        setGeometry(50, 50, 690, 510);
        initToolbars();
-       // This enables to clear session data if any.
+
+       // clear session data if any.
        QSettings settings;
-       settings.clear();
+       settings.remove("views");
 }
 
 
@@ -346,40 +352,46 @@ GuiView::~GuiView()
 void GuiView::saveLayout() const
 {
        QSettings settings;
-       QString const key = "view-" + QString::number(id_);
+       settings.beginGroup("views");
+       settings.beginGroup(QString::number(id_));
 #ifdef Q_WS_X11
-       settings.setValue(key + "/pos", pos());
-       settings.setValue(key + "/size", size());
+       settings.setValue("pos", pos());
+       settings.setValue("size", size());
 #else
-       settings.setValue(key + "/geometry", saveGeometry());
+       settings.setValue("geometry", saveGeometry());
 #endif
-       settings.setValue(key + "/layout", saveState(0));
-       settings.setValue(key + "/icon_size", iconSize());
+       settings.setValue("layout", saveState(0));
+       settings.setValue("icon_size", iconSize());
 }
 
 
 bool GuiView::restoreLayout()
 {
        QSettings settings;
-       QString const key = "view-" + QString::number(id_);
-       QString const icon_key = key + "/icon_size";
+       settings.beginGroup("views");
+       settings.beginGroup(QString::number(id_));
+       QString const icon_key = "icon_size";
        if (!settings.contains(icon_key))
                return false;
 
        setIconSize(settings.value(icon_key).toSize());
 #ifdef Q_WS_X11
-       QPoint pos = settings.value(key + "/pos", QPoint(50, 50)).toPoint();
-       QSize size = settings.value(key + "/size", QSize(690, 510)).toSize();
+       QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
+       QSize size = settings.value("size", QSize(690, 510)).toSize();
        resize(size);
        move(pos);
 #else
-       if (!restoreGeometry(settings.value(key + "/geometry").toByteArray()))
+       if (!restoreGeometry(settings.value("geometry").toByteArray()))
                setGeometry(50, 50, 690, 510);
 #endif
+       // Make sure layout is correctly oriented.
+       setLayoutDirection(qApp->layoutDirection());
+
        // Allow the toc and view-source dock widget to be restored if needed.
        findOrBuild("toc", true);
        findOrBuild("view-source", true);
-       if (!restoreState(settings.value(key + "/layout").toByteArray(), 0))
+
+       if (!restoreState(settings.value("layout").toByteArray(), 0))
                initToolbars();
        updateDialogs();
        return true;
@@ -472,12 +484,13 @@ TocModels & GuiView::tocModels()
 
 void GuiView::setFocus()
 {
+       LYXERR(Debug::DEBUG, "GuiView::setFocus()" << this);
        // Make sure LyXFunc points to the correct view.
+       guiApp->setCurrentView(this);
        theLyXFunc().setLyXView(this);
+       QMainWindow::setFocus();
        if (d.current_work_area_)
                d.current_work_area_->setFocus();
-       else
-               QWidget::setFocus();
 }
 
 
@@ -501,15 +514,20 @@ void GuiView::showEvent(QShowEvent * e)
 }
 
 
+/** Destroy only all tabbed WorkAreas. Destruction of other WorkAreas
+ ** is responsibility of the container (e.g., dialog)
+ **/
 void GuiView::closeEvent(QCloseEvent * close_event)
 {
+       LYXERR(Debug::DEBUG, "GuiView::closeEvent()");
        closing_ = true;
 
        // it can happen that this event arrives without selecting the view,
        // e.g. when clicking the close button on a background window.
-       theLyXFunc().setLyXView(this);
-
-       while (Buffer * b = buffer()) {
+       setFocus();
+       setCurrentWorkArea(currentMainWorkArea());
+       while (GuiWorkArea * wa = currentMainWorkArea()) {
+               Buffer * b = &wa->bufferView().buffer();
                if (b->parent()) {
                        // This is a child document, just close the tab after saving
                        // but keep the file loaded.
@@ -518,7 +536,7 @@ void GuiView::closeEvent(QCloseEvent * close_event)
                                close_event->ignore();
                                return;
                        }
-                       removeWorkArea(d.current_work_area_);
+               removeWorkArea(wa);
                        continue;
                }
 
@@ -534,12 +552,13 @@ void GuiView::closeEvent(QCloseEvent * close_event)
 
                                // This buffer is also opened in another view, so
                                // close the associated work area...
-                               removeWorkArea(d.current_work_area_);
+                               removeWorkArea(wa);
                                // ... but don't close the buffer.
                                b = 0;
                                break;
                        }
                }
+               // closeBuffer() needs buffer workArea still alive and set as currrent one, and destroys it
                if (b && !closeBuffer(*b, true)) {
                        closing_ = false;
                        close_event->ignore();
@@ -588,7 +607,7 @@ void GuiView::dragEnterEvent(QDragEnterEvent * event)
 }
 
 
-void GuiView::dropEvent(QDropEvent* event)
+void GuiView::dropEvent(QDropEvent * event)
 {
        QList<QUrl> files = event->mimeData()->urls();
        if (files.isEmpty())
@@ -598,8 +617,13 @@ void GuiView::dropEvent(QDropEvent* event)
        for (int i = 0; i != files.size(); ++i) {
                string const file = os::internal_path(fromqstr(
                        files.at(i).toLocalFile()));
-               if (!file.empty())
-                       lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file));
+               if (!file.empty()) {
+                       // Asynchronously post the event. DropEvent usually come
+                       // from the BufferView. But reloading a file might close
+                       // the BufferView from within its own event handler.
+                       guiApp->dispatchDelayed(FuncRequest(LFUN_FILE_OPEN, file));
+                       event->accept();
+               }
        }
 }
 
@@ -689,6 +713,8 @@ void GuiView::on_lastWorkAreaRemoved()
        updateDialog("document", "");
        updateDialogs();
 
+       resetWindowTitleAndIconText();
+
        if (lyxrc.open_buffers_in_tabs)
                // Nothing more to do, the window should stay open.
                return;
@@ -761,8 +787,7 @@ bool GuiView::event(QEvent * e)
                        updateDialog("document", "");
                        updateDialogs();
                } else {
-                       setWindowTitle(qt_("LyX"));
-                       setWindowIconText(qt_("LyX"));
+                       resetWindowTitleAndIconText();
                }
                setFocus();
                return QMainWindow::event(e);
@@ -770,6 +795,8 @@ bool GuiView::event(QEvent * e)
 
        case QEvent::ShortcutOverride: {
 
+#ifndef Q_WS_X11
+               // FIXME bug 4888
                if (isFullScreen() && menuBar()->isHidden()) {
                        QKeyEvent * ke = static_cast<QKeyEvent*>(e);
                        // FIXME: we should also try to detect special LyX shortcut such as
@@ -780,6 +807,7 @@ bool GuiView::event(QEvent * e)
                                menuBar()->show();
                        return QMainWindow::event(e);
                }
+#endif
 
                if (d.current_work_area_)
                        // Nothing special to do.
@@ -807,6 +835,11 @@ bool GuiView::event(QEvent * e)
        }
 }
 
+void GuiView::resetWindowTitleAndIconText()
+{
+    setWindowTitle(qt_("LyX"));
+    setWindowIconText(qt_("LyX"));
+}
 
 bool GuiView::focusNextPrevChild(bool /*next*/)
 {
@@ -834,6 +867,9 @@ void GuiView::setBusy(bool busy)
 
 GuiWorkArea * GuiView::workArea(Buffer & buffer)
 {
+       if (currentWorkArea()
+           && &currentWorkArea()->bufferView().buffer() == &buffer)
+               return (GuiWorkArea *) currentWorkArea();
        if (TabWorkArea * twa = d.currentTabWorkArea())
                return twa->workArea(buffer);
        return 0;
@@ -869,51 +905,105 @@ GuiWorkArea const * GuiView::currentWorkArea() const
 }
 
 
+GuiWorkArea * GuiView::currentWorkArea()
+{
+       return d.current_work_area_;
+}
+
+
+GuiWorkArea const * GuiView::currentMainWorkArea() const
+{
+       if (d.currentTabWorkArea() == NULL)
+               return NULL;
+       return d.currentTabWorkArea()->currentWorkArea();
+}
+
+
+GuiWorkArea * GuiView::currentMainWorkArea()
+{
+       if (d.currentTabWorkArea() == NULL)
+               return NULL;
+       return d.currentTabWorkArea()->currentWorkArea();
+}
+
+
 void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
 {
-       LASSERT(wa, /**/);
+       LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl);
+       if (wa == NULL) {
+               d.current_work_area_ = NULL;
+               d.setBackground();
+               return;
+       }
+       GuiWorkArea * old_gwa = theGuiApp()->currentView()->currentWorkArea();
+       if (old_gwa == wa)
+               return;
+
+       theGuiApp()->setCurrentView(this);
        d.current_work_area_ = wa;
        for (int i = 0; i != d.splitter_->count(); ++i) {
-               if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
+               if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) {
+                       //if (d.current_main_work_area_)
+                       //      d.current_main_work_area_->setFrameStyle(QFrame::NoFrame);
+                       d.current_main_work_area_ = wa;
+                       //d.current_main_work_area_->setFrameStyle(QFrame::Box | QFrame::Plain);
+                       //d.current_main_work_area_->setLineWidth(2);
+                       LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
                        return;
+               }
        }
+       LYXERR(Debug::DEBUG, "This is not a tabbed wa");
+       on_currentWorkAreaChanged(wa);
+       BufferView & bv = wa->bufferView();
+       bv.cursor().fixIfBroken();
+       bv.updateMetrics();
+       wa->setUpdatesEnabled(true);
+       LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
 }
 
 
 void GuiView::removeWorkArea(GuiWorkArea * wa)
 {
-       LASSERT(wa, /**/);
+       LASSERT(wa, return);
        if (wa == d.current_work_area_) {
                disconnectBuffer();
                disconnectBufferView();
                d.current_work_area_ = 0;
+               d.current_main_work_area_ = 0;
        }
 
+       bool found_twa = false;
        for (int i = 0; i != d.splitter_->count(); ++i) {
                TabWorkArea * twa = d.tabWorkArea(i);
-               if (!twa->removeWorkArea(wa))
-                       // Not found in this tab group.
-                       continue;
-
-               // We found and removed the GuiWorkArea.
-               if (!twa->count()) {
-                       // No more WorkAreas in this tab group, so delete it.
-                       delete twa;
+               if (twa->removeWorkArea(wa)) {
+                       // Found in this tab group, and deleted the GuiWorkArea.
+                       found_twa = true;
+                       if (twa->count() != 0) {
+                               if (d.current_work_area_ == 0)
+                                       // This means that we are closing the current GuiWorkArea, so
+                                       // switch to the next GuiWorkArea in the found TabWorkArea.
+                                       setCurrentWorkArea(twa->currentWorkArea());
+                       } else {
+                               // No more WorkAreas in this tab group, so delete it.
+                               delete twa;
+                       }
                        break;
                }
+       }
 
-               if (d.current_work_area_)
-                       // This means that we are not closing the current GuiWorkArea;
-                       break;
+       // It is not a tabbed work area (i.e., the search work area), so it
+       // should be deleted by other means.
+       LASSERT(found_twa, /* */);
 
-               // Switch to the next GuiWorkArea in the found TabWorkArea.
-               d.current_work_area_ = twa->currentWorkArea();
-               break;
+       if (d.current_work_area_ == 0) {
+               if (d.splitter_->count() != 0) {
+                       TabWorkArea * twa = d.currentTabWorkArea();
+                       setCurrentWorkArea(twa->currentWorkArea());
+               } else {
+                       // No more work areas, switch to the background widget.
+                       setCurrentWorkArea(0);
+               }
        }
-
-       if (d.splitter_->count() == 0)
-               // No more work area, switch to the background widget.
-               d.setBackground();
 }
 
 
@@ -970,12 +1060,13 @@ Buffer const * GuiView::buffer() const
 
 void GuiView::setBuffer(Buffer * newBuffer)
 {
-       LASSERT(newBuffer, /**/);
+       LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << std::endl);
+       LASSERT(newBuffer, return);
        setBusy(true);
 
        GuiWorkArea * wa = workArea(*newBuffer);
        if (wa == 0) {
-               updateLabels(*newBuffer->masterBuffer());
+               newBuffer->masterBuffer()->updateLabels();
                wa = addWorkArea(*newBuffer);
        } else {
                //Disconnect the old buffer...there's no new one.
@@ -1023,6 +1114,12 @@ void GuiView::errors(string const & error_type)
 }
 
 
+void GuiView::updateTocItem(std::string const & type, DocIterator const & dit)
+{
+       d.toc_models_.updateItem(toqstr(type), dit);
+}
+
+
 void GuiView::structureChanged()
 {
        d.toc_models_.reset(view());
@@ -1095,7 +1192,12 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                break;
 
        case LFUN_SPLIT_VIEW:
-               enable = buf;
+               if (cmd.getArg(0) == "vertical")
+                       enable = buf && (d.splitter_->count() == 1 ||
+                                        d.splitter_->orientation() == Qt::Vertical);
+               else
+                       enable = buf && (d.splitter_->count() == 1 ||
+                                        d.splitter_->orientation() == Qt::Horizontal);
                break;
 
        case LFUN_CLOSE_TAB_GROUP:
@@ -1143,7 +1245,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                else if (name == "latexlog")
                        enable = FileName(buf->logName()).isReadableFile();
                else if (name == "spellchecker")
-#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
+#if defined (USE_ASPELL)
                        enable = !buf->isReadonly();
 #else
                        enable = false;
@@ -1168,7 +1270,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                        FuncStatus fs;
                        if (!inset->getStatus(view()->cursor(), fr, fs)) {
                                // Every inset is supposed to handle this
-                               LASSERT(false, /**/);
+                               LASSERT(false, break);
                        }
                        flag |= fs;
                } else {
@@ -1197,6 +1299,21 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                    enable = false;
                break;
 
+       case LFUN_COMPLETION_ACCEPT:
+               if (!d.current_work_area_
+                   || (!d.current_work_area_->completer().popupVisible()
+                       && !d.current_work_area_->completer().inlineVisible()
+                       && !d.current_work_area_->completer().completionAvailable()))
+                       enable = false;
+               break;
+
+               case LFUN_COMPLETION_CANCEL:
+               if (!d.current_work_area_
+                   || (!d.current_work_area_->completer().popupVisible()
+                       && !d.current_work_area_->completer().inlineVisible()))
+                       enable = false;
+               break;
+
        default:
                return false;
        }
@@ -1300,6 +1417,12 @@ void GuiView::openDocument(string const & fname)
        if (!fullname.empty())
                filename = fullname.absFilename();
 
+       if (!fullname.onlyPath().isDirectory()) {
+               Alert::warning(_("Invalid filename"),
+                               bformat(_("The directory in the given path\n%1$s\ndoes not exists."),
+                               from_utf8(fullname.absFilename())));
+               return;
+       }
        // if the file doesn't exist, let the user create one
        if (!fullname.exists()) {
                // the user specifically chose this name. Believe him.
@@ -1315,11 +1438,13 @@ void GuiView::openDocument(string const & fname)
        docstring str2;
        Buffer * buf = loadDocument(fullname);
        if (buf) {
-               updateLabels(*buf);
-               
+               buf->updateLabels();
                setBuffer(buf);
                buf->errors("Parse");
                str2 = bformat(_("Document %1$s opened."), disp_fn);
+               if (buf->lyxvc().inUse())
+                       str2 += " " + from_utf8(buf->lyxvc().versionString()) +
+                               " " + _("Version control detected.");
        } else {
                str2 = bformat(_("Could not open document %1$s"), disp_fn);
        }
@@ -1362,7 +1487,7 @@ static bool import(GuiView * lv, FileName const & filename,
                Buffer * buf = lv->loadDocument(lyxfile);
                if (!buf)
                        return false;
-               updateLabels(*buf);
+               buf->updateLabels();
                lv->setBuffer(buf);
                buf->errors("Parse");
        } else {
@@ -1438,7 +1563,7 @@ void GuiView::importDocument(string const & argument)
        FileName const lyxfile(support::changeExtension(fullname.absFilename(), ".lyx"));
 
        // Check if the document already is open
-       Buffer * buf = theBufferList().getBuffer(lyxfile.absFilename());
+       Buffer * buf = theBufferList().getBuffer(lyxfile);
        if (buf) {
                setBuffer(buf);
                if (!closeBuffer()) {
@@ -1662,6 +1787,9 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
 
 bool GuiView::saveBuffer(Buffer & b)
 {
+       if (workArea(b) && workArea(b)->inDialogMode())
+               return true;
+
        if (b.isUnnamed())
                return renameBuffer(b, docstring());
 
@@ -1706,13 +1834,18 @@ bool GuiView::closeBuffer(Buffer & buf, bool tolastopened)
 {
        // goto bookmark to update bookmark pit.
        //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);
 
        if (buf.isClean() || buf.paragraphs().empty()) {
                if (buf.masterBuffer() == &buf && tolastopened)
                        theSession().lastOpened().add(buf.fileName());
-               theBufferList().release(&buf);
+               if (buf.parent())
+                       // Don't close child documents.
+                       removeWorkArea(currentMainWorkArea());
+               else
+                       theBufferList().release(&buf);
                return true;
        }
        // Switch to this Buffer.
@@ -1757,7 +1890,7 @@ bool GuiView::closeBuffer(Buffer & buf, bool tolastopened)
 
        if (buf.parent())
                // Don't close child documents.
-               removeWorkArea(d.current_work_area_);
+               removeWorkArea(currentMainWorkArea());
        else
                theBufferList().release(&buf);
 
@@ -1779,7 +1912,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        break;
 
                case LFUN_BUFFER_SWITCH:
-                       setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
+                       setBuffer(theBufferList().getBuffer(FileName(to_utf8(cmd.argument()))));
                        break;
 
                case LFUN_BUFFER_NEXT:
@@ -1918,18 +2051,30 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                data = bv->cursor().getEncoding()->name();
                                if (!data.empty())
                                        showDialog("symbols", data);
+                       // bug 5274
+                       } else if (name == "prefs" && isFullScreen()) {
+                               FuncRequest fr(LFUN_INSET_INSERT, "fullscreen");
+                               lfunUiToggle(fr);
+                               showDialog("prefs", data);
                        } else
                                showDialog(name, data);
                        break;
                }
 
                case LFUN_INSET_APPLY: {
-                       view()->cursor().recordUndoFullDocument();
                        string const name = cmd.getArg(0);
                        Inset * inset = getOpenInset(name);
                        if (inset) {
+                               // put cursor in front of inset.
+                               if (!view()->setCursorFromInset(inset))
+                                       LASSERT(false, break);
+                               
+                               // useful if we are called from a dialog.
+                               view()->cursor().beginUndoGroup();
+                               view()->cursor().recordUndo();
                                FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
                                inset->dispatch(view()->cursor(), fr);
+                               view()->cursor().endUndoGroup();
                        } else {
                                FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
                                lyx::dispatch(fr);
@@ -1943,11 +2088,6 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        setFocus();
                        break;
 
-               case LFUN_COMPLETION_INLINE:
-                       if (d.current_work_area_)
-                               d.current_work_area_->completer().showInline();
-                       break;
-
                case LFUN_SPLIT_VIEW:
                        if (Buffer * buf = buffer()) {
                                string const orientation = cmd.getArg(0);
@@ -1965,18 +2105,19 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                twa = d.currentTabWorkArea();
                                // Switch to the next GuiWorkArea in the found TabWorkArea.
                                if (twa) {
-                                       d.current_work_area_ = twa->currentWorkArea();
                                        // Make sure the work area is up to date.
-                                       twa->setCurrentWorkArea(d.current_work_area_);
+                                       setCurrentWorkArea(twa->currentWorkArea());
                                } else {
-                                       d.current_work_area_ = 0;
+                                       setCurrentWorkArea(0);
                                }
-                               if (d.splitter_->count() == 0)
-                                       // No more work area, switch to the background widget.
-                                       d.setBackground();
                        }
                        break;
                        
+               case LFUN_COMPLETION_INLINE:
+                       if (d.current_work_area_)
+                               d.current_work_area_->completer().showInline();
+                       break;
+
                case LFUN_COMPLETION_POPUP:
                        if (d.current_work_area_)
                                d.current_work_area_->completer().showPopup();
@@ -1988,11 +2129,27 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                d.current_work_area_->completer().tab();
                        break;
 
+               case LFUN_COMPLETION_CANCEL:
+                       if (d.current_work_area_) {
+                               if (d.current_work_area_->completer().popupVisible())
+                                       d.current_work_area_->completer().hidePopup();
+                               else
+                                       d.current_work_area_->completer().hideInline();
+                       }
+                       break;
+
+               case LFUN_COMPLETION_ACCEPT:
+                       if (d.current_work_area_)
+                               d.current_work_area_->completer().activate();
+                       break;
+
+
                default:
                        dispatched = false;
                        break;
        }
 
+       // Part of automatic menu appearance feature.
        if (isFullScreen()) {
                if (menuBar()->isVisible())
                        menuBar()->hide();
@@ -2063,6 +2220,8 @@ void GuiView::toggleFullScreen()
                menuBar()->show();
                statusBar()->show();
        } else {
+               // bug 5274
+               hideDialogs("prefs", 0);
                for (int i = 0; i != d.splitter_->count(); ++i)
                        d.tabWorkArea(i)->setFullScreen(true);
 #if QT_VERSION >= 0x040300
@@ -2078,6 +2237,9 @@ void GuiView::toggleFullScreen()
                                it->second->hide();
                }
        }
+
+       // give dialogs like the TOC a chance to adapt
+       updateDialogs();
 }
 
 
@@ -2132,7 +2294,7 @@ char const * const dialognames[] = {
 "thesaurus",
 #endif
 
-"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
+"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings", "findreplaceadv" };
 
 char const * const * const end_dialognames =
        dialognames + (sizeof(dialognames) / sizeof(char *));
@@ -2164,7 +2326,7 @@ void GuiView::resetDialogs()
        saveLayout();
        menuBar()->clear();
        constructToolbars();
-       guiApp->menus().fillMenuBar(menuBar(), this, true);
+       guiApp->menus().fillMenuBar(menuBar(), this, false);
        if (d.layout_)
                d.layout_->updateContents(true);
        // Now update controls with current buffer.
@@ -2181,8 +2343,11 @@ Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
 
        map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
 
-       if (it != d.dialogs_.end())
+       if (it != d.dialogs_.end()) {
+               if (hide_it)
+                       it->second->hideView();
                return it->second.get();
+       }
 
        Dialog * dialog = build(name);
        d.dialogs_[name].reset(dialog);
@@ -2201,11 +2366,17 @@ void GuiView::showDialog(string const & name, string const & data,
                return;
 
        d.in_show_ = true;
-       Dialog * dialog = findOrBuild(name, false);
-       if (dialog) {
-               dialog->showData(data);
-               if (inset)
-                       d.open_insets_[name] = inset;
+       try {
+               Dialog * dialog = findOrBuild(name, false);
+               if (dialog) {
+                       dialog->showData(data);
+                       if (inset)
+                               d.open_insets_[name] = inset;
+               }
+       }
+       catch (ExceptionMessage const & ex) {
+               d.in_show_ = false;
+               throw ex;
        }
        d.in_show_ = false;
 }
@@ -2311,6 +2482,7 @@ Dialog * createGuiPreferences(GuiView & lv);
 Dialog * createGuiPrint(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);
@@ -2328,7 +2500,7 @@ Dialog * createGuiWrap(GuiView & lv);
 
 Dialog * GuiView::build(string const & name)
 {
-       LASSERT(isValidName(name), /**/);
+       LASSERT(isValidName(name), return 0);
 
        if (name == "aboutlyx")
                return createGuiAbout(*this);
@@ -2358,6 +2530,8 @@ Dialog * GuiView::build(string const & name)
                return createGuiShowFile(*this);
        if (name == "findreplace")
                return createGuiSearch(*this);
+       if (name == "findreplaceadv")
+               return createGuiSearchAdv(*this);
        if (name == "float")
                return createGuiFloat(*this);
        if (name == "graphics")
@@ -2424,4 +2598,4 @@ Dialog * GuiView::build(string const & name)
 } // namespace frontend
 } // namespace lyx
 
-#include "GuiView_moc.cpp"
+#include "moc_GuiView.cpp"