X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiView.cpp;h=569de58926a42788028d0e627c962fd9ef35efc1;hb=d3312032eeea9a682840e3a6b6a762cb4adec729;hp=72eead693b218f067e95e58529fdd739174c4d59;hpb=a9fd4f4f952f5998ba4fdee23c55458f618d0c79;p=lyx.git diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 72eead693b..569de58926 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -16,15 +16,16 @@ #include "GuiView.h" #include "Dialog.h" +#include "DispatchResult.h" #include "FileDialog.h" #include "FontLoader.h" #include "GuiApplication.h" #include "GuiCommandBuffer.h" #include "GuiCompleter.h" -#include "GuiWorkArea.h" #include "GuiKeySymbol.h" #include "GuiToc.h" #include "GuiToolbar.h" +#include "GuiWorkArea.h" #include "LayoutBox.h" #include "Menus.h" #include "TocModel.h" @@ -38,6 +39,7 @@ #include "BufferList.h" #include "BufferParams.h" #include "BufferView.h" +#include "Compare.h" #include "Converter.h" #include "Cursor.h" #include "CutAndPaste.h" @@ -50,12 +52,12 @@ #include "Layout.h" #include "Lexer.h" #include "LyXAction.h" -#include "LyXFunc.h" #include "LyX.h" #include "LyXRC.h" #include "LyXVC.h" #include "Paragraph.h" #include "SpellChecker.h" +#include "TexRow.h" #include "TextClass.h" #include "Text.h" #include "Toolbars.h" @@ -105,9 +107,10 @@ #include #include -#define EXPORT_in_THREAD 1 +#define EXPORT_in_THREAD 1 + // QtConcurrent was introduced in Qt 4.4 #if (QT_VERSION >= 0x040400) #include @@ -115,7 +118,7 @@ #include #endif -#include +#include "support/bind.h" #include @@ -140,6 +143,8 @@ public: BackgroundWidget() { LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner); + if (!lyxrc.show_banner) + return; /// The text to be written on top of the pixmap QString const text = lyx_version ? qt_("version ") + lyx_version : qt_("unknown version"); @@ -152,8 +157,10 @@ public: font.setStyleHint(QFont::SansSerif); font.setWeight(QFont::Bold); font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble())); + int width = QFontMetrics(font).width(text); pain.setFont(font); - pain.drawText(260, 15, text); + pain.drawText(397 - width, 15, text); + setFocusPolicy(Qt::StrongFocus); } void paintEvent(QPaintEvent *) @@ -164,6 +171,18 @@ public: pain.drawPixmap(x, y, splash_); } + void keyPressEvent(QKeyEvent * ev) + { + KeySymbol sym; + setKeySymbol(&sym, ev); + if (sym.isOK()) { + guiApp->processKeySym(sym, q_key_state(ev->modifiers())); + ev->accept(); + } else { + ev->ignore(); + } + } + private: QPixmap splash_; }; @@ -172,7 +191,7 @@ private: /// Toolbar store providing access to individual toolbars by name. typedef map ToolbarMap; -typedef boost::shared_ptr DialogPtr; +typedef shared_ptr DialogPtr; } // namespace anon @@ -187,7 +206,7 @@ struct GuiView::GuiViewPrivate // hardcode here the platform specific icon size smallIconSize = 14; // scaling problems normalIconSize = 20; // ok, default - bigIconSize = 26; // better for some math icons + bigIconSize = 26; // better for some math icons splitter_ = new QSplitter; bg_widget_ = new BackgroundWidget; @@ -195,7 +214,21 @@ struct GuiView::GuiViewPrivate stack_widget_->addWidget(bg_widget_); stack_widget_->addWidget(splitter_); setBackground(); - progress_ = new GuiProgress(gv); + + // TODO cleanup, remove the singleton, handle multiple Windows? + progress_ = ProgressInterface::instance(); + if (!dynamic_cast(progress_)) { + progress_ = new GuiProgress(); // TODO who deletes it + ProgressInterface::setInstance(progress_); + } + QObject::connect( + dynamic_cast(progress_), + SIGNAL(updateStatusBarMessage(QString const&)), + gv, SLOT(updateStatusBarMessage(QString const&))); + QObject::connect( + dynamic_cast(progress_), + SIGNAL(clearMessageText()), + gv, SLOT(clearMessageText())); } ~GuiViewPrivate() @@ -203,7 +236,6 @@ struct GuiView::GuiViewPrivate delete splitter_; delete bg_widget_; delete stack_widget_; - delete progress_; } QMenu * toolBarPopup(GuiView * parent) @@ -248,6 +280,7 @@ struct GuiView::GuiViewPrivate { stack_widget_->setCurrentWidget(bg_widget_); bg_widget_->setUpdatesEnabled(true); + bg_widget_->setFocus(); } TabWorkArea * tabWorkArea(int i) @@ -294,7 +327,7 @@ public: ToolbarMap toolbars_; ProgressInterface* progress_; /// 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. @@ -324,12 +357,22 @@ public: /// QFutureWatcher autosave_watcher_; QFutureWatcher preview_watcher_; + /// + string last_export_format; #else - struct DummyWatcher { bool isRunning(){return false;} }; + struct DummyWatcher { bool isRunning(){return false;} }; DummyWatcher preview_watcher_; #endif + + static QSet busyBuffers; + static docstring previewAndDestroy(Buffer const * orig, Buffer * buffer, string const & format); + static docstring exportAndDestroy(Buffer const * orig, Buffer * buffer, string const & format); + static docstring saveAndDestroy(Buffer const * orig, Buffer * buffer, FileName const & fname); + }; +QSet GuiView::GuiViewPrivate::busyBuffers; + GuiView::GuiView(int id) : d(*new GuiViewPrivate(this)), id_(id), closing_(false) @@ -342,7 +385,7 @@ GuiView::GuiView(int id) // filling, at least for the static special menu item on Mac. Otherwise // they are greyed out. guiApp->setCurrentView(this); - + // Fill up the menu bar. guiApp->menus().fillMenuBar(menuBar(), this, true); @@ -350,7 +393,7 @@ GuiView::GuiView(int id) // Start autosave timer if (lyxrc.autosave) { - d.autosave_timeout_.timeout.connect(boost::bind(&GuiView::autoSave, this)); + d.autosave_timeout_.timeout.connect(bind(&GuiView::autoSave, this)); d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000); d.autosave_timeout_.start(); } @@ -366,6 +409,12 @@ GuiView::GuiView(int id) setWindowIcon(getPixmap("images/", "lyx", "png")); #endif +#if (QT_VERSION >= 0x040300) + // use tabbed dock area for multiple docks + // (such as "source" and "messages") + setDockOptions(QMainWindow::ForceTabbedDocks); +#endif + // For Drag&Drop. setAcceptDrops(true); @@ -414,6 +463,8 @@ void GuiView::threadFinished() QFutureWatcher const * watcher = static_cast const *>(sender()); message(watcher->result()); + updateToolbars(); + errors(d.last_export_format); #endif } @@ -486,7 +537,6 @@ GuiToolbar * GuiView::toolbar(string const & name) return it->second; LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name); - message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name))); return 0; } @@ -522,7 +572,7 @@ void GuiView::initToolbars() if (!tb) continue; int const visibility = guiApp->toolbars().defaultVisibility(cit->name); - bool newline = true; + bool newline = !(visibility & Toolbars::SAMEROW); tb->setVisible(false); tb->setVisibility(visibility); @@ -535,7 +585,8 @@ void GuiView::initToolbars() if (visibility & Toolbars::BOTTOM) { // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock. #if (QT_VERSION >= 0x040202) - addToolBarBreak(Qt::BottomToolBarArea); + if (newline) + addToolBarBreak(Qt::BottomToolBarArea); #endif addToolBar(Qt::BottomToolBarArea, tb); } @@ -543,7 +594,8 @@ void GuiView::initToolbars() if (visibility & Toolbars::LEFT) { // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock. #if (QT_VERSION >= 0x040202) - addToolBarBreak(Qt::LeftToolBarArea); + if (newline) + addToolBarBreak(Qt::LeftToolBarArea); #endif addToolBar(Qt::LeftToolBarArea, tb); } @@ -551,7 +603,8 @@ void GuiView::initToolbars() if (visibility & Toolbars::RIGHT) { // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock. #if (QT_VERSION >= 0x040202) - addToolBarBreak(Qt::RightToolBarArea); + if (newline) + addToolBarBreak(Qt::RightToolBarArea); #endif addToolBar(Qt::RightToolBarArea, tb); } @@ -571,11 +624,22 @@ TocModels & GuiView::tocModels() void GuiView::setFocus() { LYXERR(Debug::DEBUG, "GuiView::setFocus()" << this); - // Make sure LyXFunc points to the correct view. - guiApp->setCurrentView(this); QMainWindow::setFocus(); - if (d.current_work_area_) - d.current_work_area_->setFocus(); +} + + +void GuiView::focusInEvent(QFocusEvent * e) +{ + LYXERR(Debug::DEBUG, "GuiView::focusInEvent()" << this); + QMainWindow::focusInEvent(e); + // Make sure guiApp points to the correct view. + guiApp->setCurrentView(this); + if (currentMainWorkArea()) + currentMainWorkArea()->setFocus(); + else if (currentWorkArea()) + currentWorkArea()->setFocus(); + else + d.bg_widget_->setFocus(); } @@ -599,12 +663,30 @@ void GuiView::showEvent(QShowEvent * e) } +bool GuiView::closeScheduled() +{ + closing_ = true; + return close(); +} + + /** 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()"); + + if (!GuiViewPrivate::busyBuffers.isEmpty()) { + Alert::warning(_("Exit LyX"), _("LyX could not be closed because documents are processed by LyX.")); + close_event->setAccepted(false); + return; + } + + // If the user pressed the x (so we didn't call closeView + // programmatically), we want to clear all existing entries. + if (!closing_) + theSession().lastOpened().clear(); closing_ = true; writeSession(); @@ -676,7 +758,7 @@ void GuiView::dropEvent(QDropEvent * event) vector found_formats; // Find all formats that have the correct extension. - vector const & import_formats + vector const & import_formats = theConverters().importableFormats(); vector::const_iterator it = import_formats.begin(); for (; it != import_formats.end(); ++it) @@ -692,7 +774,7 @@ void GuiView::dropEvent(QDropEvent * event) } string const arg = found_formats[0]->name() + " " + file; cmd = FuncRequest(LFUN_BUFFER_IMPORT, arg); - } + } else { //FIXME: do we have to explicitly check whether it's a lyx file? LYXERR(Debug::FILES, @@ -713,13 +795,19 @@ void GuiView::message(docstring const & str) { if (ForkedProcess::iAmAChild()) return; - + // call is moved to GUI-thread by GuiProgress d.progress_->appendMessage(toqstr(str)); } -void GuiView::updateMessage(QString const & str) +void GuiView::clearMessageText() +{ + message(docstring()); +} + + +void GuiView::updateStatusBarMessage(QString const & str) { statusBar()->showMessage(str); d.statusbar_timer_.stop(); @@ -759,7 +847,8 @@ void GuiView::clearMessage() void GuiView::updateWindowTitle(GuiWorkArea * wa) { - if (wa != d.current_work_area_) + if (wa != d.current_work_area_ + || wa->bufferView().buffer().isInternal()) return; setWindowTitle(qt_("LyX: ") + wa->windowTitle()); setWindowIconText(wa->windowIconText()); @@ -912,25 +1001,7 @@ bool GuiView::event(QEvent * e) } } #endif - - if (d.current_work_area_) - // Nothing special to do. - return QMainWindow::event(e); - - QKeyEvent * ke = static_cast(e); - // Let Qt handle menu access and the Tab keys to navigate keys to navigate - // between controls. - if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab - || ke->key() == Qt::Key_Backtab) - return QMainWindow::event(e); - - // Allow processing of shortcuts that are allowed even when no Buffer - // is viewed. - KeySymbol sym; - setKeySymbol(&sym, ke); - guiApp->processKeySym(sym, q_key_state(ke->modifiers())); - e->accept(); - return true; + return QMainWindow::event(e); } default: @@ -940,8 +1011,8 @@ bool GuiView::event(QEvent * e) void GuiView::resetWindowTitleAndIconText() { - setWindowTitle(qt_("LyX")); - setWindowIconText(qt_("LyX")); + setWindowTitle(qt_("LyX")); + setWindowIconText(qt_("LyX")); } bool GuiView::focusNextPrevChild(bool /*next*/) @@ -951,8 +1022,15 @@ bool GuiView::focusNextPrevChild(bool /*next*/) } +bool GuiView::busy() const +{ + return busy_; +} + + void GuiView::setBusy(bool busy) { + busy_ = busy; if (d.current_work_area_) { d.current_work_area_->setUpdatesEnabled(!busy); if (busy) @@ -971,7 +1049,7 @@ void GuiView::setBusy(bool busy) GuiWorkArea * GuiView::workArea(Buffer & buffer) { if (currentWorkArea() - && ¤tWorkArea()->bufferView().buffer() == &buffer) + && ¤tWorkArea()->bufferView().buffer() == &buffer) return (GuiWorkArea *) currentWorkArea(); if (TabWorkArea * twa = d.currentTabWorkArea()) return twa->workArea(buffer); @@ -982,7 +1060,7 @@ GuiWorkArea * GuiView::workArea(Buffer & buffer) GuiWorkArea * GuiView::addWorkArea(Buffer & buffer) { // Automatically create a TabWorkArea if there are none yet. - TabWorkArea * tab_widget = d.splitter_->count() + TabWorkArea * tab_widget = d.splitter_->count() ? d.currentTabWorkArea() : addTabWorkArea(); return tab_widget->addWorkArea(buffer, *this); } @@ -1016,16 +1094,16 @@ GuiWorkArea * GuiView::currentWorkArea() GuiWorkArea const * GuiView::currentMainWorkArea() const { - if (d.currentTabWorkArea() == NULL) - return NULL; + if (!d.currentTabWorkArea()) + return 0; return d.currentTabWorkArea()->currentWorkArea(); } GuiWorkArea * GuiView::currentMainWorkArea() { - if (d.currentTabWorkArea() == NULL) - return NULL; + if (!d.currentTabWorkArea()) + return 0; return d.currentTabWorkArea()->currentWorkArea(); } @@ -1033,13 +1111,17 @@ GuiWorkArea * GuiView::currentMainWorkArea() void GuiView::setCurrentWorkArea(GuiWorkArea * wa) { LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl); - if (wa == NULL) { - d.current_work_area_ = NULL; + if (!wa) { + d.current_work_area_ = 0; d.setBackground(); return; } - GuiWorkArea * old_gwa = theGuiApp()->currentView()->currentWorkArea(); - if (old_gwa == wa) + + // FIXME: I've no clue why this is here and why it accesses + // theGuiApp()->currentView, which might be 0 (bug 6464). + // See also 27525 (vfr). + if (theGuiApp()->currentView() == this + && theGuiApp()->currentView()->currentWorkArea() == wa) return; if (currentBufferView()) @@ -1131,12 +1213,13 @@ void GuiView::updateToolbars() ToolbarMap::iterator end = d.toolbars_.end(); if (d.current_work_area_) { bool const math = - d.current_work_area_->bufferView().cursor().inMathed(); + d.current_work_area_->bufferView().cursor().inMathed() + && !d.current_work_area_->bufferView().cursor().inRegexped(); bool const table = lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled(); bool const review = lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() && - lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true); + lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onOff(true); bool const mathmacrotemplate = lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled(); @@ -1156,7 +1239,7 @@ void GuiView::setBuffer(Buffer * newBuffer) GuiWorkArea * wa = workArea(*newBuffer); if (wa == 0) { - newBuffer->masterBuffer()->updateLabels(); + newBuffer->masterBuffer()->updateBuffer(); wa = addWorkArea(*newBuffer); } else { //Disconnect the old buffer...there's no new one. @@ -1198,9 +1281,9 @@ void GuiView::disconnectBufferView() void GuiView::errors(string const & error_type, bool from_master) { - ErrorList & el = from_master ? - documentBufferView()->buffer().masterBuffer()->errorList(error_type) - : documentBufferView()->buffer().errorList(error_type); + ErrorList & el = from_master ? + currentBufferView()->buffer().masterBuffer()->errorList(error_type) + : currentBufferView()->buffer().errorList(error_type); string data = error_type; if (from_master) data = "from_master|" + error_type; @@ -1247,7 +1330,7 @@ BufferView * GuiView::documentBufferView() } -BufferView const * GuiView::documentBufferView() const +BufferView const * GuiView::documentBufferView() const { return currentMainWorkArea() ? ¤tMainWorkArea()->bufferView() @@ -1267,7 +1350,8 @@ BufferView const * GuiView::currentBufferView() const } -static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname) +#if (QT_VERSION >= 0x040400) +docstring GuiView::GuiViewPrivate::saveAndDestroy(Buffer const * orig, Buffer * buffer, FileName const & fname) { bool failed = true; FileName const tmp_ret = FileName::tempName("lyxauto"); @@ -1280,10 +1364,12 @@ static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname) failed = buffer->writeFile(fname); } delete buffer; + busyBuffers.remove(orig); return failed ? _("Automatic save failed!") : _("Automatic save done."); } +#endif void GuiView::autoSave() @@ -1296,8 +1382,9 @@ void GuiView::autoSave() return; #if (QT_VERSION >= 0x040400) - QFuture f = QtConcurrent::run(saveAndDestroyBuffer, buffer->clone(), - buffer->getAutosaveFilename()); + GuiViewPrivate::busyBuffers.insert(buffer); + QFuture f = QtConcurrent::run(GuiViewPrivate::saveAndDestroy, buffer, buffer->clone(), + buffer->getAutosaveFileName()); d.autosave_watcher_.setFuture(f); #else buffer->autoSave(); @@ -1321,30 +1408,27 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) ? &(documentBufferView()->buffer()) : 0; // Check whether we need a buffer - if (!lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !buf) { + if (!lyxaction.funcHasFlag(cmd.action(), LyXAction::NoBuffer) && !buf) { // no, exit directly flag.message(from_utf8(N_("Command not allowed with" - "out any document open"))); + "out any document open"))); flag.setEnabled(false); return true; } - if (cmd.origin == FuncRequest::TOC) { + if (cmd.origin() == FuncRequest::TOC) { GuiToc * toc = static_cast(findOrBuild("toc", false)); - FuncStatus fs; - if (toc->getStatus(documentBufferView()->cursor(), cmd, fs)) - flag |= fs; - else + if (!toc || !toc->getStatus(documentBufferView()->cursor(), cmd, flag)) flag.setEnabled(false); return true; } - switch(cmd.action) { + switch(cmd.action()) { case LFUN_BUFFER_IMPORT: break; case LFUN_MASTER_BUFFER_UPDATE: - case LFUN_MASTER_BUFFER_VIEW: + case LFUN_MASTER_BUFFER_VIEW: enable = doc_buffer && doc_buffer->parent() != 0 && !d.preview_watcher_.isRunning(); break; @@ -1392,7 +1476,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } b = theBufferList().next(b); - } while (b != first); + } while (b != first); break; } @@ -1421,13 +1505,21 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = d.currentTabWorkArea(); break; - case LFUN_TOOLBAR_TOGGLE: - if (GuiToolbar * t = toolbar(cmd.getArg(0))) + case LFUN_TOOLBAR_TOGGLE: { + string const name = cmd.getArg(0); + if (GuiToolbar * t = toolbar(name)) flag.setOnOff(t->isVisible()); + else { + enable = false; + docstring const msg = + bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)); + flag.message(msg); + } break; + } case LFUN_DROP_LAYOUTS_CHOICE: - enable = buf; + enable = buf; break; case LFUN_UI_TOGGLE: @@ -1457,8 +1549,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = doc_buffer->isExportable("dvi") && lyxrc.print_command != "none"; else if (name == "character" || name == "symbols") { - if (!buf || buf->isReadonly() - || !currentBufferView()->cursor().inTexted()) + if (!buf || buf->isReadonly()) enable = false; else { // FIXME we should consider passthru @@ -1491,28 +1582,28 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_COMPLETION_INLINE: if (!d.current_work_area_ - || !d.current_work_area_->completer().inlinePossible( + || !d.current_work_area_->completer().inlinePossible( currentBufferView()->cursor())) - enable = false; + enable = false; break; case LFUN_COMPLETION_POPUP: if (!d.current_work_area_ - || !d.current_work_area_->completer().popupPossible( + || !d.current_work_area_->completer().popupPossible( currentBufferView()->cursor())) - enable = false; + enable = false; break; case LFUN_COMPLETION_COMPLETE: if (!d.current_work_area_ || !d.current_work_area_->completer().inlinePossible( currentBufferView()->cursor())) - enable = false; + enable = false; break; case LFUN_COMPLETION_ACCEPT: if (!d.current_work_area_ - || (!d.current_work_area_->completer().popupVisible() + || (!d.current_work_area_->completer().popupVisible() && !d.current_work_area_->completer().inlineVisible() && !d.current_work_area_->completer().completionAvailable())) enable = false; @@ -1520,7 +1611,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_COMPLETION_CANCEL: if (!d.current_work_area_ - || (!d.current_work_area_->completer().popupVisible() + || (!d.current_work_area_->completer().popupVisible() && !d.current_work_area_->completer().inlineVisible())) enable = false; break; @@ -1532,7 +1623,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_BUFFER_ZOOM_IN: enable = doc_buffer; break; - + case LFUN_BUFFER_NEXT: case LFUN_BUFFER_PREVIOUS: // FIXME: should we check is there is an previous or next buffer? @@ -1557,16 +1648,16 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_VC_LOCKING_TOGGLE: enable = doc_buffer && !doc_buffer->isReadonly() && doc_buffer->lyxvc().lockingToggleEnabled(); - flag.setOnOff(enable && !doc_buffer->lyxvc().locker().empty()); + flag.setOnOff(enable && doc_buffer->lyxvc().locking()); break; case LFUN_VC_REVERT: - enable = doc_buffer && doc_buffer->lyxvc().inUse(); + enable = doc_buffer && doc_buffer->lyxvc().inUse() && !doc_buffer->isReadonly(); break; case LFUN_VC_UNDO_LAST: enable = doc_buffer && doc_buffer->lyxvc().undoLastEnabled(); break; case LFUN_VC_REPO_UPDATE: - enable = doc_buffer && doc_buffer->lyxvc().inUse(); + enable = doc_buffer && doc_buffer->lyxvc().repoUpdateEnabled(); break; case LFUN_VC_COMMAND: { if (cmd.argument().empty()) @@ -1575,9 +1666,15 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = false; break; } + case LFUN_VC_COMPARE: + enable = doc_buffer && doc_buffer->lyxvc().prepareFileRevisionEnabled(); + break; case LFUN_SERVER_GOTO_FILE_ROW: break; + case LFUN_FORWARD_SEARCH: + enable = !(lyxrc.forward_search_dvi.empty() && lyxrc.forward_search_pdf.empty()); + break; default: return false; @@ -1594,10 +1691,10 @@ static FileName selectTemplateFile() { FileDialog dlg(qt_("Select template file")); dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); - dlg.setButton1(qt_("Templates|#T#t"), toqstr(lyxrc.template_path)); + dlg.setButton2(qt_("Templates|#T#t"), toqstr(lyxrc.template_path)); FileDialog::Result result = dlg.open(toqstr(lyxrc.template_path), - QStringList(qt_("LyX Documents (*.lyx)"))); + QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) return FileName(); @@ -1618,7 +1715,7 @@ Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles) setBusy(false); return 0; } - + setBuffer(newBuffer); // scroll to the position when the file was last closed @@ -1653,7 +1750,7 @@ void GuiView::openDocument(string const & fname) FileDialog dlg(qt_("Select document to open"), LFUN_FILE_OPEN); dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); dlg.setButton2(qt_("Examples|#E#e"), - toqstr(addPath(package().system_support().absFilename(), "examples"))); + toqstr(addPath(package().system_support().absFileName(), "examples"))); QStringList filter(qt_("LyX Documents (*.lyx)")); filter << qt_("LyX-1.3.x Documents (*.lyx13)") @@ -1677,20 +1774,22 @@ void GuiView::openDocument(string const & fname) filename = fname; // get absolute path of file and add ".lyx" to the filename if - // necessary. - FileName const fullname = + // necessary. + FileName const fullname = fileSearch(string(), filename, "lyx", support::may_not_exist); if (!fullname.empty()) - filename = fullname.absFilename(); + filename = fullname.absFileName(); if (!fullname.onlyPath().isDirectory()) { Alert::warning(_("Invalid filename"), bformat(_("The directory in the given path\n%1$s\ndoes not exist."), - from_utf8(fullname.absFilename()))); + from_utf8(fullname.absFileName()))); return; } - // if the file doesn't exist, let the user create one - if (!fullname.exists()) { + + // if the file doesn't exist and isn't already open (bug 6645), + // let the user create one + if (!fullname.exists() && !theBufferList().exists(fullname)) { // the user specifically chose this name. Believe him. Buffer * const b = newFile(filename, string(), true); if (b) @@ -1704,7 +1803,8 @@ void GuiView::openDocument(string const & fname) docstring str2; Buffer * buf = loadDocument(fullname); if (buf) { - buf->updateLabels(); + // I don't think this is needed, since it will be done in setBuffer(). + // buf->updateBuffer(); setBuffer(buf); buf->errors("Parse"); str2 = bformat(_("Document %1$s opened."), disp_fn); @@ -1721,18 +1821,18 @@ void GuiView::openDocument(string const & fname) static bool import(GuiView * lv, FileName const & filename, string const & format, ErrorList & errorList) { - FileName const lyxfile(support::changeExtension(filename.absFilename(), ".lyx")); + FileName const lyxfile(support::changeExtension(filename.absFileName(), ".lyx")); string loader_format; vector loaders = theConverters().loaders(); if (find(loaders.begin(), loaders.end(), format) == loaders.end()) { for (vector::const_iterator it = loaders.begin(); - it != loaders.end(); ++it) { + it != loaders.end(); ++it) { if (!theConverters().isReachable(format, *it)) continue; string const tofile = - support::changeExtension(filename.absFilename(), + support::changeExtension(filename.absFileName(), formats.extension(*it)); if (!theConverters().convert(0, filename, FileName(tofile), filename, format, *it, errorList)) @@ -1742,7 +1842,7 @@ static bool import(GuiView * lv, FileName const & filename, } if (loader_format.empty()) { frontend::Alert::error(_("Couldn't import file"), - bformat(_("No information for importing the format %1$s."), + bformat(_("No information for importing the format %1$s."), formats.prettyName(format))); return false; } @@ -1753,17 +1853,18 @@ static bool import(GuiView * lv, FileName const & filename, Buffer * buf = lv->loadDocument(lyxfile); if (!buf) return false; - buf->updateLabels(); + // I don't think this is needed, since it will be done in setBuffer(). + // buf->updateBuffer(); lv->setBuffer(buf); buf->errors("Parse"); } else { - Buffer * const b = newFile(lyxfile.absFilename(), string(), true); + Buffer * const b = newFile(lyxfile.absFileName(), string(), true); if (!b) return false; lv->setBuffer(b); bool as_paragraphs = loader_format == "textparagraph"; - string filename2 = (loader_format == format) ? filename.absFilename() - : support::changeExtension(filename.absFilename(), + string filename2 = (loader_format == format) ? filename.absFileName() + : support::changeExtension(filename.absFileName(), formats.extension(loader_format)); lv->currentBufferView()->insertPlaintextFile(FileName(filename2), as_paragraphs); @@ -1798,7 +1899,7 @@ void GuiView::importDocument(string const & argument) FileDialog dlg(toqstr(text), LFUN_BUFFER_IMPORT); dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); dlg.setButton2(qt_("Examples|#E#e"), - toqstr(addPath(package().system_support().absFilename(), "examples"))); + toqstr(addPath(package().system_support().absFileName(), "examples"))); docstring filter = formats.prettyName(format); filter += " (*."; @@ -1825,7 +1926,7 @@ void GuiView::importDocument(string const & argument) // get absolute path of file FileName const fullname(support::makeAbsPath(filename)); - FileName const lyxfile(support::changeExtension(fullname.absFilename(), ".lyx")); + FileName const lyxfile(support::changeExtension(fullname.absFileName(), ".lyx")); // Check if the document already is open Buffer * buf = theBufferList().getBuffer(lyxfile); @@ -1837,7 +1938,7 @@ void GuiView::importDocument(string const & argument) } } - docstring const displaypath = makeDisplayPath(lyxfile.absFilename(), 30); + docstring const displaypath = makeDisplayPath(lyxfile.absFileName(), 30); // if the file exists already, and we didn't do // -i lyx thefile.lyx, warn @@ -1877,11 +1978,11 @@ void GuiView::newDocument(string const & filename, bool from_template) string templatefile; if (from_template) { - templatefile = selectTemplateFile().absFilename(); + templatefile = selectTemplateFile().absFileName(); if (templatefile.empty()) return; } - + Buffer * b; if (filename.empty()) b = newUnnamedFile(initpath, to_utf8(_("newfile")), templatefile); @@ -1891,7 +1992,7 @@ void GuiView::newDocument(string const & filename, bool from_template) if (b) setBuffer(b); - // If no new document could be created, it is unsure + // If no new document could be created, it is unsure // whether there is a valid BufferView. if (currentBufferView()) // Ensure the cursor is correctly positioned on screen. @@ -1907,7 +2008,7 @@ void GuiView::insertLyXFile(docstring const & fname) // FIXME UNICODE FileName filename(to_utf8(fname)); - + if (!filename.empty()) { bv->insertLyXFile(filename); return; @@ -1925,11 +2026,11 @@ void GuiView::insertLyXFile(docstring const & fname) FileDialog dlg(qt_("Select LyX document to insert"), LFUN_FILE_INSERT); dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); dlg.setButton2(qt_("Examples|#E#e"), - toqstr(addPath(package().system_support().absFilename(), + toqstr(addPath(package().system_support().absFileName(), "examples"))); FileDialog::Result result = dlg.open(toqstr(initpath), - QStringList(qt_("LyX Documents (*.lyx)"))); + QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) return; @@ -1962,7 +2063,7 @@ void GuiView::insertPlaintextFile(docstring const & fname, // FIXME UNICODE FileName filename(to_utf8(fname)); - + if (!filename.empty()) { bv->insertPlaintextFile(filename, asParagraph); return; @@ -1998,7 +2099,7 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) if (!newname.empty()) { // FIXME UNICODE - fname = support::makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename()); + fname = support::makeAbsPath(to_utf8(newname), oldname.onlyPath().absFileName()); } else { // Switch to this Buffer. setBuffer(&b); @@ -2010,13 +2111,13 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); dlg.setButton2(qt_("Templates|#T#t"), toqstr(lyxrc.template_path)); - if (!isLyXFilename(fname.absFilename())) + if (!isLyXFileName(fname.absFileName())) fname.changeExtension(".lyx"); FileDialog::Result result = - dlg.save(toqstr(fname.onlyPath().absFilename()), - QStringList(qt_("LyX Documents (*.lyx)")), - toqstr(fname.onlyFileName())); + dlg.save(toqstr(fname.onlyPath().absFileName()), + QStringList(qt_("LyX Documents (*.lyx)")), + toqstr(fname.onlyFileName())); if (result.first == FileDialog::Later) return false; @@ -2026,15 +2127,16 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) if (fname.empty()) return false; - if (!isLyXFilename(fname.absFilename())) + if (!isLyXFileName(fname.absFileName())) fname.changeExtension(".lyx"); } + // fname is now the new Buffer location. if (FileName(fname).exists()) { - docstring const file = makeDisplayPath(fname.absFilename(), 30); + docstring const file = makeDisplayPath(fname.absFileName(), 30); docstring text = bformat(_("The document %1$s already " "exists.\n\nDo you want to " - "overwrite that document?"), + "overwrite that document?"), file); int const ret = Alert::prompt(_("Overwrite document?"), text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel")); @@ -2045,10 +2147,10 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) } } - FileName oldauto = b.getAutosaveFilename(); + FileName oldauto = b.getAutosaveFileName(); // Ok, change the name of the buffer - b.setFileName(fname.absFilename()); + b.setFileName(fname.absFileName()); b.markDirty(); bool unnamed = b.isUnnamed(); b.setUnnamed(false); @@ -2056,16 +2158,21 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) // bring the autosave file with us, just in case. b.moveAutosaveFile(oldauto); - + if (!saveBuffer(b)) { - oldauto = b.getAutosaveFilename(); - b.setFileName(oldname.absFilename()); + oldauto = b.getAutosaveFileName(); + b.setFileName(oldname.absFileName()); b.setUnnamed(unnamed); b.saveCheckSum(oldname); b.moveAutosaveFile(oldauto); return false; } + // the file has now been saved to the new location. + // we need to check that the locations of child buffers + // are still valid. + b.checkChildBuffers(); + return true; } @@ -2124,6 +2231,7 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa) bool GuiView::closeBuffer() { GuiWorkArea * wa = currentMainWorkArea(); + setCurrentWorkArea(wa); Buffer & buf = wa->bufferView().buffer(); return wa && closeWorkArea(wa, !buf.parent()); } @@ -2167,7 +2275,7 @@ bool GuiView::closeWorkAreaAll() setCurrentWorkArea(currentMainWorkArea()); // 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 + // 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; @@ -2196,6 +2304,11 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer) Buffer & buf = wa->bufferView().buffer(); + if (close_buffer && GuiViewPrivate::busyBuffers.contains(&buf)) { + Alert::warning(_("Close document "), _("Document could not be closed because it is processed by LyX.")); + return false; + } + if (close_buffer) return closeBuffer(buf); else { @@ -2215,9 +2328,10 @@ bool GuiView::closeBuffer(Buffer & buf) // in the session file in the correct order. If we close the master // buffer, we can close or release the child buffers here too. if (!closing_) { - vector clist = buf.getChildren(false); - for (vector::const_iterator it = clist.begin(); - it != clist.end(); ++it) { + ListOfBuffers clist = buf.getChildren(); + ListOfBuffers::const_iterator it = clist.begin(); + ListOfBuffers::const_iterator const bend = clist.end(); + for (; it != bend; ++it) { // If a child is dirty, do not close // without user intervention //FIXME: should we look in other tabworkareas? @@ -2234,9 +2348,10 @@ bool GuiView::closeBuffer(Buffer & buf) //FIXME: we should update only the bookmarks related to this buffer! LYXERR(Debug::DEBUG, "GuiView::closeBuffer()"); for (size_t i = 0; i < theSession().bookmarks().size(); ++i) - theLyXFunc().gotoBookmark(i+1, false, false); + guiApp->gotoBookmark(i+1, false, false); if (saveBufferIfNeeded(buf, false)) { + buf.removeAutosaveFile(); theBufferList().release(&buf); return true; } @@ -2255,7 +2370,7 @@ bool GuiView::closeTabWorkArea(TabWorkArea * twa) // We only want to close the buffer if the same buffer is not visible // in another view, and if this is not a child and if we are closing // a view (not a tabgroup). - bool const close_buffer = + bool const close_buffer = !inMultiViews(wa) && !b.parent() && closing_; if (!closeWorkArea(wa, close_buffer)) @@ -2287,9 +2402,9 @@ bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding) 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?"), + "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; @@ -2309,10 +2424,11 @@ bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding) // if we crash after this we could // have no autosave file but I guess // this is really improbable (Jug) - buf.removeAutosaveFile(); + // Sometime improbable things happen, bug 6857 (ps) + // buf.removeAutosaveFile(); if (hiding) // revert all changes - buf.loadLyXFile(buf.fileName()); + buf.reload(); buf.markClean(); break; case 2: @@ -2344,7 +2460,7 @@ bool GuiView::inMultiViews(GuiWorkArea * wa) 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; } @@ -2387,14 +2503,14 @@ static bool ensureBufferClean(Buffer * buffer) docstring text; if (!buffer->isUnnamed()) { text = bformat(_("The document %1$s has unsaved " - "changes.\n\nDo you want to save " - "the document?"), file); + "changes.\n\nDo you want to save " + "the document?"), file); title = _("Save changed document?"); - + } else { text = bformat(_("The document %1$s has not been " - "saved yet.\n\nDo you want to save " - "the document?"), file); + "saved yet.\n\nDo you want to save " + "the document?"), file); title = _("Save new document?"); } int const ret = Alert::prompt(title, text, 0, 1, _("&Save"), _("&Cancel")); @@ -2406,39 +2522,10 @@ static bool ensureBufferClean(Buffer * buffer) } -void GuiView::reloadBuffer() +bool GuiView::reloadBuffer() { Buffer * buf = &documentBufferView()->buffer(); - reloadBuffer(buf); -} - - -void GuiView::reloadBuffer(Buffer * buf) -{ - FileName filename = buf->fileName(); - // e.g., read-only status could have changed due to version control - filename.refresh(); - Buffer const * parent = buf->parent(); - bool const is_child = parent != buf; - // The user has already confirmed that the changes, if any, should - // be discarded. So we just release the Buffer and don't call closeBuffer(); - theBufferList().release(buf); - buf = loadDocument(filename); - docstring const disp_fn = makeDisplayPath(filename.absFilename()); - docstring str; - if (buf) { - // re-allocate master if necessary - if (is_child && theBufferList().isLoaded(parent) - && buf->parent() != parent) - buf->setParent(parent); - buf->updateLabels(); - setBuffer(buf); - buf->errors("Parse"); - str = bformat(_("Document %1$s reloaded."), disp_fn); - } else { - str = bformat(_("Could not reload document %1$s"), disp_fn); - } - message(str); + return buf->reload(); } @@ -2448,33 +2535,33 @@ void GuiView::checkExternallyModifiedBuffers() BufferList::iterator const bend = theBufferList().end(); for (; bit != bend; ++bit) { if ((*bit)->fileName().exists() - && (*bit)->isExternallyModified(Buffer::checksum_method)) { + && (*bit)->isExternallyModified(Buffer::checksum_method)) { docstring text = bformat(_("Document \n%1$s\n has been externally modified." " Reload now? Any local changes will be lost."), from_utf8((*bit)->absFileName())); int const ret = Alert::prompt(_("Reload externally changed document?"), text, 0, 1, _("&Reload"), _("&Cancel")); if (!ret) - reloadBuffer(*bit); + (*bit)->reload(); } } } -void GuiView::dispatchVC(FuncRequest const & cmd) +void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr) { - // message for statusbar - string msg; Buffer * buffer = documentBufferView() ? &(documentBufferView()->buffer()) : 0; - switch (cmd.action) { + switch (cmd.action()) { case LFUN_VC_REGISTER: if (!buffer || !ensureBufferClean(buffer)) break; if (!buffer->lyxvc().inUse()) { - if (buffer->lyxvc().registrer()) + if (buffer->lyxvc().registrer()) { reloadBuffer(); + dr.suppressMessageUpdate(); + } } break; @@ -2482,8 +2569,9 @@ void GuiView::dispatchVC(FuncRequest const & cmd) if (!buffer || !ensureBufferClean(buffer)) break; if (buffer->lyxvc().inUse() && !buffer->isReadonly()) { - msg = buffer->lyxvc().checkIn(); - reloadBuffer(); + dr.setMessage(buffer->lyxvc().checkIn()); + if (!dr.message().empty()) + reloadBuffer(); } break; @@ -2491,7 +2579,7 @@ void GuiView::dispatchVC(FuncRequest const & cmd) if (!buffer || !ensureBufferClean(buffer)) break; if (buffer->lyxvc().inUse()) { - msg = buffer->lyxvc().checkOut(); + dr.setMessage(buffer->lyxvc().checkOut()); reloadBuffer(); } break; @@ -2506,7 +2594,7 @@ void GuiView::dispatchVC(FuncRequest const & cmd) frontend::Alert::error(_("Revision control error."), _("Error when setting the locking property.")); } else { - msg = res; + dr.setMessage(res); reloadBuffer(); } } @@ -2516,18 +2604,20 @@ void GuiView::dispatchVC(FuncRequest const & cmd) LASSERT(buffer, return); buffer->lyxvc().revert(); reloadBuffer(); + dr.suppressMessageUpdate(); break; case LFUN_VC_UNDO_LAST: LASSERT(buffer, return); buffer->lyxvc().undoLast(); reloadBuffer(); + dr.suppressMessageUpdate(); break; case LFUN_VC_REPO_UPDATE: LASSERT(buffer, return); if (ensureBufferClean(buffer)) { - msg = buffer->lyxvc().repoUpdate(); + dr.setMessage(buffer->lyxvc().repoUpdate()); checkExternallyModifiedBuffers(); } break; @@ -2573,12 +2663,42 @@ void GuiView::dispatchVC(FuncRequest const & cmd) break; } - default: + + case LFUN_VC_COMPARE: { + + if (cmd.argument().empty()) { + lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "comparehistory")); + break; + } + + string rev1 = cmd.getArg(0); + string f1, f2; + + // f1 + if (!buffer->lyxvc().prepareFileRevision(rev1, f1)) + break; + + if (isStrInt(rev1) && convert(rev1) <= 0) { + f2 = buffer->absFileName(); + } else { + string rev2 = cmd.getArg(1); + if (rev2.empty()) + break; + // f2 + if (!buffer->lyxvc().prepareFileRevision(rev2, f2)) + break; + } + + LYXERR(Debug::LYXVC, "Launching comparison for fetched revisions:\n" << + f1 << "\n" << f2 << "\n" ); + string par = "compare run " + quoteName(f1) + " " + quoteName(f2); + lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, par)); break; } - if (!msg.empty()) - message(from_utf8(msg)); + default: + break; + } } @@ -2594,7 +2714,7 @@ void GuiView::openChildDocument(string const & fname) child = theBufferList().getBuffer(filename); } else { message(bformat(_("Opening child document %1$s..."), - makeDisplayPath(filename.absFilename()))); + makeDisplayPath(filename.absFileName()))); child = loadDocument(filename, false); parsed = true; } @@ -2605,7 +2725,10 @@ void GuiView::openChildDocument(string const & fname) // This makes insertion of citations and references in the child work, // when the target is in the parent or another child document. child->setParent(&buffer); - child->masterBuffer()->updateLabels(); + + // I don't think this is needed, since it will be called in + // setBuffer(). + // child->masterBuffer()->updateBuffer(); setBuffer(child); if (parsed) child->errors("Parse"); @@ -2629,7 +2752,7 @@ bool GuiView::goToFileRow(string const & argument) return false; } Buffer * buf = 0; - string const abstmp = package().temp_dir().absFilename(); + string const abstmp = package().temp_dir().absFileName(); string const realtmp = package().temp_dir().realPath(); // We have to use os::path_prefix_is() here, instead of // simply prefixIs(), because the file name comes from @@ -2647,13 +2770,17 @@ bool GuiView::goToFileRow(string const & argument) // Must replace extension of the file to be .lyx // and get full path FileName const s = fileSearch(string(), - support::changeExtension(file_name, ".lyx"), "lyx"); + support::changeExtension(file_name, ".lyx"), "lyx"); // Either change buffer or load the file if (theBufferList().exists(s)) buf = theBufferList().getBuffer(s); else if (s.exists()) { buf = loadDocument(s); - buf->updateLabels(); + if (!buf) + return false; + // I don't think this is needed. loadDocument() calls + // setBuffer(), which calls updateBuffer(). + // buf->updateBuffer(); buf->errors("Parse"); } else { message(bformat( @@ -2668,47 +2795,58 @@ bool GuiView::goToFileRow(string const & argument) } -static docstring exportAndDestroy(Buffer * buffer, string const & format) +#if (QT_VERSION >= 0x040400) +docstring GuiView::GuiViewPrivate::exportAndDestroy(Buffer const * orig, Buffer * buffer, string const & format) { - bool const success = buffer->doExport(format, true); + bool const update_unincluded = + buffer->params().maintain_unincluded_children + && !buffer->params().getIncludedChildren().empty(); + bool const success = buffer->doExport(format, true, update_unincluded); delete buffer; + busyBuffers.remove(orig); return success ? bformat(_("Successful export to format: %1$s"), from_utf8(format)) : bformat(_("Error exporting to format: %1$s"), from_utf8(format)); } -static docstring previewAndDestroy(Buffer * buffer, string const & format) +docstring GuiView::GuiViewPrivate::previewAndDestroy(Buffer const * orig, Buffer * buffer, string const & format) { - bool const success = buffer->preview(format); + bool const update_unincluded = + buffer->params().maintain_unincluded_children + && !buffer->params().getIncludedChildren().empty(); + bool const success = buffer->preview(format, update_unincluded); delete buffer; + busyBuffers.remove(orig); return success ? bformat(_("Successful preview of format: %1$s"), from_utf8(format)) : bformat(_("Error previewing format: %1$s"), from_utf8(format)); } +#endif -bool GuiView::dispatch(FuncRequest const & cmd) + +void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) { BufferView * bv = currentBufferView(); // By default we won't need any update. - if (bv) - bv->cursor().updateFlags(Update::None); + dr.screenUpdate(Update::None); + // assume cmd will be dispatched + dr.dispatched(true); Buffer * doc_buffer = documentBufferView() ? &(documentBufferView()->buffer()) : 0; - bool dispatched = true; - - if (cmd.origin == FuncRequest::TOC) { + if (cmd.origin() == FuncRequest::TOC) { GuiToc * toc = static_cast(findOrBuild("toc", false)); + // FIXME: do we need to pass a DispatchResult object here? toc->doDispatch(bv->cursor(), cmd); - return true; + return; } string const argument = to_utf8(cmd.argument()); - switch(cmd.action) { + switch(cmd.action()) { case LFUN_BUFFER_CHILD_OPEN: openChildDocument(to_utf8(cmd.argument())); break; @@ -2720,12 +2858,15 @@ bool GuiView::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_EXPORT: { if (!doc_buffer) break; - if (cmd.argument() == "custom") { - lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto")); + // GCC only sees strfwd.h when building merged + if (::lyx::operator==(cmd.argument(), "custom")) { + dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"), + dr); break; } - if (doc_buffer->doExport(argument, false)) { - message(bformat(_("Error exporting to format: %1$s."), + if (!doc_buffer->doExport(argument, false)) { + dr.setError(true); + dr.setMessage(bformat(_("Error exporting to format: %1$s."), cmd.argument())); } break; @@ -2734,77 +2875,148 @@ bool GuiView::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_UPDATE: { if (!doc_buffer) break; + docstring msg = _("Exporting ..."); + Buffer const * used_buffer = doc_buffer; string format = argument; - if (argument.empty()) - format = doc_buffer->getDefaultOutputFormat(); + if (format.empty()) + format = used_buffer->getDefaultOutputFormat(); #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400) - d.progress_->clearMessages(); - message(_("Exporting ...")); - QFuture f = QtConcurrent::run(exportAndDestroy, - doc_buffer->clone(), format); + if (!msg.empty()) { + d.progress_->clearMessages(); + message(msg); + } + GuiViewPrivate::busyBuffers.insert(used_buffer); + QFuture f = QtConcurrent::run( + GuiViewPrivate::exportAndDestroy, + used_buffer, + used_buffer->clone(), + format); d.setPreviewFuture(f); + d.last_export_format = used_buffer->bufferFormat(); #else - doc_buffer->doExport(format, true); + bool const update_unincluded = + used_buffer->params().maintain_unincluded_children && + !used_buffer->params().getIncludedChildren().empty(); + used_buffer->doExport(format, true, update_unincluded); #endif break; } case LFUN_BUFFER_VIEW: { if (!doc_buffer) break; + docstring msg = _("Previewing ..."); + Buffer const * used_buffer = doc_buffer; string format = argument; - if (argument.empty()) - format = doc_buffer->getDefaultOutputFormat(); + if (format.empty()) + format = used_buffer->getDefaultOutputFormat(); #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400) - d.progress_->clearMessages(); - message(_("Previewing ...")); - QFuture f = QtConcurrent::run(previewAndDestroy, - doc_buffer->clone(), format); + if (!msg.empty()) { + d.progress_->clearMessages(); + message(msg); + } + GuiViewPrivate::busyBuffers.insert(used_buffer); + QFuture f = QtConcurrent::run( + GuiViewPrivate::previewAndDestroy, + used_buffer, + used_buffer->clone(), + format); d.setPreviewFuture(f); + d.last_export_format = used_buffer->bufferFormat(); #else - doc_buffer->preview(format); + bool const update_unincluded = + used_buffer->params().maintain_unincluded_children && + !used_buffer->params().getIncludedChildren().empty(); + used_buffer->preview(format, update_unincluded); #endif break; } case LFUN_MASTER_BUFFER_UPDATE: { if (!doc_buffer) break; + Buffer const * used_buffer = doc_buffer->masterBuffer(); string format = argument; - Buffer const * master = doc_buffer->masterBuffer(); - if (argument.empty()) - format = master->getDefaultOutputFormat(); + if (format.empty()) + format = used_buffer->getDefaultOutputFormat(); #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400) - QFuture f = QtConcurrent::run(exportAndDestroy, - master->clone(), format); + GuiViewPrivate::busyBuffers.insert(used_buffer); + QFuture f = QtConcurrent::run( + GuiViewPrivate::exportAndDestroy, + used_buffer, + used_buffer->clone(), + format); d.setPreviewFuture(f); + d.last_export_format = used_buffer->bufferFormat(); #else - master->doExport(format, true); + bool const update_unincluded = + used_buffer->params().maintain_unincluded_children && + !used_buffer->params().getIncludedChildren().empty(); + used_buffer->doExport(format, update_unincluded); #endif break; } case LFUN_MASTER_BUFFER_VIEW: { + if (!doc_buffer) + break; + Buffer const * used_buffer = doc_buffer->masterBuffer(); string format = argument; - Buffer const * master = doc_buffer->masterBuffer(); - if (argument.empty()) - format = master->getDefaultOutputFormat(); + if (format.empty()) + format = used_buffer->getDefaultOutputFormat(); #if EXPORT_in_THREAD && (QT_VERSION >= 0x040400) - QFuture f = QtConcurrent::run(previewAndDestroy, - master->clone(), format); + GuiViewPrivate::busyBuffers.insert(used_buffer); + QFuture f = QtConcurrent::run( + GuiViewPrivate::previewAndDestroy, + used_buffer, + used_buffer->clone(), + format); d.setPreviewFuture(f); + // TODO doc_buffer was used used? Was this this a copy & paste error? + d.last_export_format = used_buffer->bufferFormat(); #else - master->preview(format); + used_buffer->preview(format); #endif break; } - case LFUN_BUFFER_SWITCH: - if (FileName::isAbsolute(to_utf8(cmd.argument()))) { - Buffer * buffer = - theBufferList().getBuffer(FileName(to_utf8(cmd.argument()))); - if (buffer) - setBuffer(buffer); - else - message(_("Document not loaded")); + case LFUN_BUFFER_SWITCH: { + string const file_name = to_utf8(cmd.argument()); + if (!FileName::isAbsolute(file_name)) { + dr.setError(true); + dr.setMessage(_("Absolute filename expected.")); + break; + } + + Buffer * buffer = theBufferList().getBuffer(FileName(file_name)); + if (!buffer) { + dr.setError(true); + dr.setMessage(_("Document not loaded")); + break; + } + + // Do we open or switch to the buffer in this view ? + if (workArea(*buffer) + || lyxrc.open_buffers_in_tabs || !documentBufferView()) { + setBuffer(buffer); + break; + } + + // Look for the buffer in other views + QList const ids = guiApp->viewIds(); + int i = 0; + for (; i != ids.size(); ++i) { + GuiView & gv = guiApp->view(ids[i]); + if (gv.workArea(*buffer)) { + gv.activateWindow(); + gv.setBuffer(buffer); + break; + } + } + + // If necessary, open a new window as a last resort + if (i == ids.size()) { + lyx::dispatch(FuncRequest(LFUN_WINDOW_NEW)); + lyx::dispatch(cmd); } break; + } case LFUN_BUFFER_NEXT: gotoNextOrPreviousBuffer(NEXTBUFFER); @@ -2849,13 +3061,14 @@ bool GuiView::dispatch(FuncRequest const & cmd) LASSERT(doc_buffer, break); docstring const file = makeDisplayPath(doc_buffer->absFileName(), 20); docstring text = bformat(_("Any changes will be lost. Are you sure " - "you want to revert to the saved version of the document %1$s?"), file); + "you want to revert to the saved version of the document %1$s?"), file); int const ret = Alert::prompt(_("Revert to saved document?"), text, 1, 1, _("&Revert"), _("&Cancel")); if (ret == 0) { doc_buffer->markClean(); reloadBuffer(); + dr.forceBufferUpdate(); } break; } @@ -2883,8 +3096,8 @@ bool GuiView::dispatch(FuncRequest const & cmd) LYXERR(Debug::ACTION, "Saved " << b->absFileName()); } b = theBufferList().next(b); - } while (b != first); - message(_("All documents saved.")); + } while (b != first); + dr.setMessage(_("All documents saved.")); break; } @@ -2913,6 +3126,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) // FIXME: get rid of this indirection; GuiView ask the inset // if he is kind enough to update itself... FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument()); + //FIXME: pass DispatchResult here? inset->dispatch(currentBufferView()->cursor(), fr); } else if (name == "paragraph") { lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE)); @@ -2924,9 +3138,9 @@ bool GuiView::dispatch(FuncRequest const & cmd) case LFUN_DIALOG_TOGGLE: { if (isDialogVisible(cmd.getArg(0))) - dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument())); + dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()), dr); else - dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument())); + dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()), dr); break; } @@ -2948,7 +3162,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) if (!data.empty()) showDialog("character", data); } else if (name == "latexlog") { - Buffer::LogType type; + Buffer::LogType type; string const logfile = doc_buffer->logName(&type); switch (type) { case Buffer::latexlog: @@ -2970,8 +3184,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) showDialog("symbols", data); // bug 5274 } else if (name == "prefs" && isFullScreen()) { - FuncRequest fr(LFUN_INSET_INSERT, "fullscreen"); - lfunUiToggle(fr); + lfunUiToggle("fullscreen"); showDialog("prefs", data); } else showDialog(name, data); @@ -2979,14 +3192,19 @@ bool GuiView::dispatch(FuncRequest const & cmd) } case LFUN_MESSAGE: - message(cmd.argument()); + dr.setMessage(cmd.argument()); break; - case LFUN_UI_TOGGLE: - lfunUiToggle(cmd); + case LFUN_UI_TOGGLE: { + string arg = cmd.getArg(0); + if (!lfunUiToggle(arg)) { + docstring const msg = "ui-toggle " + _("%1$s unknown command!"); + dr.setMessage(bformat(msg, from_utf8(arg))); + } // Make sure the keyboard focus stays in the work area. setFocus(); break; + } case LFUN_SPLIT_VIEW: { LASSERT(doc_buffer, break); @@ -3012,7 +3230,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) } } break; - + case LFUN_COMPLETION_INLINE: if (d.current_work_area_) d.current_work_area_->completer().showInline(); @@ -3046,7 +3264,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_ZOOM_IN: case LFUN_BUFFER_ZOOM_OUT: if (cmd.argument().empty()) { - if (cmd.action == LFUN_BUFFER_ZOOM_IN) + if (cmd.action() == LFUN_BUFFER_ZOOM_IN) lyxrc.zoom += 20; else lyxrc.zoom -= 20; @@ -3055,7 +3273,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) 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(); @@ -3071,15 +3289,53 @@ bool GuiView::dispatch(FuncRequest const & cmd) case LFUN_VC_REVERT: case LFUN_VC_UNDO_LAST: case LFUN_VC_COMMAND: - dispatchVC(cmd); + case LFUN_VC_COMPARE: + dispatchVC(cmd, dr); break; case LFUN_SERVER_GOTO_FILE_ROW: goToFileRow(to_utf8(cmd.argument())); break; + case LFUN_FORWARD_SEARCH: { + FileName const path(doc_buffer->temppath()); + string const texname = doc_buffer->latexName(); + FileName const dviname(addName(path.absFileName(), + support::changeExtension(texname, "dvi"))); + FileName const pdfname(addName(path.absFileName(), + support::changeExtension(texname, "pdf"))); + if (!dviname.exists() && !pdfname.exists()) { + dr.setMessage(_("Please, preview the document first.")); + break; + } + string outname = dviname.onlyFileName(); + string command = lyxrc.forward_search_dvi; + if (!dviname.exists() || + pdfname.lastModified() > dviname.lastModified()) { + outname = pdfname.onlyFileName(); + command = lyxrc.forward_search_pdf; + } + + int row = doc_buffer->texrow().getRowFromIdPos(bv->cursor().paragraph().id(), bv->cursor().pos()); + LYXERR(Debug::ACTION, "Forward search: row:" << row + << " id:" << bv->cursor().paragraph().id()); + if (!row || command.empty()) { + dr.setMessage(_("Couldn't proceed.")); + break; + } + string texrow = convert(row); + + command = subst(command, "$$n", texrow); + command = subst(command, "$$t", texname); + command = subst(command, "$$o", outname); + + PathChanger p(path); + Systemcall one; + one.startscript(Systemcall::DontWait, command); + break; + } default: - dispatched = false; + dr.dispatched(false); break; } @@ -3091,14 +3347,13 @@ bool GuiView::dispatch(FuncRequest const & cmd) statusBar()->hide(); } - return dispatched; + return; } -void GuiView::lfunUiToggle(FuncRequest const & cmd) +bool GuiView::lfunUiToggle(string const & ui_component) { - string const arg = cmd.getArg(0); - if (arg == "scrollbar") { + if (ui_component == "scrollbar") { // hide() is of no help if (d.current_work_area_->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) @@ -3108,18 +3363,13 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd) else d.current_work_area_->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff); - return; - } - if (arg == "statusbar") { + } else if (ui_component == "statusbar") { statusBar()->setVisible(!statusBar()->isVisible()); - return; - } - if (arg == "menubar") { + } else if (ui_component == "menubar") { menuBar()->setVisible(!menuBar()->isVisible()); - return; - } + } else #if QT_VERSION >= 0x040300 - if (arg == "frame") { + if (ui_component == "frame") { int l, t, r, b; getContentsMargins(&l, &t, &r, &b); //are the frames in default state? @@ -3129,15 +3379,13 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd) } else { setContentsMargins(0, 0, 0, 0); } - return; - } + } else #endif - if (arg == "fullscreen") { + if (ui_component == "fullscreen") { toggleFullScreen(); - return; - } - - message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg))); + } else + return false; + return true; } @@ -3180,13 +3428,20 @@ void GuiView::toggleFullScreen() Buffer const * GuiView::updateInset(Inset const * inset) { - if (!d.current_work_area_) + if (!inset) return 0; - if (inset) - d.current_work_area_->scheduleRedraw(); + Buffer const * inset_buffer = &(inset->buffer()); - return &d.current_work_area_->bufferView().buffer(); + for (int i = 0; i != d.splitter_->count(); ++i) { + GuiWorkArea * wa = d.tabWorkArea(i)->currentWorkArea(); + if (!wa) + continue; + Buffer const * buffer = &(wa->bufferView().buffer()); + if (inset_buffer == buffer) + wa->scheduleRedraw(); + } + return inset_buffer; } @@ -3219,14 +3474,15 @@ namespace { // docs in LyXAction.cpp. char const * const dialognames[] = { + "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", -"citation", "compare", "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", "progress"}; +"citation", "compare", "comparehistory", "document", "errorlist", "ert", +"external", "file", "findreplace", "findreplaceadv", "float", "graphics", +"href", "include", "index", "index_print", "info", "listings", "label", "line", +"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", "progress"}; char const * const * const end_dialognames = dialognames + (sizeof(dialognames) / sizeof(char *)); @@ -3245,7 +3501,7 @@ private: bool isValidName(string const & name) { return find_if(dialognames, end_dialognames, - cmpCStr(name.c_str())) != end_dialognames; + cmpCStr(name.c_str())) != end_dialognames; } } // namespace anon @@ -3253,7 +3509,7 @@ bool isValidName(string const & name) void GuiView::resetDialogs() { - // Make sure that no LFUN uses any LyXView. + // Make sure that no LFUN uses any GuiView. guiApp->setCurrentView(0); saveLayout(); menuBar()->clear(); @@ -3310,9 +3566,18 @@ void GuiView::doShowDialog(QString const & qname, QString const & qdata, try { Dialog * dialog = findOrBuild(name, false); if (dialog) { + bool const visible = dialog->isVisibleView(); dialog->showData(data); if (inset && currentBufferView()) currentBufferView()->editInset(name, inset); + // We only set the focus to the new dialog if it was not yet + // visible in order not to change the existing previous behaviour + if (visible) { + // activateWindow is needed for floating dockviews + dialog->asQWidget()->raise(); + dialog->asQWidget()->activateWindow(); + dialog->asQWidget()->setFocus(); + } } } catch (ExceptionMessage const & ex) { @@ -3376,38 +3641,37 @@ void GuiView::updateDialogs() for(; it != end; ++it) { Dialog * dialog = it->second.get(); - if (dialog && dialog->isVisibleView()) - dialog->checkStatus(); + if (dialog) { + if (dialog->needBufferOpen() && !documentBufferView()) + hideDialog(fromqstr(dialog->name()), 0); + else if (dialog->isVisibleView()) + dialog->checkStatus(); + } } updateToolbars(); updateLayoutList(); } +Dialog * createDialog(GuiView & lv, string const & name); // will be replaced by a proper factory... Dialog * createGuiAbout(GuiView & lv); -Dialog * createGuiBibitem(GuiView & lv); Dialog * createGuiBibtex(GuiView & lv); -Dialog * createGuiBox(GuiView & lv); -Dialog * createGuiBranch(GuiView & lv); Dialog * createGuiChanges(GuiView & lv); Dialog * createGuiCharacter(GuiView & lv); Dialog * createGuiCitation(GuiView & lv); Dialog * createGuiCompare(GuiView & lv); +Dialog * createGuiCompareHistory(GuiView & lv); Dialog * createGuiDelimiter(GuiView & lv); Dialog * createGuiDocument(GuiView & lv); Dialog * createGuiErrorList(GuiView & lv); -Dialog * createGuiERT(GuiView & lv); Dialog * createGuiExternal(GuiView & lv); -Dialog * createGuiFloat(GuiView & lv); Dialog * createGuiGraphics(GuiView & lv); Dialog * createGuiInclude(GuiView & lv); Dialog * createGuiIndex(GuiView & lv); -Dialog * createGuiInfo(GuiView & lv); Dialog * createGuiLabel(GuiView & lv); Dialog * createGuiListings(GuiView & lv); Dialog * createGuiLog(GuiView & lv); -Dialog * createGuiMathHSpace(GuiView & lv); Dialog * createGuiMathMatrix(GuiView & lv); Dialog * createGuiNomenclature(GuiView & lv); Dialog * createGuiNote(GuiView & lv); @@ -3425,13 +3689,10 @@ Dialog * createGuiShowFile(GuiView & lv); Dialog * createGuiSpellchecker(GuiView & lv); Dialog * createGuiSymbols(GuiView & lv); Dialog * createGuiTabularCreate(GuiView & lv); -Dialog * createGuiTabular(GuiView & lv); Dialog * createGuiTexInfo(GuiView & lv); -Dialog * createGuiTextHSpace(GuiView & lv); Dialog * createGuiToc(GuiView & lv); Dialog * createGuiThesaurus(GuiView & lv); Dialog * createGuiHyperlink(GuiView & lv); -Dialog * createGuiVSpace(GuiView & lv); Dialog * createGuiViewSource(GuiView & lv); Dialog * createGuiWrap(GuiView & lv); Dialog * createGuiProgressView(GuiView & lv); @@ -3442,16 +3703,14 @@ Dialog * GuiView::build(string const & name) { LASSERT(isValidName(name), return 0); + Dialog * dialog = createDialog(*this, name); + if (dialog) + return dialog; + if (name == "aboutlyx") return createGuiAbout(*this); - if (name == "bibitem") - return createGuiBibitem(*this); if (name == "bibtex") return createGuiBibtex(*this); - if (name == "box") - return createGuiBox(*this); - if (name == "branch") - return createGuiBranch(*this); if (name == "changes") return createGuiChanges(*this); if (name == "character") @@ -3460,12 +3719,12 @@ Dialog * GuiView::build(string const & name) return createGuiCitation(*this); if (name == "compare") return createGuiCompare(*this); + if (name == "comparehistory") + return createGuiCompareHistory(*this); if (name == "document") return createGuiDocument(*this); if (name == "errorlist") return createGuiErrorList(*this); - if (name == "ert") - return createGuiERT(*this); if (name == "external") return createGuiExternal(*this); if (name == "file") @@ -3474,8 +3733,6 @@ Dialog * GuiView::build(string const & name) return createGuiSearch(*this); if (name == "findreplaceadv") return createGuiSearchAdv(*this); - if (name == "float") - return createGuiFloat(*this); if (name == "graphics") return createGuiGraphics(*this); if (name == "href") @@ -3486,8 +3743,6 @@ Dialog * GuiView::build(string const & name) return createGuiIndex(*this); if (name == "index_print") return createGuiPrintindex(*this); - if (name == "info") - return createGuiInfo(*this); if (name == "label") return createGuiLabel(*this); if (name == "listings") @@ -3496,8 +3751,6 @@ Dialog * GuiView::build(string const & name) return createGuiLog(*this); if (name == "mathdelimiter") return createGuiDelimiter(*this); - if (name == "mathspace") - return createGuiMathHSpace(*this); if (name == "mathmatrix") return createGuiMathMatrix(*this); if (name == "nomenclature") @@ -3518,14 +3771,10 @@ Dialog * GuiView::build(string const & name) return createGuiRef(*this); if (name == "sendto") return createGuiSendTo(*this); - if (name == "space") - return createGuiTextHSpace(*this); if (name == "spellchecker") return createGuiSpellchecker(*this); if (name == "symbols") return createGuiSymbols(*this); - if (name == "tabular") - return createGuiTabular(*this); if (name == "tabularcreate") return createGuiTabularCreate(*this); if (name == "texinfo") @@ -3536,8 +3785,6 @@ Dialog * GuiView::build(string const & name) return createGuiToc(*this); if (name == "view-source") return createGuiViewSource(*this); - if (name == "vspace") - return createGuiVSpace(*this); if (name == "wrap") return createGuiWrap(*this); if (name == "progress")