]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiView.cpp
Fix a crash when closing LyX while a master and a dirty child were open, and if the...
[lyx.git] / src / frontends / qt4 / GuiView.cpp
index e21be78af7ed620a0409f29e31188c57823e73d9..df9986b29e7fab6bc735549aab8417e6a54110bb 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.
  */
 
 #include "Dialog.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 "LayoutBox.h"
 #include "Menus.h"
 #include "TocModel.h"
 
@@ -37,6 +40,7 @@
 #include "BufferView.h"
 #include "Converter.h"
 #include "Cursor.h"
+#include "CutAndPaste.h"
 #include "Encoding.h"
 #include "ErrorList.h"
 #include "Format.h"
 #include "LyXRC.h"
 #include "LyXVC.h"
 #include "Paragraph.h"
+#include "SpellChecker.h"
 #include "TextClass.h"
 #include "Text.h"
 #include "Toolbars.h"
 #include "version.h"
 
-#include "support/lassert.h"
+#include "support/convert.h"
 #include "support/debug.h"
 #include "support/ExceptionMessage.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/ForkedCalls.h"
+#include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/os.h"
 #include "support/Package.h"
@@ -79,6 +85,7 @@
 #include <QMenuBar>
 #include <QPainter>
 #include <QPixmap>
+#include <QPixmapCache>
 #include <QPoint>
 #include <QPushButton>
 #include <QSettings>
@@ -117,7 +124,7 @@ public:
                /// The text to be written on top of the pixmap
                QString const text = lyx_version ?
                        qt_("version ") + lyx_version : qt_("unknown version");
-               splash_ = QPixmap(":/images/banner.png");
+               splash_ = getPixmap("images/", "banner", "png");
 
                QPainter pain(&splash_);
                pain.setPen(QColor(0, 0, 0));
@@ -127,7 +134,7 @@ public:
                font.setWeight(QFont::Bold);
                font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
                pain.setFont(font);
-               pain.drawText(190, 225, text);
+               pain.drawText(260, 15, text);
        }
 
        void paintEvent(QPaintEvent *)
@@ -142,6 +149,7 @@ private:
        QPixmap splash_;
 };
 
+
 /// Toolbar store providing access to individual toolbars by name.
 typedef std::map<std::string, GuiToolbar *> ToolbarMap;
 
@@ -153,13 +161,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;
@@ -233,7 +242,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;
                }
 
@@ -243,6 +252,7 @@ struct GuiView::GuiViewPrivate
 
 public:
        GuiWorkArea * current_work_area_;
+       GuiWorkArea * current_main_work_area_;
        QSplitter * splitter_;
        QStackedWidget * stack_widget_;
        BackgroundWidget * bg_widget_;
@@ -257,7 +267,7 @@ public:
         * FIXME: replace that with a proper model so that we are not limited
         * to only one dialog.
         */
-       GuiLayoutBox * layout_;
+       LayoutBox * layout_;
 
        ///
        map<string, Inset *> open_insets_;
@@ -284,6 +294,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
@@ -311,7 +322,7 @@ GuiView::GuiView(int id)
 #if (!defined(Q_WS_WIN) && !defined(Q_WS_MACX))
        // assign an icon to main form. We do not do it under Qt/Win or Qt/Mac,
        // since the icon is provided in the application bundle.
-       setWindowIcon(QPixmap(":/images/lyx.png"));
+       setWindowIcon(getPixmap("images/", "lyx", "png"));
 #endif
 
        // For Drag&Drop.
@@ -329,10 +340,11 @@ 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.remove("views");
 }
@@ -369,6 +381,7 @@ bool GuiView::restoreLayout()
        if (!settings.contains(icon_key))
                return false;
 
+       //code below is skipped when when ~/.config/LyX is (re)created
        setIconSize(settings.value(icon_key).toSize());
 #ifdef Q_WS_X11
        QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
@@ -376,15 +389,24 @@ bool GuiView::restoreLayout()
        resize(size);
        move(pos);
 #else
-       if (!restoreGeometry(settings.value("geometry").toByteArray()))
-               setGeometry(50, 50, 690, 510);
+       // 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
        // 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);
+       Dialog * dialog;
+       if ((dialog = findOrBuild("toc", true)))
+               // see bug 5082. At least setup title and enabled state.
+               // Visibility will be adjusted by restoreState below.
+               dialog->prepareView();
+       if ((dialog = findOrBuild("view-source", true)))
+               dialog->prepareView();
 
        if (!restoreState(settings.value("layout").toByteArray(), 0))
                initToolbars();
@@ -411,7 +433,12 @@ void GuiView::constructToolbars()
        for (; it != d.toolbars_.end(); ++it)
                delete it->second;
        d.toolbars_.clear();
-       d.layout_ = 0;
+
+       // I don't like doing this here, but the standard toolbar
+       // destroys this object when it's destroyed itself (vfr)
+       d.layout_ = new LayoutBox(*this);
+       d.stack_widget_->addWidget(d.layout_);
+       d.layout_->move(0,0);
 
        // extracts the toolbars from the backend
        Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
@@ -479,6 +506,7 @@ 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);
@@ -508,53 +536,24 @@ 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.
        setFocus();
-
-       while (Buffer * b = buffer()) {
-               if (b->parent()) {
-                       // This is a child document, just close the tab after saving
-                       // but keep the file loaded.
-                       if (!saveBuffer(*b)) {
-                               closing_ = false;
-                               close_event->ignore();
-                               return;
-                       }
-                       removeWorkArea(d.current_work_area_);
-                       continue;
-               }
-
-               QList<int> const ids = guiApp->viewIds();
-               for (int i = 0; i != ids.size(); ++i) {
-                       if (id_ == ids[i])
-                               continue;
-                       if (guiApp->view(ids[i]).workArea(*b)) {
-                               // FIXME 1: should we put an alert box here that the buffer
-                               // is viewed elsewhere?
-                               // FIXME 2: should we try to save this buffer in any case?
-                               //saveBuffer(b);
-
-                               // This buffer is also opened in another view, so
-                               // close the associated work area...
-                               removeWorkArea(d.current_work_area_);
-                               // ... but don't close the buffer.
-                               b = 0;
-                               break;
-                       }
-               }
-               if (b && !closeBuffer(*b, true)) {
-                       closing_ = false;
-                       close_event->ignore();
-                       return;
-               }
+       if (!closeBufferAll(true)) {
+               closing_ = false;
+               close_event->ignore();
+               return;
        }
 
-       // Make sure that nothing will use this close to be closed View.
+       // Make sure that nothing will use this to be closed View.
        guiApp->unregisterView(this);
 
        if (isFullScreen()) {
@@ -585,6 +584,68 @@ void GuiView::closeEvent(QCloseEvent * close_event)
 }
 
 
+bool GuiView::closeBufferAll(bool tolastopened)
+{
+       GuiWorkArea * active_wa = currentMainWorkArea();
+       setCurrentWorkArea(active_wa);
+
+       // We might be in a situation that there is still a tabWorkArea, but
+       // there are no tabs anymore. This can happen when we get here after a 
+       // TabWorkArea::lastWorkAreaRemoved() signal. Therefore we count how
+       // many TabWorkArea's have no documents anymore.
+       int empty_twa = 0;
+
+       // We have to call count() each time, because it can happen that
+       // more than one splitter will disappear in one iteration (bug 5998).
+       for (; d.splitter_->count() > empty_twa; ) {
+               TabWorkArea * twa = d.tabWorkArea(empty_twa);
+                               
+               int twa_count = twa->count();
+               if (twa->count() == 0)
+                       ++empty_twa;
+
+               for (; twa == d.tabWorkArea(empty_twa) && twa_count; --twa_count) {
+                       twa->setCurrentIndex(twa_count-1);
+
+                       GuiWorkArea * wa = twa->currentWorkArea();
+                       bool const is_active_wa = active_wa == wa;
+                       Buffer & b = wa->bufferView().buffer();
+
+                       if (b.parent()) {
+                               // This is a child document, just close the tab
+                               // after saving but keep the file loaded.
+                               if (!closeWorkArea(wa, false, tolastopened, is_active_wa))
+                                       return false;
+                               continue;
+                       }
+
+                       vector<Buffer *> clist = b.getChildren();
+                       for (vector<Buffer *>::const_iterator it = clist.begin();
+                                it != clist.end(); ++it) {
+                               if ((*it)->isClean())
+                                       continue;
+                               Buffer * c = *it;
+                               // If a child is dirty, do not close
+                               // without user intervention
+                               //FIXME: should buffers be closed or not?
+                               if (!closeWorkArea(workArea(*c), false, false))
+                                       return false;
+                       }
+
+                       // We only want to close the buffer if the same buffer is not in
+                       // another view.
+                       bool const close_buffer = !inMultiViews(wa);
+
+                       // closeBuffer() needs buffer workArea still alive and
+                       // set as currrent one, and destroys it
+                       if (!closeWorkArea(wa, close_buffer, tolastopened, is_active_wa))
+                               return false;
+               }
+       }
+       return true;
+}
+
+
 void GuiView::dragEnterEvent(QDragEnterEvent * event)
 {
        if (event->mimeData()->hasUrls())
@@ -595,7 +656,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())
@@ -605,8 +666,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();
+               }
        }
 }
 
@@ -778,17 +844,18 @@ bool GuiView::event(QEvent * e)
 
        case QEvent::ShortcutOverride: {
 
-#ifndef Q_WS_X11
-               // FIXME bug 4888
+// See bug 4888
+#if (!defined Q_WS_X11) || (QT_VERSION >= 0x040500)
                if (isFullScreen() && menuBar()->isHidden()) {
                        QKeyEvent * ke = static_cast<QKeyEvent*>(e);
                        // FIXME: we should also try to detect special LyX shortcut such as
                        // Alt-P and Alt-M. Right now there is a hack in
                        // GuiWorkArea::processKeySym() that hides again the menubar for
                        // those cases.
-                       if (ke->modifiers() & Qt::AltModifier && ke->key() != Qt::Key_Alt)
+                       if (ke->modifiers() & Qt::AltModifier && ke->key() != Qt::Key_Alt) {
                                menuBar()->show();
-                       return QMainWindow::event(e);
+                               return QMainWindow::event(e);
+                       }
                }
 #endif
 
@@ -850,6 +917,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;
@@ -885,14 +955,63 @@ 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, return);
+       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;
+
+       if (view())
+               cap::saveSelection(view()->cursor());
+
+       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());
 }
 
 
@@ -903,39 +1022,47 @@ void GuiView::removeWorkArea(GuiWorkArea * wa)
                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();
 }
 
 
-void GuiView::setLayoutDialog(GuiLayoutBox * layout)
+LayoutBox * GuiView::getLayoutDialog() const
 {
-       d.layout_ = layout;
+       return d.layout_;
 }
 
 
@@ -986,12 +1113,13 @@ Buffer const * GuiView::buffer() const
 
 void GuiView::setBuffer(Buffer * 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.
@@ -1031,11 +1159,16 @@ void GuiView::disconnectBufferView()
 }
 
 
-void GuiView::errors(string const & error_type)
+void GuiView::errors(string const & error_type, bool from_master)
 {
-       ErrorList & el = buffer()->errorList(error_type);
+       ErrorList & el = from_master ? 
+               buffer()->masterBuffer()->errorList(error_type)
+               : buffer()->errorList(error_type);
+       string data = error_type;
+       if (from_master)
+               data = "from_master|" + error_type;
        if (!el.empty())
-               showDialog("errorlist", error_type);
+               showDialog("errorlist", data);
 }
 
 
@@ -1096,16 +1229,15 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
        bool enable = true;
        Buffer * buf = buffer();
 
-       /* In LyX/Mac, when a dialog is open, the menus of the
-          application can still be accessed without giving focus to
-          the main window. In this case, we want to disable the menu
-          entries that are buffer-related.
-
-          Note that this code is not perfect, as bug 1941 attests:
-          http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
-       */
-       if (cmd.origin == FuncRequest::MENU && !hasFocus())
-               buf = 0;
+       if (cmd.origin == FuncRequest::TOC) {
+               GuiToc * toc = static_cast<GuiToc*>(findOrBuild("toc", false));
+               FuncStatus fs;
+               if (toc->getStatus(view()->cursor(), cmd, fs))
+                       flag |= fs;
+               else
+                       flag.setEnabled(false);
+               return true;
+       }
 
        switch(cmd.action) {
        case LFUN_BUFFER_WRITE:
@@ -1116,6 +1248,22 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                enable = buf;
                break;
 
+       case LFUN_BUFFER_CLOSE_ALL: {
+               enable = false;
+               BufferList::iterator it = theBufferList().begin();
+               BufferList::iterator end = theBufferList().end();
+               int visible_buffers = 0;
+               for (; it != end; ++it) {
+                       if (workArea(**it))
+                               ++visible_buffers;
+                       if (visible_buffers > 1) {
+                               enable = true;
+                               break;
+                       }
+               }
+               break;
+       }
+
        case LFUN_SPLIT_VIEW:
                if (cmd.getArg(0) == "vertical")
                        enable = buf && (d.splitter_->count() == 1 ||
@@ -1151,30 +1299,20 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                else if (name == "print")
                        enable = buf->isExportable("dvi")
                                && lyxrc.print_command != "none";
-               else if (name == "character") {
-                       if (!view())
+               else if (name == "character" || name == "symbols") {
+                       if (buf->isReadonly() || !view() || !view()->cursor().inTexted())
                                enable = false;
                        else {
-                               InsetCode ic = view()->cursor().inset().lyxCode();
-                               enable = ic != ERT_CODE && ic != LISTINGS_CODE;
-                       }
-               }
-               else if (name == "symbols") {
-                       if (!view() || view()->cursor().inMathed())
-                               enable = false;
-                       else {
-                               InsetCode ic = view()->cursor().inset().lyxCode();
-                               enable = ic != ERT_CODE && ic != LISTINGS_CODE;
+                               // FIXME we should consider passthru
+                               // paragraphs too.
+                               Inset const & in = view()->cursor().inset();
+                               enable = !in.getLayout().isPassThru();
                        }
                }
                else if (name == "latexlog")
                        enable = FileName(buf->logName()).isReadableFile();
                else if (name == "spellchecker")
-#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
-                       enable = !buf->isReadonly();
-#else
-                       enable = false;
-#endif
+                       enable = theSpellChecker() && !buf->isReadonly();
                else if (name == "vclog")
                        enable = buf->lyxvc().inUse();
                break;
@@ -1225,6 +1363,13 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                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()
@@ -1232,6 +1377,14 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                        enable = false;
                break;
 
+       case LFUN_BUFFER_ZOOM_OUT:
+               enable = buf && lyxrc.zoom > 10;
+               break;
+
+       case LFUN_BUFFER_ZOOM_IN:
+               enable = buf;
+               break;
+
        default:
                return false;
        }
@@ -1311,7 +1464,8 @@ void GuiView::openDocument(string const & fname)
                QStringList filter(qt_("LyX Documents (*.lyx)"));
                filter << qt_("LyX-1.3.x Documents (*.lyx13)")
                        << qt_("LyX-1.4.x Documents (*.lyx14)")
-                       << qt_("LyX-1.5.x Documents (*.lyx15)");
+                       << qt_("LyX-1.5.x Documents (*.lyx15)")
+                       << qt_("LyX-1.6.x Documents (*.lyx16)");
                FileDialog::Result result =
                        dlg.open(toqstr(initpath), filter);
 
@@ -1337,7 +1491,7 @@ void GuiView::openDocument(string const & fname)
 
        if (!fullname.onlyPath().isDirectory()) {
                Alert::warning(_("Invalid filename"),
-                               bformat(_("The directory in the given path\n%1$s\ndoes not exists."),
+                               bformat(_("The directory in the given path\n%1$s\ndoes not exist."),
                                from_utf8(fullname.absFilename())));
                return;
        }
@@ -1356,8 +1510,7 @@ 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);
@@ -1406,7 +1559,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 {
@@ -1530,8 +1683,13 @@ void GuiView::newDocument(string const & filename, bool from_template)
                        initpath = trypath;
        }
 
-       string templatefile = from_template ?
-               selectTemplateFile().absFilename() : string();
+       string templatefile;
+       if (from_template) {
+               templatefile = selectTemplateFile().absFilename();
+               if (templatefile.empty())
+                       return;
+       }
+       
        Buffer * b;
        if (filename.empty())
                b = newUnnamedFile(templatefile, initpath);
@@ -1540,8 +1698,12 @@ void GuiView::newDocument(string const & filename, bool from_template)
 
        if (b)
                setBuffer(b);
-       // Ensure the cursor is correctly positionned on screen.
-       view()->showCursor();
+
+       // If no new document could be created, it is unsure 
+       // whether there is a valid BufferView.
+       if (view())
+               // Ensure the cursor is correctly positioned on screen.
+               view()->showCursor();
 }
 
 
@@ -1601,6 +1763,11 @@ void GuiView::insertPlaintextFile(docstring const & fname,
        if (!bv)
                return;
 
+       if (!fname.empty() && !FileName::isAbsolute(to_utf8(fname))) {
+               message(_("Absolute filename expected."));
+               return;
+       }
+
        // FIXME UNICODE
        FileName filename(to_utf8(fname));
        
@@ -1613,7 +1780,7 @@ void GuiView::insertPlaintextFile(docstring const & fname,
                LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
 
        FileDialog::Result result = dlg.open(toqstr(bv->buffer().filePath()),
-               QStringList());
+               QStringList(qt_("All Files (*)")));
 
        if (result.first == FileDialog::Later)
                return;
@@ -1644,7 +1811,7 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
                // Switch to this Buffer.
                setBuffer(&b);
 
-               /// No argument? Ask user through dialog.
+               // No argument? Ask user through dialog.
                // FIXME UNICODE
                FileDialog dlg(qt_("Choose a filename to save document as"),
                                   LFUN_BUFFER_WRITE_AS);
@@ -1686,6 +1853,8 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
                }
        }
 
+       FileName oldauto = b.getAutosaveFilename();
+
        // Ok, change the name of the buffer
        b.setFileName(fname.absFilename());
        b.markDirty();
@@ -1693,10 +1862,15 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
        b.setUnnamed(false);
        b.saveCheckSum(fname);
 
+       // bring the autosave file with us, just in case.
+       b.moveAutosaveFile(oldauto);
+       
        if (!saveBuffer(b)) {
+               oldauto = b.getAutosaveFilename();
                b.setFileName(oldname.absFilename());
                b.setUnnamed(unnamed);
                b.saveCheckSum(oldname);
+               b.moveAutosaveFile(oldauto);
                return false;
        }
 
@@ -1706,6 +1880,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());
 
@@ -1739,30 +1916,55 @@ bool GuiView::saveBuffer(Buffer & b)
 }
 
 
+bool GuiView::hideWorkArea(GuiWorkArea * wa)
+{
+       return closeWorkArea(wa, false);
+}
+
+
 bool GuiView::closeBuffer()
 {
-       Buffer * buf = buffer();
-       return buf && closeBuffer(*buf);
+       GuiWorkArea * wa = currentMainWorkArea();
+       Buffer & buf = wa->bufferView().buffer();
+       return wa && closeWorkArea(wa, !buf.parent());
 }
 
 
-bool GuiView::closeBuffer(Buffer & buf, bool tolastopened)
+bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
+       bool tolastopened, bool mark_active)
 {
        // 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());
-               if (buf.parent())
-                       // Don't close child documents.
-                       removeWorkArea(d.current_work_area_);
+       // if we are only hiding the buffer and there are multiple views
+       // of the buffer, then we do not need to ensure a clean buffer.
+       bool const allow_dirty = inMultiTabs(wa) && !close_buffer;
+
+       Buffer & buf = wa->bufferView().buffer();
+       if (allow_dirty || saveBufferIfNeeded(buf, !close_buffer)) {
+               // save in sessions if requested
+               // do not save childs if their master
+               // is opened as well
+               if (tolastopened)
+                       theSession().lastOpened().add(buf.fileName(), mark_active);
+               if (!close_buffer)
+                       removeWorkArea(wa);
                else
                        theBufferList().release(&buf);
                return true;
        }
+       return false;
+}
+
+
+bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding)
+{
+       if (buf.isClean() || buf.paragraphs().empty())
+               return true;
+
        // Switch to this Buffer.
        setBuffer(&buf);
 
@@ -1777,10 +1979,21 @@ bool GuiView::closeBuffer(Buffer & buf, bool tolastopened)
        raise();
        activateWindow();
 
-       docstring const text = bformat(_("The document %1$s has unsaved changes."
-               "\n\nDo you want to save the document or discard the changes?"), file);
-       int const ret = Alert::prompt(_("Save changed document?"),
-               text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
+       int ret;
+       if (hiding && buf.isUnnamed()) {
+               docstring const text = bformat(_("The document %1$s has not been "
+                                            "saved yet.\n\nDo you want to save "
+                                            "the document?"), file);
+               ret = Alert::prompt(_("Save new document?"), 
+                       text, 0, 1, _("&Save"), _("&Cancel"));
+               if (ret == 1)
+                       ++ret;
+       } else {
+               docstring const text = bformat(_("The document %1$s has unsaved changes."
+                       "\n\nDo you want to save the document or discard the changes?"), file);
+               ret = Alert::prompt(_("Save changed document?"),
+                       text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
+       }
 
        switch (ret) {
        case 0:
@@ -1791,25 +2004,69 @@ bool GuiView::closeBuffer(Buffer & buf, bool tolastopened)
                // if we crash after this we could
                // have no autosave file but I guess
                // this is really improbable (Jug)
-               removeAutosaveFile(buf.absFileName());
+               buf.removeAutosaveFile();
+               if (hiding) {
+                       // revert all changes
+                       buf.loadLyXFile(buf.fileName());
+                       buf.markClean();
+               }
                break;
        case 2:
                return false;
        }
+       return true;
+}
 
-       // save file names to .lyx/session
-       // if master/slave are both open, do not save slave since it
-       // will be automatically loaded when the master is loaded
-       if (buf.masterBuffer() == &buf && tolastopened)
-               theSession().lastOpened().add(buf.fileName());
 
-       if (buf.parent())
-               // Don't close child documents.
-               removeWorkArea(d.current_work_area_);
-       else
-               theBufferList().release(&buf);
+bool GuiView::inMultiTabs(GuiWorkArea * wa)
+{
+       Buffer & buf = wa->bufferView().buffer();
 
-       return true;
+       for (int i = 0; i != d.splitter_->count(); ++i) {
+               GuiWorkArea * wa_ = d.tabWorkArea(i)->workArea(buf);
+               if (wa_ && wa_ != wa)
+                       return true;
+       }
+       return inMultiViews(wa);
+}
+
+
+bool GuiView::inMultiViews(GuiWorkArea * wa)
+{
+       QList<int> const ids = guiApp->viewIds();
+       Buffer & buf = wa->bufferView().buffer();
+
+       int found_twa = 0;
+       for (int i = 0; i != ids.size() && found_twa <= 1; ++i) {
+               if (id_ == ids[i])
+                       continue;
+               
+               if (guiApp->view(ids[i]).workArea(buf))
+                       return true;
+       }
+       return false;
+}
+
+
+void GuiView::gotoNextOrPreviousBuffer(NextOrPrevious np)
+{
+       Buffer * const curbuf = buffer();
+       Buffer * nextbuf = curbuf;
+       while (true) {
+               if (np == NEXTBUFFER)
+                       nextbuf = theBufferList().next(nextbuf);
+               else
+                       nextbuf = theBufferList().previous(nextbuf);
+               if (nextbuf == curbuf)
+                       break;
+               if (nextbuf == 0) {
+                       nextbuf = curbuf;
+                       break;
+               }
+               if (workArea(*nextbuf))
+                       break;
+       }
+       setBuffer(nextbuf);
 }
 
 
@@ -1821,21 +2078,34 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                bv->cursor().updateFlags(Update::None);
        bool dispatched = true;
 
+       if (cmd.origin == FuncRequest::TOC) {
+               GuiToc * toc = static_cast<GuiToc*>(findOrBuild("toc", false));
+               toc->doDispatch(bv->cursor(), cmd);
+               return true;
+       }
+
        switch(cmd.action) {
                case LFUN_BUFFER_IMPORT:
                        importDocument(to_utf8(cmd.argument()));
                        break;
 
                case LFUN_BUFFER_SWITCH:
-                       setBuffer(theBufferList().getBuffer(FileName(to_utf8(cmd.argument()))));
+                       if (FileName::isAbsolute(to_utf8(cmd.argument()))) {
+                               Buffer * buffer = 
+                                       theBufferList().getBuffer(FileName(to_utf8(cmd.argument())));
+                               if (buffer)
+                                       setBuffer(buffer);
+                               else
+                                       bv->cursor().message(_("Document not loaded"));
+                       }
                        break;
 
                case LFUN_BUFFER_NEXT:
-                       setBuffer(theBufferList().next(buffer()));
+                       gotoNextOrPreviousBuffer(NEXTBUFFER);
                        break;
 
                case LFUN_BUFFER_PREVIOUS:
-                       setBuffer(theBufferList().previous(buffer()));
+                       gotoNextOrPreviousBuffer(PREVBUFFER);
                        break;
 
                case LFUN_COMMAND_EXECUTE: {
@@ -1850,8 +2120,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        break;
                }
                case LFUN_DROP_LAYOUTS_CHOICE:
-                       if (d.layout_)
-                               d.layout_->showPopup();
+                       d.layout_->showPopup();
                        break;
 
                case LFUN_MENU_OPEN:
@@ -1914,7 +2183,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                inset->dispatch(view()->cursor(), fr);
                        } else if (name == "paragraph") {
                                lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
-                       } else if (name == "prefs") {
+                       } else if (name == "prefs" || name == "document") {
                                updateDialog(name, string());
                        }
                        break;
@@ -1966,6 +2235,11 @@ 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;
@@ -1976,8 +2250,9 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                        Inset * inset = getOpenInset(name);
                        if (inset) {
                                // put cursor in front of inset.
-                               if (!view()->setCursorFromInset(inset))
+                               if (!view()->setCursorFromInset(inset)) {
                                        LASSERT(false, break);
+                               }
                                
                                // useful if we are called from a dialog.
                                view()->cursor().beginUndoGroup();
@@ -2012,18 +2287,15 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                case LFUN_CLOSE_TAB_GROUP:
                        if (TabWorkArea * twa = d.currentTabWorkArea()) {
                                delete twa;
+                               d.current_work_area_ = 0;
                                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;
                        
@@ -2057,6 +2329,25 @@ bool GuiView::dispatch(FuncRequest const & cmd)
                                d.current_work_area_->completer().activate();
                        break;
 
+               case LFUN_BUFFER_ZOOM_IN:
+               case LFUN_BUFFER_ZOOM_OUT:
+                       if (cmd.argument().empty()) {
+                               if (cmd.action == LFUN_BUFFER_ZOOM_IN)
+                                       lyxrc.zoom += 20;
+                               else
+                                       lyxrc.zoom -= 20;
+                       } else
+                               lyxrc.zoom += convert<int>(cmd.argument());
+
+                       if (lyxrc.zoom < 10)
+                               lyxrc.zoom = 10;
+                               
+                       // The global QPixmapCache is used in GuiPainter to cache text
+                       // painting so we must reset it.
+                       QPixmapCache::clear();
+                       guiApp->fontLoader().update();
+                       lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
+                       break;
 
                default:
                        dispatched = false;
@@ -2065,7 +2356,7 @@ bool GuiView::dispatch(FuncRequest const & cmd)
 
        // Part of automatic menu appearance feature.
        if (isFullScreen()) {
-               if (menuBar()->isVisible())
+               if (menuBar()->isVisible() && lyxrc.full_screen_menubar)
                        menuBar()->hide();
                if (statusBar()->isVisible())
                        statusBar()->hide();
@@ -2134,6 +2425,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
@@ -2142,13 +2435,17 @@ void GuiView::toggleFullScreen()
                saveLayout();
                setWindowState(windowState() ^ Qt::WindowFullScreen);
                statusBar()->hide();
-               menuBar()->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();
 }
 
 
@@ -2194,16 +2491,13 @@ namespace {
 
 char const * const dialognames[] = {
 "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
-"citation", "document", "errorlist", "ert", "external", "file",
-"findreplace", "float", "graphics", "include", "index", "info", "nomenclature", "label", "log",
-"mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print", 
-"ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate",
-
-#ifdef HAVE_LIBAIKSAURUS
-"thesaurus",
-#endif
-
-"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
+"citation", "document", "errorlist", "ert", "external", "file", "findreplace",
+"findreplaceadv", "float", "graphics", "href", "include", "index",
+"index_print", "info", "listings", "label", "log", "mathdelimiter",
+"mathmatrix", "mathspace", "nomenclature", "nomencl_print", "note",
+"paragraph", "phantom", "prefs", "print", "ref", "sendto", "space",
+"spellchecker", "symbols", "tabular", "tabularcreate", "thesaurus", "texinfo",
+"toc", "view-source", "vspace", "wrap" };
 
 char const * const * const end_dialognames =
        dialognames + (sizeof(dialognames) / sizeof(char *));
@@ -2235,9 +2529,8 @@ void GuiView::resetDialogs()
        saveLayout();
        menuBar()->clear();
        constructToolbars();
-       guiApp->menus().fillMenuBar(menuBar(), this, true);
-       if (d.layout_)
-               d.layout_->updateContents(true);
+       guiApp->menus().fillMenuBar(menuBar(), this, false);
+       d.layout_->updateContents(true);
        // Now update controls with current buffer.
        theLyXFunc().setLyXView(this);
        restoreLayout();
@@ -2296,7 +2589,7 @@ bool GuiView::isDialogVisible(string const & name) const
        map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
        if (it == d.dialogs_.end())
                return false;
-       return it->second.get()->isVisibleView();
+       return it->second.get()->isVisibleView() && !it->second.get()->isClosing();
 }
 
 
@@ -2377,20 +2670,25 @@ Dialog * createGuiERT(GuiView & lv);
 Dialog * createGuiExternal(GuiView & lv);
 Dialog * createGuiFloat(GuiView & lv);
 Dialog * createGuiGraphics(GuiView & lv);
-Dialog * createGuiHSpace(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);
 Dialog * createGuiParagraph(GuiView & lv);
+Dialog * createGuiPhantom(GuiView & lv);
 Dialog * createGuiPreferences(GuiView & lv);
 Dialog * createGuiPrint(GuiView & lv);
+Dialog * createGuiPrintindex(GuiView & lv);
+Dialog * createGuiPrintNomencl(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);
@@ -2398,6 +2696,7 @@ 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);
@@ -2438,30 +2737,44 @@ 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")
                return createGuiGraphics(*this);
+       if (name == "href")
+               return createGuiHyperlink(*this);
        if (name == "include")
                return createGuiInclude(*this);
+       if (name == "index")
+               return createGuiIndex(*this);
+       if (name == "index_print")
+               return createGuiPrintindex(*this);
        if (name == "info")
                return createGuiInfo(*this);
-       if (name == "nomenclature")
-               return createGuiNomenclature(*this);
        if (name == "label")
                return createGuiLabel(*this);
+       if (name == "listings")
+               return createGuiListings(*this);
        if (name == "log")
                return createGuiLog(*this);
-       if (name == "view-source")
-               return createGuiViewSource(*this);
        if (name == "mathdelimiter")
                return createGuiDelimiter(*this);
+       if (name == "mathspace")
+               return createGuiMathHSpace(*this);
        if (name == "mathmatrix")
                return createGuiMathMatrix(*this);
+       if (name == "nomenclature")
+               return createGuiNomenclature(*this);
+       if (name == "nomencl_print")
+               return createGuiPrintNomencl(*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 == "print")
@@ -2471,7 +2784,7 @@ Dialog * GuiView::build(string const & name)
        if (name == "sendto")
                return createGuiSendTo(*this);
        if (name == "space")
-               return createGuiHSpace(*this);
+               return createGuiTextHSpace(*this);
        if (name == "spellchecker")
                return createGuiSpellchecker(*this);
        if (name == "symbols")
@@ -2482,20 +2795,16 @@ Dialog * GuiView::build(string const & name)
                return createGuiTabularCreate(*this);
        if (name == "texinfo")
                return createGuiTexInfo(*this);
-#ifdef HAVE_LIBAIKSAURUS
        if (name == "thesaurus")
                return createGuiThesaurus(*this);
-#endif
        if (name == "toc")
                return createGuiToc(*this);
-       if (name == "href")
-               return createGuiHyperlink(*this);
+       if (name == "view-source")
+               return createGuiViewSource(*this);
        if (name == "vspace")
                return createGuiVSpace(*this);
        if (name == "wrap")
                return createGuiWrap(*this);
-       if (name == "listings")
-               return createGuiListings(*this);
 
        return 0;
 }
@@ -2504,4 +2813,4 @@ Dialog * GuiView::build(string const & name)
 } // namespace frontend
 } // namespace lyx
 
-#include "GuiView_moc.cpp"
+#include "moc_GuiView.cpp"