X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiView.cpp;h=569de58926a42788028d0e627c962fd9ef35efc1;hb=d3312032eeea9a682840e3a6b6a762cb4adec729;hp=90ef7e5e479986903db5ed693e4ccd820cdab189;hpb=6708d2da7e50e21111f3a48ffc577feea6ed9ad6;p=lyx.git diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 90ef7e5e47..569de58926 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -118,7 +118,7 @@ #include #endif -#include +#include "support/bind.h" #include @@ -191,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 @@ -217,17 +217,17 @@ struct GuiView::GuiViewPrivate // TODO cleanup, remove the singleton, handle multiple Windows? progress_ = ProgressInterface::instance(); - if (!dynamic_cast(progress_)) { + if (!dynamic_cast(progress_)) { progress_ = new GuiProgress(); // TODO who deletes it - ProgressInterface::setInstance(progress_); + ProgressInterface::setInstance(progress_); } QObject::connect( - dynamic_cast(progress_), - SIGNAL(updateStatusBarMessage(QString const&)), + dynamic_cast(progress_), + SIGNAL(updateStatusBarMessage(QString const&)), gv, SLOT(updateStatusBarMessage(QString const&))); QObject::connect( - dynamic_cast(progress_), - SIGNAL(clearMessageText()), + dynamic_cast(progress_), + SIGNAL(clearMessageText()), gv, SLOT(clearMessageText())); } @@ -327,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. @@ -360,7 +360,7 @@ public: /// string last_export_format; #else - struct DummyWatcher { bool isRunning(){return false;} }; + struct DummyWatcher { bool isRunning(){return false;} }; DummyWatcher preview_watcher_; #endif @@ -385,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); @@ -393,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(); } @@ -463,6 +463,7 @@ void GuiView::threadFinished() QFutureWatcher const * watcher = static_cast const *>(sender()); message(watcher->result()); + updateToolbars(); errors(d.last_export_format); #endif } @@ -662,6 +663,13 @@ 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) **/ @@ -670,11 +678,15 @@ void GuiView::closeEvent(QCloseEvent * close_event) LYXERR(Debug::DEBUG, "GuiView::closeEvent()"); if (!GuiViewPrivate::busyBuffers.isEmpty()) { - Alert::warning(_("Exit LyX"), _("Could not exit LyX, because documents are processed by LyX.")); + 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(); @@ -746,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) @@ -762,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, @@ -783,7 +795,7 @@ void GuiView::message(docstring const & str) { if (ForkedProcess::iAmAChild()) return; - + // call is moved to GUI-thread by GuiProgress d.progress_->appendMessage(toqstr(str)); } @@ -1010,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) @@ -1041,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); } @@ -1101,8 +1120,8 @@ void GuiView::setCurrentWorkArea(GuiWorkArea * 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) + if (theGuiApp()->currentView() == this + && theGuiApp()->currentView()->currentWorkArea() == wa) return; if (currentBufferView()) @@ -1311,7 +1330,7 @@ BufferView * GuiView::documentBufferView() } -BufferView const * GuiView::documentBufferView() const +BufferView const * GuiView::documentBufferView() const { return currentMainWorkArea() ? ¤tMainWorkArea()->bufferView() @@ -1365,7 +1384,7 @@ void GuiView::autoSave() #if (QT_VERSION >= 0x040400) GuiViewPrivate::busyBuffers.insert(buffer); QFuture f = QtConcurrent::run(GuiViewPrivate::saveAndDestroy, buffer, buffer->clone(), - buffer->getAutosaveFilename()); + buffer->getAutosaveFileName()); d.autosave_watcher_.setFuture(f); #else buffer->autoSave(); @@ -1409,7 +1428,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) 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; @@ -1457,7 +1476,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } b = theBufferList().next(b); - } while (b != first); + } while (b != first); break; } @@ -1492,7 +1511,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) flag.setOnOff(t->isVisible()); else { enable = false; - docstring const msg = + docstring const msg = bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)); flag.message(msg); } @@ -1500,7 +1519,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) } case LFUN_DROP_LAYOUTS_CHOICE: - enable = buf; + enable = buf; break; case LFUN_UI_TOGGLE: @@ -1530,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 @@ -1605,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? @@ -1633,13 +1651,13 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) 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()) @@ -1649,8 +1667,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } case LFUN_VC_COMPARE: - enable = doc_buffer && !cmd.argument().empty() - && doc_buffer->lyxvc().prepareFileRevisionEnabled(); + enable = doc_buffer && doc_buffer->lyxvc().prepareFileRevisionEnabled(); break; case LFUN_SERVER_GOTO_FILE_ROW: @@ -1674,7 +1691,7 @@ 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)"))); @@ -1698,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 @@ -1733,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)") @@ -1757,20 +1774,20 @@ 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 and isn't already open (bug 6645), + // 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. @@ -1786,7 +1803,8 @@ void GuiView::openDocument(string const & fname) docstring str2; Buffer * buf = loadDocument(fullname); if (buf) { - buf->updateBuffer(); + // 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); @@ -1803,7 +1821,7 @@ 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(); @@ -1814,7 +1832,7 @@ static bool import(GuiView * lv, FileName const & filename, 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)) @@ -1835,17 +1853,18 @@ static bool import(GuiView * lv, FileName const & filename, Buffer * buf = lv->loadDocument(lyxfile); if (!buf) return false; - buf->updateBuffer(); + // 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); @@ -1880,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 += " (*."; @@ -1907,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); @@ -1919,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 @@ -1959,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); @@ -1973,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. @@ -1989,7 +2008,7 @@ void GuiView::insertLyXFile(docstring const & fname) // FIXME UNICODE FileName filename(to_utf8(fname)); - + if (!filename.empty()) { bv->insertLyXFile(filename); return; @@ -2007,7 +2026,7 @@ 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), @@ -2044,7 +2063,7 @@ void GuiView::insertPlaintextFile(docstring const & fname, // FIXME UNICODE FileName filename(to_utf8(fname)); - + if (!filename.empty()) { bv->insertPlaintextFile(filename, asParagraph); return; @@ -2080,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); @@ -2092,11 +2111,11 @@ 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()), + dlg.save(toqstr(fname.onlyPath().absFileName()), QStringList(qt_("LyX Documents (*.lyx)")), toqstr(fname.onlyFileName())); @@ -2108,16 +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")); @@ -2128,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); @@ -2139,10 +2158,10 @@ 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); @@ -2256,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; @@ -2286,7 +2305,7 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer) Buffer & buf = wa->bufferView().buffer(); if (close_buffer && GuiViewPrivate::busyBuffers.contains(&buf)) { - Alert::warning(_("Close document "), _("Could not close document, because it is processed by LyX.")); + Alert::warning(_("Close document "), _("Document could not be closed because it is processed by LyX.")); return false; } @@ -2309,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? @@ -2350,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)) @@ -2384,7 +2404,7 @@ bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding) 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?"), + ret = Alert::prompt(_("Save new document?"), text, 0, 1, _("&Save"), _("&Cancel")); if (ret == 1) ++ret; @@ -2440,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; } @@ -2486,7 +2506,7 @@ static bool ensureBufferClean(Buffer * buffer) "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 " @@ -2502,10 +2522,10 @@ static bool ensureBufferClean(Buffer * buffer) } -void GuiView::reloadBuffer() +bool GuiView::reloadBuffer() { Buffer * buf = &documentBufferView()->buffer(); - buf->reload(); + return buf->reload(); } @@ -2528,11 +2548,8 @@ void GuiView::checkExternallyModifiedBuffers() } -//FIXME use a DispatchResult object to transmit messages -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; @@ -2541,8 +2558,10 @@ void GuiView::dispatchVC(FuncRequest const & cmd) if (!buffer || !ensureBufferClean(buffer)) break; if (!buffer->lyxvc().inUse()) { - if (buffer->lyxvc().registrer()) + if (buffer->lyxvc().registrer()) { reloadBuffer(); + dr.suppressMessageUpdate(); + } } break; @@ -2550,8 +2569,8 @@ void GuiView::dispatchVC(FuncRequest const & cmd) if (!buffer || !ensureBufferClean(buffer)) break; if (buffer->lyxvc().inUse() && !buffer->isReadonly()) { - msg = buffer->lyxvc().checkIn(); - if (!msg.empty()) + dr.setMessage(buffer->lyxvc().checkIn()); + if (!dr.message().empty()) reloadBuffer(); } break; @@ -2560,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; @@ -2575,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(); } } @@ -2585,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; @@ -2645,6 +2666,11 @@ void GuiView::dispatchVC(FuncRequest const & cmd) case LFUN_VC_COMPARE: { + if (cmd.argument().empty()) { + lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "comparehistory")); + break; + } + string rev1 = cmd.getArg(0); string f1, f2; @@ -2662,29 +2688,17 @@ void GuiView::dispatchVC(FuncRequest const & cmd) if (!buffer->lyxvc().prepareFileRevision(rev2, f2)) break; } - // FIXME We need to call comparison feature here. - // This is quick and dirty code for testing VC. - // We need that comparison feature has some LFUN_COMPARE file1 file1 - // where specifies whether we want GUI dialog or just launch - // running with defaults. - /* - FileName initpath(lyxrc.document_path); - Buffer * dest = newUnnamedFile(initpath, to_utf8(_("differences"))); - CompareOptions options; - Compare * compare = new Compare(loadIfNeeded(FileName(f1)), loadIfNeeded(FileName(f2)), dest, options); - compare->start(QThread::LowPriority); - Sleep::millisec(200); - lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, dest->absFileName())); - */ + + 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; } default: break; } - - if (!msg.empty()) - message(from_utf8(msg)); } @@ -2700,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; } @@ -2711,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()->updateBuffer(); + + // I don't think this is needed, since it will be called in + // setBuffer(). + // child->masterBuffer()->updateBuffer(); setBuffer(child); if (parsed) child->errors("Parse"); @@ -2735,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 @@ -2759,7 +2776,11 @@ bool GuiView::goToFileRow(string const & argument) buf = theBufferList().getBuffer(s); else if (s.exists()) { buf = loadDocument(s); - buf->updateBuffer(); + 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( @@ -2804,11 +2825,12 @@ docstring GuiView::GuiViewPrivate::previewAndDestroy(Buffer const * orig, Buffer #endif + void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) { BufferView * bv = currentBufferView(); // By default we won't need any update. - dr.update(Update::None); + dr.screenUpdate(Update::None); // assume cmd will be dispatched dr.dispatched(true); @@ -2838,7 +2860,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; // GCC only sees strfwd.h when building merged if (::lyx::operator==(cmd.argument(), "custom")) { - dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"), + dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"), dr); break; } @@ -2853,96 +2875,148 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) 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 ...")); - GuiViewPrivate::busyBuffers.insert(doc_buffer); - QFuture f = QtConcurrent::run(GuiViewPrivate::exportAndDestroy, - doc_buffer, 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 = doc_buffer->bufferFormat(); + d.last_export_format = used_buffer->bufferFormat(); #else bool const update_unincluded = - doc_buffer->params().maintain_unincluded_children - && !doc_buffer->params().getIncludedChildren().empty(); - doc_buffer->doExport(format, true, 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 ...")); - GuiViewPrivate::busyBuffers.insert(doc_buffer); - QFuture f = QtConcurrent::run(GuiViewPrivate::previewAndDestroy, - doc_buffer, 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 = doc_buffer->bufferFormat(); + d.last_export_format = used_buffer->bufferFormat(); #else bool const update_unincluded = - doc_buffer->params().maintain_unincluded_children - && !doc_buffer->params().getIncludedChildren().empty(); - doc_buffer->preview(format, 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) - GuiViewPrivate::busyBuffers.insert(master); - QFuture f = QtConcurrent::run(GuiViewPrivate::exportAndDestroy, - master, 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 = doc_buffer->bufferFormat(); + d.last_export_format = used_buffer->bufferFormat(); #else bool const update_unincluded = - master->params().maintain_unincluded_children - && !master->params().getIncludedChildren().empty(); - master->doExport(format, true); + 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) - GuiViewPrivate::busyBuffers.insert(master); - QFuture f = QtConcurrent::run(GuiViewPrivate::previewAndDestroy, - master, master->clone(), format); + GuiViewPrivate::busyBuffers.insert(used_buffer); + QFuture f = QtConcurrent::run( + GuiViewPrivate::previewAndDestroy, + used_buffer, + used_buffer->clone(), + format); d.setPreviewFuture(f); - d.last_export_format = doc_buffer->bufferFormat(); + // 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 { - dr.setError(true); - dr.setMessage(_("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); @@ -2994,6 +3068,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) if (ret == 0) { doc_buffer->markClean(); reloadBuffer(); + dr.forceBufferUpdate(); } break; } @@ -3021,7 +3096,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) LYXERR(Debug::ACTION, "Saved " << b->absFileName()); } b = theBufferList().next(b); - } while (b != first); + } while (b != first); dr.setMessage(_("All documents saved.")); break; } @@ -3087,7 +3162,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) 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: @@ -3155,7 +3230,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) } } break; - + case LFUN_COMPLETION_INLINE: if (d.current_work_area_) d.current_work_area_->completer().showInline(); @@ -3198,7 +3273,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) 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(); @@ -3215,7 +3290,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) case LFUN_VC_UNDO_LAST: case LFUN_VC_COMMAND: case LFUN_VC_COMPARE: - dispatchVC(cmd); + dispatchVC(cmd, dr); break; case LFUN_SERVER_GOTO_FILE_ROW: @@ -3223,18 +3298,27 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_FORWARD_SEARCH: { - string command = lyxrc.forward_search_dvi; FileName const path(doc_buffer->temppath()); string const texname = doc_buffer->latexName(); - string outname = support::changeExtension(texname, "dvi"); - if (!FileName(addName(path.absFilename(), outname)).exists()) { - outname = support::changeExtension(texname, "pdf"); + 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; - if (!FileName(addName(path.absFilename(), outname)).exists()) - break; } 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; @@ -3247,7 +3331,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) PathChanger p(path); Systemcall one; - one.startscript(Systemcall::Wait, command); + one.startscript(Systemcall::DontWait, command); break; } default: @@ -3390,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 *)); @@ -3481,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) { @@ -3548,7 +3642,7 @@ void GuiView::updateDialogs() for(; it != end; ++it) { Dialog * dialog = it->second.get(); if (dialog) { - if (dialog->isBufferDependent() && !documentBufferView()) + if (dialog->needBufferOpen() && !documentBufferView()) hideDialog(fromqstr(dialog->name()), 0); else if (dialog->isVisibleView()) dialog->checkStatus(); @@ -3567,6 +3661,7 @@ 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); @@ -3624,6 +3719,8 @@ 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")