]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiView.cpp
Allow use of Tab keys when no document's open.
[lyx.git] / src / frontends / qt4 / GuiView.cpp
index 333fdf58e58ceed5243919d8b342045552d9ceaf..c07aa04ec0aedc20424c0bd294ad51f41dbb3bdd 100644 (file)
 
 #include <config.h>
 
-#include "GuiView.h"
-#include "Dialog.h"
-
-#include <boost/assert.hpp>
-
-using std::string;
-
 #include "GuiView.h"
 
+#include "Dialog.h"
+#include "frontends/FileDialog.h"
 #include "GuiApplication.h"
 #include "GuiWorkArea.h"
 #include "GuiKeySymbol.h"
-#include "GuiMenubar.h"
 #include "GuiToolbar.h"
 #include "GuiToolbars.h"
+#include "Menus.h"
 
 #include "qt_helpers.h"
 
-#include "support/filetools.h"
-#include "support/convert.h"
-#include "support/lstrings.h"
-#include "support/os.h"
+#include "frontends/alert.h"
 
 #include "buffer_funcs.h"
 #include "Buffer.h"
@@ -42,29 +34,36 @@ using std::string;
 #include "BufferParams.h"
 #include "BufferView.h"
 #include "Cursor.h"
-#include "debug.h"
+#include "support/debug.h"
 #include "ErrorList.h"
 #include "FuncRequest.h"
-#include "gettext.h"
+#include "support/gettext.h"
 #include "Intl.h"
 #include "Layout.h"
+#include "Lexer.h"
 #include "LyXFunc.h"
 #include "LyX.h"
 #include "LyXRC.h"
-#include "MenuBackend.h"
+#include "LyXVC.h"
 #include "Paragraph.h"
 #include "TextClass.h"
 #include "Text.h"
 #include "ToolbarBackend.h"
 #include "version.h"
 
+#include "support/FileFilterList.h"
+#include "support/FileName.h"
+#include "support/filetools.h"
+#include "support/ForkedCalls.h"
 #include "support/lstrings.h"
-#include "support/filetools.h" // OnlyFilename()
+#include "support/os.h"
+#include "support/Package.h"
 #include "support/Timeout.h"
 
 #include <QAction>
 #include <QApplication>
 #include <QCloseEvent>
+#include <QDebug>
 #include <QDesktopWidget>
 #include <QDragEnterEvent>
 #include <QDropEvent>
@@ -79,11 +78,12 @@ using std::string;
 #include <QSplitter>
 #include <QStackedWidget>
 #include <QStatusBar>
+#include <QTimer>
 #include <QToolBar>
 #include <QUrl>
 
+#include <boost/assert.hpp>
 #include <boost/bind.hpp>
-#include <boost/current_function.hpp>
 
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -92,9 +92,8 @@ using std::string;
 # include <unistd.h>
 #endif
 
-using std::endl;
-using std::string;
-using std::vector;
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
 
@@ -102,50 +101,39 @@ extern bool quitting;
 
 namespace frontend {
 
-using support::bformat;
-using support::FileName;
-using support::makeDisplayPath;
-using support::onlyFilename;
-
 namespace {
 
-int const statusbar_timer_value = 3000;
-
 class BackgroundWidget : public QWidget
 {
 public:
-       BackgroundWidget(QString const & file, QString const & text)
+       BackgroundWidget()
        {
-               splash_ = new QPixmap(file);
-               if (!splash_) {
-                       lyxerr << "could not load splash screen: '" << fromqstr(file) << "'" << endl;
-                       return;
-               }
+               LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner);
+               /// The text to be written on top of the pixmap
+               QString const text = lyx_version ? lyx_version : qt_("unknown version");
+               splash_ = QPixmap(":/images/banner.png");
 
-               QPainter pain(splash_);
+               QPainter pain(&splash_);
                pain.setPen(QColor(255, 255, 0));
                QFont font;
                // The font used to display the version info
                font.setStyleHint(QFont::SansSerif);
                font.setWeight(QFont::Bold);
-               font.setPointSize(convert<int>(lyxrc.font_sizes[FONT_SIZE_LARGE]));
+               font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
                pain.setFont(font);
                pain.drawText(260, 270, text);
        }
 
        void paintEvent(QPaintEvent *)
        {
-               if (!splash_)
-                       return;
-
-               int x = (width() - splash_->width()) / 2;
-               int y = (height() - splash_->height()) / 2;
+               int x = (width() - splash_.width()) / 2;
+               int y = (height() - splash_.height()) / 2;
                QPainter pain(this);
-               pain.drawPixmap(x, y, *splash_);
+               pain.drawPixmap(x, y, splash_);
        }
 
 private:
-       QPixmap splash_;
+       QPixmap splash_;
 };
 
 } // namespace anon
@@ -156,9 +144,8 @@ typedef boost::shared_ptr<Dialog> DialogPtr;
 struct GuiView::GuiViewPrivate
 {
        GuiViewPrivate()
-               : current_work_area_(0), posx_offset(0), posy_offset(0),
-               autosave_timeout_(new Timeout(5000)), quitting_by_menu_(false),
-               in_show_(false)
+               : current_work_area_(0), layout_(0),
+               quitting_by_menu_(false), autosave_timeout_(5000), in_show_(false)
        {
                // hardcode here the platform specific icon size
                smallIconSize = 14;     // scaling problems
@@ -166,7 +153,7 @@ struct GuiView::GuiViewPrivate
                bigIconSize = 26;               // better for some math icons
 
                splitter_ = new QSplitter;
-               initBackground();
+               bg_widget_ = new BackgroundWidget;
                stack_widget_ = new QStackedWidget;
                stack_widget_->addWidget(bg_widget_);
                stack_widget_->addWidget(splitter_);
@@ -178,9 +165,7 @@ struct GuiView::GuiViewPrivate
                delete splitter_;
                delete bg_widget_;
                delete stack_widget_;
-               delete menubar_;
                delete toolbars_;
-               delete autosave_timeout_;
        }
 
        QMenu * toolBarPopup(GuiView * parent)
@@ -221,14 +206,6 @@ struct GuiView::GuiViewPrivate
                return menu;
        }
 
-       void initBackground()
-       {
-               LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner);
-               /// The text to be written on top of the pixmap
-               QString const text = lyx_version ? QString(lyx_version) : qt_("unknown version");
-               bg_widget_ = new BackgroundWidget(":/images/banner.png", text);
-       }
-
        void setBackground()
        {
                stack_widget_->setCurrentWidget(bg_widget_);
@@ -260,28 +237,28 @@ struct GuiView::GuiViewPrivate
        }
 
 public:
-       ///
-       string cur_title;
-
        GuiWorkArea * current_work_area_;
-       int posx_offset;
-       int posy_offset;
-
        QSplitter * splitter_;
        QStackedWidget * stack_widget_;
        BackgroundWidget * bg_widget_;
-       /// view's menubar
-       GuiMenubar * menubar_;
        /// view's toolbars
        GuiToolbars * toolbars_;
-       ///
-       docstring current_layout;
+       /// The main layout box.
+       /** 
+        * \warning Don't Delete! The layout box is actually owned by
+        * whichever toolbar contains it. All the GuiView class needs is a
+        * means of accessing it.
+        *
+        * FIXME: replace that with a proper model so that we are not limited
+        * to only one dialog.
+        */
+       GuiLayoutBox * layout_;
 
        ///
-       std::map<std::string, Inset *> open_insets_;
+       map<string, Inset *> open_insets_;
 
        ///
-       std::map<std::string, DialogPtr> dialogs_;
+       map<string, DialogPtr> dialogs_;
 
        unsigned int smallIconSize;
        unsigned int normalIconSize;
@@ -291,30 +268,30 @@ public:
        /// are we quitting by the menu?
        bool quitting_by_menu_;
        /// auto-saving of buffers
-       Timeout * const autosave_timeout_;
-       ///
-       /// flag against a race condition due to multiclicks in Qt frontend,
-       /// see bug #1119
+       Timeout autosave_timeout_;
+       /// flag against a race condition due to multiclicks, see bug #1119
        bool in_show_;
 };
 
 
 GuiView::GuiView(int id)
-       : d(*new GuiViewPrivate),  id_(id)
+       : d(*new GuiViewPrivate), id_(id)
 {
-       // GuiToolbars *must* be initialised before GuiMenubar.
+       // GuiToolbars *must* be initialised before the menu bar.
        d.toolbars_ = new GuiToolbars(*this);
-       d.menubar_ = new GuiMenubar(this, menubackend);
+
+       // Fill up the menu bar.
+       guiApp->menus().fillMenuBar(this);
 
        setCentralWidget(d.stack_widget_);
 
        // Start autosave timer
        if (lyxrc.autosave) {
-               d.autosave_timeout_->timeout.connect(boost::bind(&GuiView::autoSave, this));
-               d.autosave_timeout_->setTimeout(lyxrc.autosave * 1000);
-               d.autosave_timeout_->start();
+               d.autosave_timeout_.timeout.connect(boost::bind(&GuiView::autoSave, this));
+               d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
+               d.autosave_timeout_.start();
        }
-       QObject::connect(&d.statusbar_timer_, SIGNAL(timeout()),
+       connect(&d.statusbar_timer_, SIGNAL(timeout()),
                this, SLOT(clearMessage()));
 
        // Qt bug? signal lastWindowClosed does not work
@@ -384,7 +361,7 @@ void GuiView::setFocus()
 }
 
 
-QMenu* GuiView::createPopupMenu()
+QMenu * GuiView::createPopupMenu()
 {
        return d.toolBarPopup(this);
 }
@@ -409,7 +386,7 @@ void GuiView::closeEvent(QCloseEvent * close_event)
        // we may have been called through the close window button
        // which bypasses the LFUN machinery.
        if (!d.quitting_by_menu_ && guiApp->viewCount() == 1) {
-               if (!theBufferList().quitWriteAll()) {
+               if (!quitWriteAll()) {
                        close_event->ignore();
                        return;
                }
@@ -431,6 +408,10 @@ void GuiView::closeEvent(QCloseEvent * close_event)
 #endif
                settings.setValue(key + "/icon_size", iconSize());
                d.toolbars_->saveToolbarInfo();
+               // Now take care of all other dialogs:
+               map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
+               for (; it!= d.dialogs_.end(); ++it)
+                       it->second->saveSession();
        }
 
        guiApp->unregisterView(id_);
@@ -467,21 +448,24 @@ void GuiView::dropEvent(QDropEvent* event)
        if (files.isEmpty())
                return;
 
-       LYXERR(Debug::GUI, BOOST_CURRENT_FUNCTION << " got URLs!");
+       LYXERR(Debug::GUI, "GuiView::dropEvent: got URLs!");
        for (int i = 0; i != files.size(); ++i) {
-               string const file = support::os::internal_path(fromqstr(
+               string const file = os::internal_path(fromqstr(
                        files.at(i).toLocalFile()));
                if (!file.empty())
-                       dispatch(FuncRequest(LFUN_FILE_OPEN, file));
+                       lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file));
        }
 }
 
 
 void GuiView::message(docstring const & str)
 {
+       if (ForkedProcess::iAmAChild())
+               return;
+
        statusBar()->showMessage(toqstr(str));
        d.statusbar_timer_.stop();
-       d.statusbar_timer_.start(statusbar_timer_value);
+       d.statusbar_timer_.start(3000);
 }
 
 
@@ -539,7 +523,7 @@ void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa)
        // require bv_->text.
        updateBufferDependent(true);
        updateToolbars();
-       updateLayoutChoice(false);
+       updateLayoutList();
        updateStatusBar();
 }
 
@@ -594,24 +578,30 @@ bool GuiView::event(QEvent * e)
                }
                return QMainWindow::event(e);
        }
+
        case QEvent::ShortcutOverride: {
+               if (d.current_work_area_)
+                       // Nothing special to do.
+                       return QMainWindow::event(e);
+
                QKeyEvent * ke = static_cast<QKeyEvent*>(e);
-               if (!d.current_work_area_) {
-                       theLyXFunc().setLyXView(this);
-                       KeySymbol sym;
-                       setKeySymbol(&sym, ke);
-                       theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
-                       e->accept();
-                       return true;
-               }
-               if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
-                       KeySymbol sym;
-                       setKeySymbol(&sym, ke);
-                       d.current_work_area_->processKeySym(sym, NoModifier);
-                       e->accept();
-                       return true;
-               }
+
+               // 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.
+               theLyXFunc().setLyXView(this);
+               KeySymbol sym;
+               setKeySymbol(&sym, ke);
+               theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
+               e->accept();
+               return true;
        }
+
        default:
                return QMainWindow::event(e);
        }
@@ -702,23 +692,13 @@ GuiWorkArea * GuiView::workArea(Buffer & buffer)
 
 GuiWorkArea * GuiView::addWorkArea(Buffer & buffer)
 {
-       GuiWorkArea * wa = new GuiWorkArea(buffer, *this);
-       wa->setUpdatesEnabled(false);
 
        // Automatically create a TabWorkArea if there are none yet.
        if (!d.splitter_->count())
                addTabWorkArea();
 
        TabWorkArea * tab_widget = d.currentTabWorkArea();
-       tab_widget->addTab(wa, wa->windowTitle());
-       QObject::connect(wa, SIGNAL(titleChanged(GuiWorkArea *)),
-               tab_widget, SLOT(updateTabText(GuiWorkArea *)));
-
-       wa->bufferView().updateMetrics();
-
-       // Hide tabbar if there's only one tab.
-       tab_widget->showBar(tab_widget->count() > 1);
-       return wa;
+       return tab_widget->addWorkArea(buffer, *this);
 }
 
 
@@ -738,15 +718,14 @@ GuiWorkArea const * GuiView::currentWorkArea() const
 }
 
 
-void GuiView::setCurrentWorkArea(GuiWorkArea * work_area)
+void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
 {
-       BOOST_ASSERT(work_area);
+       BOOST_ASSERT(wa);
 
        // Changing work area can result from opening a file so
        // update the toc in any case.
        updateToc();
 
-       GuiWorkArea * wa = static_cast<GuiWorkArea *>(work_area);
        d.current_work_area_ = wa;
        for (int i = 0; i != d.splitter_->count(); ++i) {
                if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
@@ -755,24 +734,19 @@ void GuiView::setCurrentWorkArea(GuiWorkArea * work_area)
 }
 
 
-void GuiView::removeWorkArea(GuiWorkArea * work_area)
+void GuiView::removeWorkArea(GuiWorkArea * wa)
 {
-       BOOST_ASSERT(work_area);
-       GuiWorkArea * gwa = static_cast<GuiWorkArea *>(work_area);
-       if (gwa == d.current_work_area_) {
+       BOOST_ASSERT(wa);
+       if (wa == d.current_work_area_) {
                disconnectBuffer();
                disconnectBufferView();
                hideBufferDependent();
                d.current_work_area_ = 0;
        }
 
-       // removing a work area often results from closing a file so
-       // update the toc in any case.
-       updateToc();
-
        for (int i = 0; i != d.splitter_->count(); ++i) {
                TabWorkArea * twa = d.tabWorkArea(i);
-               if (!twa->removeWorkArea(gwa))
+               if (!twa->removeWorkArea(wa))
                        // Not found in this tab group.
                        continue;
 
@@ -798,34 +772,19 @@ void GuiView::removeWorkArea(GuiWorkArea * work_area)
 }
 
 
-void GuiView::updateLayoutChoice(bool force)
+void GuiView::setLayoutDialog(GuiLayoutBox * layout)
 {
-       // Don't show any layouts without a buffer
-       if (!buffer()) {
-               d.toolbars_->clearLayoutList();
-               return;
-       }
-
-       // Update the layout display
-       if (d.toolbars_->updateLayoutList(buffer()->params().getTextClassPtr(), force)) {
-               d.current_layout = buffer()->params().getTextClass().defaultLayoutName();
-       }
-
-       docstring const & layout = d.current_work_area_->bufferView().cursor().
-               innerParagraph().layout()->name();
-
-       if (layout != d.current_layout) {
-               d.toolbars_->setLayout(layout);
-               d.current_layout = layout;
-       }
+       d.layout_ = layout;
 }
 
 
-bool GuiView::isToolbarVisible(std::string const & id)
+void GuiView::updateLayoutList()
 {
-       return d.toolbars_->visible(id);
+       if (d.layout_)
+               d.layout_->updateContents(false);
 }
 
+
 void GuiView::updateToolbars()
 {
        if (d.current_work_area_) {
@@ -836,10 +795,12 @@ void GuiView::updateToolbars()
                bool const review =
                        lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
                        lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
+               bool const mathmacrotemplate =
+                       lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
 
-               d.toolbars_->update(math, table, review);
+               d.toolbars_->update(math, table, review, mathmacrotemplate);
        } else
-               d.toolbars_->update(false, false, false);
+               d.toolbars_->update(false, false, false, false);
 
        // update read-only status of open dialogs.
        checkStatus();
@@ -883,40 +844,6 @@ void GuiView::setBuffer(Buffer * newBuffer)
 }
 
 
-Buffer * GuiView::loadLyXFile(FileName const & filename, bool tolastfiles)
-{
-       setBusy(true);
-
-       Buffer * newBuffer = checkAndLoadLyXFile(filename);
-
-       if (!newBuffer) {
-               message(_("Document not loaded."));
-               updateStatusBar();
-               setBusy(false);
-               return 0;
-       }
-
-       GuiWorkArea * wa = workArea(*newBuffer);
-       if (wa == 0)
-               wa = addWorkArea(*newBuffer);
-
-       // scroll to the position when the file was last closed
-       if (lyxrc.use_lastfilepos) {
-               LastFilePosSection::FilePos filepos =
-                       LyX::ref().session().lastFilePos().load(filename);
-               // if successfully move to pit (returned par_id is not zero),
-               // update metrics and reset font
-               wa->bufferView().moveToPosition(filepos.pit, filepos.pos, 0, 0);
-       }
-
-       if (tolastfiles)
-               LyX::ref().session().lastFiles().add(filename);
-
-       setBusy(false);
-       return newBuffer;
-}
-
-
 void GuiView::connectBuffer(Buffer & buf)
 {
        buf.setGuiDelegate(this);
@@ -956,7 +883,7 @@ void GuiView::updateDialog(string const & name, string const & data)
        if (!isDialogVisible(name))
                return;
 
-       std::map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
+       map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
        if (it == d.dialogs_.end())
                return;
 
@@ -996,30 +923,500 @@ void GuiView::autoSave()
 void GuiView::resetAutosaveTimers()
 {
        if (lyxrc.autosave)
-               d.autosave_timeout_->restart();
+               d.autosave_timeout_.restart();
+}
+
+
+FuncStatus 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;
+
+       switch(cmd.action) {
+       case LFUN_BUFFER_WRITE:
+               enable = buf && (buf->isUnnamed() || !buf->isClean());
+               break;
+
+       case LFUN_BUFFER_WRITE_AS:
+               enable = buf;
+               break;
+
+       case LFUN_TOOLBAR_TOGGLE:
+               flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
+               break;
+
+       case LFUN_DIALOG_TOGGLE:
+               flag.setOnOff(isDialogVisible(cmd.getArg(0)));
+               // fall through to set "enable"
+       case LFUN_DIALOG_SHOW: {
+               string const name = cmd.getArg(0);
+               if (!buf)
+                       enable = name == "aboutlyx"
+                               || name == "file" //FIXME: should be removed.
+                               || name == "prefs"
+                               || name == "texinfo";
+               else if (name == "print")
+                       enable = buf->isExportable("dvi")
+                               && lyxrc.print_command != "none";
+               else if (name == "character") {
+                       if (!view())
+                               enable = false;
+                       else {
+                               InsetCode ic = view()->cursor().inset().lyxCode();
+                               enable = ic != ERT_CODE && ic != LISTINGS_CODE;
+                       }
+               }
+               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
+               else if (name == "vclog")
+                       enable = buf->lyxvc().inUse();
+               break;
+       }
+
+       case LFUN_DIALOG_UPDATE: {
+               string const name = cmd.getArg(0);
+               if (!buf)
+                       enable = name == "prefs";
+               break;
+       }
+
+       case LFUN_INSET_APPLY: {
+               if (!buf) {
+                       enable = false;
+                       break;
+               }
+               string const name = cmd.getArg(0);
+               Inset * inset = getOpenInset(name);
+               if (inset) {
+                       FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
+                       FuncStatus fs;
+                       if (!inset->getStatus(view()->cursor(), fr, fs)) {
+                               // Every inset is supposed to handle this
+                               BOOST_ASSERT(false);
+                       }
+                       flag |= fs;
+               } else {
+                       FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
+                       flag |= getStatus(fr);
+               }
+               enable = flag.enabled();
+               break;
+       }
+
+       default:
+               if (!view()) {
+                       enable = false;
+                       break;
+               }
+       }
+
+       if (!enable)
+               flag.enabled(false);
+
+       return flag;
+}
+
+
+static FileName selectTemplateFile()
+{
+       FileDialog dlg(_("Select template file"));
+       dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
+       dlg.setButton1(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
+
+       FileDialog::Result result =
+               dlg.open(from_utf8(lyxrc.template_path),
+                            FileFilterList(_("LyX Documents (*.lyx)")),
+                            docstring());
+
+       if (result.first == FileDialog::Later)
+               return FileName();
+       if (result.second.empty())
+               return FileName();
+       return FileName(to_utf8(result.second));
+}
+
+
+void GuiView::newDocument(string const & filename, bool from_template)
+{
+       FileName initpath(lyxrc.document_path);
+       Buffer * buf = buffer();
+       if (buf) {
+               FileName const trypath(buf->filePath());
+               // If directory is writeable, use this as default.
+               if (trypath.isDirWritable())
+                       initpath = trypath;
+       }
+
+       string templatefile = from_template ?
+               selectTemplateFile().absFilename() : string();
+       Buffer * b;
+       if (filename.empty())
+               b = newUnnamedFile(templatefile, initpath);
+       else
+               b = newFile(filename, templatefile, true);
+
+       if (b)
+               setBuffer(b);
+       // Ensure the cursor is correctly positionned on screen.
+       view()->showCursor();
+}
+
+
+void GuiView::insertLyXFile(docstring const & fname)
+{
+       BufferView * bv = view();
+       if (!bv)
+               return;
+
+       // FIXME UNICODE
+       FileName filename(to_utf8(fname));
+       
+       if (!filename.empty()) {
+               bv->insertLyXFile(filename);
+               return;
+       }
+
+       // Launch a file browser
+       // FIXME UNICODE
+       string initpath = lyxrc.document_path;
+       string const trypath = bv->buffer().filePath();
+       // If directory is writeable, use this as default.
+       if (FileName(trypath).isDirWritable())
+               initpath = trypath;
+
+       // FIXME UNICODE
+       FileDialog dlg(_("Select LyX document to insert"), LFUN_FILE_INSERT);
+       dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
+       dlg.setButton2(_("Examples|#E#e"),
+               from_utf8(addPath(package().system_support().absFilename(),
+               "examples")));
+
+       FileDialog::Result result =
+               dlg.open(from_utf8(initpath),
+                            FileFilterList(_("LyX Documents (*.lyx)")),
+                            docstring());
+
+       if (result.first == FileDialog::Later)
+               return;
+
+       // FIXME UNICODE
+       filename.set(to_utf8(result.second));
+
+       // check selected filename
+       if (filename.empty()) {
+               // emit message signal.
+               message(_("Canceled."));
+               return;
+       }
+
+       bv->insertLyXFile(filename);
+}
+
+
+void GuiView::insertPlaintextFile(docstring const & fname,
+       bool asParagraph)
+{
+       BufferView * bv = view();
+       if (!bv)
+               return;
+
+       // FIXME UNICODE
+       FileName filename(to_utf8(fname));
+       
+       if (!filename.empty()) {
+               bv->insertPlaintextFile(filename, asParagraph);
+               return;
+       }
+
+       FileDialog dlg(_("Select file to insert"), (asParagraph ?
+               LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
+
+       FileDialog::Result result = dlg.open(from_utf8(bv->buffer().filePath()),
+               FileFilterList(), docstring());
+
+       if (result.first == FileDialog::Later)
+               return;
+
+       // FIXME UNICODE
+       filename.set(to_utf8(result.second));
+
+       // check selected filename
+       if (filename.empty()) {
+               // emit message signal.
+               message(_("Canceled."));
+               return;
+       }
+
+       bv->insertPlaintextFile(filename, asParagraph);
+}
+
+
+bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
+{
+       FileName fname = b.fileName();
+       FileName const oldname = fname;
+
+       if (!newname.empty()) {
+               // FIXME UNICODE
+               fname = makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename());
+       } else {
+               // Switch to this Buffer.
+               setBuffer(&b);
+
+               /// No argument? Ask user through dialog.
+               // FIXME UNICODE
+               FileDialog dlg(_("Choose a filename to save document as"),
+                                  LFUN_BUFFER_WRITE_AS);
+               dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
+               dlg.setButton2(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
+
+               if (!isLyXFilename(fname.absFilename()))
+                       fname.changeExtension(".lyx");
+
+               FileFilterList const filter(_("LyX Documents (*.lyx)"));
+
+               FileDialog::Result result =
+                       dlg.save(from_utf8(fname.onlyPath().absFilename()),
+                                    filter,
+                                    from_utf8(fname.onlyFileName()));
+
+               if (result.first == FileDialog::Later)
+                       return false;
+
+               fname.set(to_utf8(result.second));
+
+               if (fname.empty())
+                       return false;
+
+               if (!isLyXFilename(fname.absFilename()))
+                       fname.changeExtension(".lyx");
+       }
+
+       if (FileName(fname).exists()) {
+               docstring const file = makeDisplayPath(fname.absFilename(), 30);
+               docstring text = bformat(_("The document %1$s already "
+                                          "exists.\n\nDo you want to "
+                                          "overwrite that document?"), 
+                                        file);
+               int const ret = Alert::prompt(_("Overwrite document?"),
+                       text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
+               switch (ret) {
+               case 0: break;
+               case 1: return renameBuffer(b, docstring());
+               case 2: return false;
+               }
+       }
+
+       // Ok, change the name of the buffer
+       b.setFileName(fname.absFilename());
+       b.markDirty();
+       bool unnamed = b.isUnnamed();
+       b.setUnnamed(false);
+       b.saveCheckSum(fname);
+
+       if (!saveBuffer(b)) {
+               b.setFileName(oldname.absFilename());
+               b.setUnnamed(unnamed);
+               b.saveCheckSum(oldname);
+               return false;
+       }
+
+       return true;
+}
+
+
+bool GuiView::saveBuffer(Buffer & b)
+{
+       if (b.isUnnamed())
+               return renameBuffer(b, docstring());
+
+       if (b.save()) {
+               LyX::ref().session().lastFiles().add(b.fileName());
+               return true;
+       }
+
+       // Switch to this Buffer.
+       setBuffer(&b);
+
+       // FIXME: we don't tell the user *WHY* the save failed !!
+       docstring const file = makeDisplayPath(b.absFileName(), 30);
+       docstring text = bformat(_("The document %1$s could not be saved.\n\n"
+                                  "Do you want to rename the document and "
+                                  "try again?"), file);
+       int const ret = Alert::prompt(_("Rename and save?"),
+               text, 0, 2, _("&Rename"), _("&Retry"), _("&Cancel"));
+       switch (ret) {
+       case 0:
+               if (!renameBuffer(b, docstring()))
+                       return false;
+               break;
+       case 1:
+               return false;
+       case 2:
+               break;
+       }
+
+       return saveBuffer(b);
+}
+
+
+bool GuiView::closeBuffer()
+{
+       Buffer * buf = buffer();
+       return buf && closeBuffer(*buf);
+}
+
+
+bool GuiView::closeBuffer(Buffer & buf)
+{
+       if (buf.isClean() || buf.paragraphs().empty()) {
+               theBufferList().release(&buf);
+               return true;
+       }
+       // Switch to this Buffer.
+       setBuffer(&buf);
+
+       docstring file;
+       // FIXME: Unicode?
+       if (buf.isUnnamed())
+               file = from_utf8(buf.fileName().onlyFileName());
+       else
+               file = buf.fileName().displayName(30);
+
+       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"));
+
+       switch (ret) {
+       case 0:
+               if (!saveBuffer(buf))
+                       return false;
+               break;
+       case 1:
+               // if we crash after this we could
+               // have no autosave file but I guess
+               // this is really improbable (Jug)
+               removeAutosaveFile(buf.absFileName());
+               break;
+       case 2:
+               return false;
+       }
+
+       // 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)
+               LyX::ref().session().lastOpened().add(buf.fileName());
+
+       theBufferList().release(&buf);
+       return true;
 }
 
 
-void GuiView::dispatch(FuncRequest const & cmd)
+bool GuiView::quitWriteAll()
 {
+       while (!theBufferList().empty()) {
+               Buffer * b = theBufferList().first();
+               if (!closeBuffer(*b))
+                       return false;
+       }
+       return true;
+}
+
+
+bool GuiView::dispatch(FuncRequest const & cmd)
+{
+       BufferView * bv = view();       
+       // By default we won't need any update.
+       if (bv)
+               bv->cursor().updateFlags(Update::None);
+
        switch(cmd.action) {
                case LFUN_BUFFER_SWITCH:
                        setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
                        break;
 
+               case LFUN_BUFFER_NEXT:
+                       setBuffer(theBufferList().next(buffer()));
+                       break;
+
+               case LFUN_BUFFER_PREVIOUS:
+                       setBuffer(theBufferList().previous(buffer()));
+                       break;
+
                case LFUN_COMMAND_EXECUTE: {
                        bool const show_it = cmd.argument() != "off";
                        d.toolbars_->showCommandBuffer(show_it);
                        break;
                }
                case LFUN_DROP_LAYOUTS_CHOICE:
-                       d.toolbars_->openLayoutList();
+                       if (d.layout_)
+                               d.layout_->showPopup();
                        break;
 
                case LFUN_MENU_OPEN:
-                       d.menubar_->openByName(toqstr(cmd.argument()));
+                       if (QMenu * menu = guiApp->menus().menu(toqstr(cmd.argument())))
+                               menu->exec(QCursor::pos());
+                       break;
+
+               case LFUN_FILE_INSERT:
+                       insertLyXFile(cmd.argument());
+                       break;
+               case LFUN_FILE_INSERT_PLAINTEXT_PARA:
+                       insertPlaintextFile(cmd.argument(), true);
+                       break;
+
+               case LFUN_FILE_INSERT_PLAINTEXT:
+                       insertPlaintextFile(cmd.argument(), false);
+                       break;
+
+               case LFUN_BUFFER_WRITE:
+                       if (bv)
+                               saveBuffer(bv->buffer());
                        break;
 
+               case LFUN_BUFFER_WRITE_AS:
+                       if (bv)
+                               renameBuffer(bv->buffer(), cmd.argument());
+                       break;
+
+               case LFUN_BUFFER_WRITE_ALL: {
+                       Buffer * first = theBufferList().first();
+                       if (!first)
+                               break;
+                       message(_("Saving all documents..."));
+                       // We cannot use a for loop as the buffer list cycles.
+                       Buffer * b = first;
+                       do {
+                               if (b->isClean())
+                                       continue;
+                               saveBuffer(*b);
+                               LYXERR(Debug::ACTION, "Saved " << b->absFileName());
+                               b = theBufferList().next(b);
+                       } while (b != first); 
+                       message(_("All documents saved."));
+                       break;
+               }
+
                case LFUN_TOOLBAR_TOGGLE: {
                        string const name = cmd.getArg(0);
                        bool const allowauto = cmd.getArg(1) == "allowauto";
@@ -1051,10 +1448,88 @@ void GuiView::dispatch(FuncRequest const & cmd)
                        break;
                }
 
+               case LFUN_DIALOG_UPDATE: {
+                       string const name = to_utf8(cmd.argument());
+                       // Can only update a dialog connected to an existing inset
+                       Inset * inset = getOpenInset(name);
+                       if (inset) {
+                               FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
+                               inset->dispatch(view()->cursor(), fr);
+                       } else if (name == "paragraph") {
+                               lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
+                       } else if (name == "prefs") {
+                               updateDialog(name, string());
+                       }
+                       break;
+               }
+
+               case LFUN_DIALOG_TOGGLE: {
+                       if (isDialogVisible(cmd.getArg(0)))
+                               dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
+                       else
+                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
+                       break;
+               }
+
+               case LFUN_DIALOG_DISCONNECT_INSET:
+                       disconnectDialog(to_utf8(cmd.argument()));
+                       break;
+
+               case LFUN_DIALOG_HIDE: {
+                       if (quitting)
+                               break;
+                       guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
+                       break;
+               }
+
+               case LFUN_DIALOG_SHOW: {
+                       string const name = cmd.getArg(0);
+                       string data = trim(to_utf8(cmd.argument()).substr(name.size()));
+
+                       if (name == "character") {
+                               data = freefont2string();
+                               if (!data.empty())
+                                       showDialog("character", data);
+                       } else if (name == "latexlog") {
+                               Buffer::LogType type; 
+                               string const logfile = buffer()->logName(&type);
+                               switch (type) {
+                               case Buffer::latexlog:
+                                       data = "latex ";
+                                       break;
+                               case Buffer::buildlog:
+                                       data = "literate ";
+                                       break;
+                               }
+                               data += Lexer::quoteString(logfile);
+                               showDialog("log", data);
+                       } else if (name == "vclog") {
+                               string const data = "vc " +
+                                       Lexer::quoteString(buffer()->lyxvc().getLogFile());
+                               showDialog("log", data);
+                       } else
+                               showDialog(name, data);
+                       break;
+               }
+
+               case LFUN_INSET_APPLY: {
+                       string const name = cmd.getArg(0);
+                       Inset * inset = getOpenInset(name);
+                       if (inset) {
+                               FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
+                               inset->dispatch(view()->cursor(), fr);
+                       } else {
+                               FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
+                               lyx::dispatch(fr);
+                       }
+                       break;
+               }
+
                default:
-                       theLyXFunc().setLyXView(this);
-                       lyx::dispatch(cmd);
+                       return false;
        }
+
+       return true;
 }
 
 
@@ -1077,6 +1552,65 @@ void GuiView::restartCursor()
         */
        if (d.current_work_area_)
                d.current_work_area_->startBlinkingCursor();
+
+       // Take this occasion to update the toobars and layout list.
+       updateLayoutList();
+       updateToolbars();
+}
+
+namespace {
+
+// This list should be kept in sync with the list of insets in
+// src/insets/Inset.cpp.  I.e., if a dialog goes with an inset, the
+// dialog should have the same name as the inset.
+
+char const * const dialognames[] = {
+"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
+"citation", "document", "embedding", "errorlist", "ert", "external", "file",
+"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
+"mathdelimiter", "mathmatrix", "note", "paragraph",
+"prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate",
+
+#ifdef HAVE_LIBAIKSAURUS
+"thesaurus",
+#endif
+
+"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
+
+char const * const * const end_dialognames =
+       dialognames + (sizeof(dialognames) / sizeof(char *));
+
+class cmpCStr {
+public:
+       cmpCStr(char const * name) : name_(name) {}
+       bool operator()(char const * other) {
+               return strcmp(other, name_) == 0;
+       }
+private:
+       char const * name_;
+};
+
+
+bool isValidName(string const & name)
+{
+       return find_if(dialognames, end_dialognames,
+                           cmpCStr(name.c_str())) != end_dialognames;
+}
+
+} // namespace anon
+
+
+void GuiView::resetDialogs()
+{
+       // Make sure that no LFUN uses any LyXView.
+       theLyXFunc().setLyXView(0);
+       d.toolbars_->init();
+       guiApp->menus().fillMenuBar(this);
+       if (d.layout_)
+               d.layout_->updateContents(true);
+       // Now update controls with current buffer.
+       theLyXFunc().setLyXView(this);
+       restartCursor();
 }
 
 
@@ -1085,13 +1619,16 @@ Dialog * GuiView::find_or_build(string const & name)
        if (!isValidName(name))
                return 0;
 
-       std::map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
+       map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
 
        if (it != d.dialogs_.end())
                return it->second.get();
 
-       d.dialogs_[name].reset(build(name));
-       return d.dialogs_[name].get();
+       Dialog * dialog = build(name);
+       d.dialogs_[name].reset(dialog);
+       if (lyxrc.allow_geometry_session)
+               dialog->restoreSession();
+       return dialog;
 }
 
 
@@ -1114,7 +1651,7 @@ void GuiView::showDialog(string const & name, string const & data,
 
 bool GuiView::isDialogVisible(string const & name) const
 {
-       std::map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
+       map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
        if (it == d.dialogs_.end())
                return false;
        return it->second.get()->isVisibleView();
@@ -1130,7 +1667,7 @@ void GuiView::hideDialog(string const & name, Inset * inset)
        if (quitting)
                return;
 
-       std::map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
+       map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
        if (it == d.dialogs_.end())
                return;
 
@@ -1139,7 +1676,7 @@ void GuiView::hideDialog(string const & name, Inset * inset)
 
        Dialog * const dialog = it->second.get();
        if (dialog->isVisibleView())
-               dialog->hide();
+               dialog->hideView();
        d.open_insets_[name] = 0;
 }
 
@@ -1159,70 +1696,62 @@ Inset * GuiView::getOpenInset(string const & name) const
        if (!isValidName(name))
                return 0;
 
-       std::map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
+       map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
        return it == d.open_insets_.end() ? 0 : it->second;
 }
 
 
 void GuiView::hideAll() const
 {
-       std::map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       std::map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
+       map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
+       map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
 
        for(; it != end; ++it)
-               it->second->hide();
+               it->second->hideView();
 }
 
 
 void GuiView::hideBufferDependent() const
 {
-       std::map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       std::map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
+       map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
+       map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
 
        for(; it != end; ++it) {
                Dialog * dialog = it->second.get();
                if (dialog->isBufferDependent())
-                       dialog->hide();
+                       dialog->hideView();
        }
 }
 
 
 void GuiView::updateBufferDependent(bool switched) const
 {
-       std::map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       std::map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
+       map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
+       map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
 
        for(; it != end; ++it) {
                Dialog * dialog = it->second.get();
+               if (!dialog->isVisibleView())
+                       continue;
                if (switched && dialog->isBufferDependent()) {
-                       if (dialog->isVisibleView() && dialog->initialiseParams(""))
+                       if (dialog->initialiseParams(""))
                                dialog->updateView();
                        else
-                               dialog->hide();
+                               dialog->hideView();
                } else {
                        // A bit clunky, but the dialog will request
                        // that the kernel provides it with the necessary
                        // data.
-                       dialog->slotRestore();
+                       dialog->updateDialog();
                }
        }
 }
 
 
-void GuiView::redrawDialog() const
-{
-       std::map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       std::map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
-
-       for(; it != end; ++it)
-               it->second->redraw();
-}
-
-
 void GuiView::checkStatus()
 {
-       std::map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
-       std::map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
+       map<string, DialogPtr>::const_iterator it  = d.dialogs_.begin();
+       map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
 
        for(; it != end; ++it) {
                Dialog * const dialog = it->second.get();
@@ -1232,89 +1761,48 @@ void GuiView::checkStatus()
 }
 
 
-namespace {
-
-// This list should be kept in sync with the list of insets in
-// src/insets/Inset.cpp.  I.e., if a dialog goes with an inset, the
-// dialog should have the same name as the inset.
-
-char const * const dialognames[] = {
-"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
-"citation", "document", "embedding", "errorlist", "ert", "external", "file",
-"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
-"mathdelimiter", "mathmatrix", "note", "paragraph",
-"prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate",
-
-#ifdef HAVE_LIBAIKSAURUS
-"thesaurus",
-#endif
-
-"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
-
-char const * const * const end_dialognames =
-       dialognames + (sizeof(dialognames) / sizeof(char *));
-
-class cmpCStr {
-public:
-       cmpCStr(char const * name) : name_(name) {}
-       bool operator()(char const * other) {
-               return strcmp(other, name_) == 0;
-       }
-private:
-       char const * name_;
-};
-
-
-} // namespace anon
 
 // will be replaced by a proper factory...
-Dialog * createGuiAbout(LyXView & lv);
-Dialog * createGuiBibitem(LyXView & lv);
-Dialog * createGuiBibtex(LyXView & lv);
-Dialog * createGuiBox(LyXView & lv);
-Dialog * createGuiBranch(LyXView & lv);
-Dialog * createGuiChanges(LyXView & lv);
-Dialog * createGuiCharacter(LyXView & lv);
-Dialog * createGuiCitation(LyXView & lv);
-Dialog * createGuiDelimiter(LyXView & lv);
-Dialog * createGuiDocument(LyXView & lv);
-Dialog * createGuiErrorList(LyXView & lv);
-Dialog * createGuiERT(LyXView & lv);
-Dialog * createGuiExternal(LyXView & lv);
-Dialog * createGuiFloat(LyXView & lv);
-Dialog * createGuiGraphics(LyXView & lv);
-Dialog * createGuiInclude(LyXView & lv);
-Dialog * createGuiIndex(LyXView & lv);
-Dialog * createGuiLabel(LyXView & lv);
-Dialog * createGuiListings(LyXView & lv);
-Dialog * createGuiLog(LyXView & lv);
-Dialog * createGuiMathMatrix(LyXView & lv);
-Dialog * createGuiNomenclature(LyXView & lv);
-Dialog * createGuiNote(LyXView & lv);
-Dialog * createGuiParagraph(LyXView & lv);
-Dialog * createGuiPreferences(LyXView & lv);
-Dialog * createGuiPrint(LyXView & lv);
-Dialog * createGuiRef(LyXView & lv);
-Dialog * createGuiSearch(LyXView & lv);
-Dialog * createGuiSendTo(LyXView & lv);
-Dialog * createGuiShowFile(LyXView & lv);
-Dialog * createGuiSpellchecker(LyXView & lv);
-Dialog * createGuiTabularCreate(LyXView & lv);
-Dialog * createGuiTabular(LyXView & lv);
-Dialog * createGuiTexInfo(LyXView & lv);
-Dialog * createGuiToc(LyXView & lv);
-Dialog * createGuiThesaurus(LyXView & lv);
-Dialog * createGuiHyperlink(LyXView & lv);
-Dialog * createGuiVSpace(LyXView & lv);
-Dialog * createGuiViewSource(LyXView & lv);
-Dialog * createGuiWrap(LyXView & lv);
-
-
-bool GuiView::isValidName(string const & name) const
-{
-       return std::find_if(dialognames, end_dialognames,
-                           cmpCStr(name.c_str())) != end_dialognames;
-}
+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);
+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 * createGuiLabel(GuiView & lv);
+Dialog * createGuiListings(GuiView & lv);
+Dialog * createGuiLog(GuiView & lv);
+Dialog * createGuiMathMatrix(GuiView & lv);
+Dialog * createGuiNomenclature(GuiView & lv);
+Dialog * createGuiNote(GuiView & lv);
+Dialog * createGuiParagraph(GuiView & lv);
+Dialog * createGuiPreferences(GuiView & lv);
+Dialog * createGuiPrint(GuiView & lv);
+Dialog * createGuiRef(GuiView & lv);
+Dialog * createGuiSearch(GuiView & lv);
+Dialog * createGuiSendTo(GuiView & lv);
+Dialog * createGuiShowFile(GuiView & lv);
+Dialog * createGuiSpellchecker(GuiView & lv);
+Dialog * createGuiTabularCreate(GuiView & lv);
+Dialog * createGuiTabular(GuiView & lv);
+Dialog * createGuiTexInfo(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 * GuiView::build(string const & name)