X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fbufferlist.C;h=060e6269fca6bfee6e6a6a887b6a2efc59bfc684;hb=7ea7dabed1b72cc25dcbdc482ac006f2b61dacfd;hp=448a01af271a29df14080adb4aea393389d46044;hpb=2f08c8882155b1158548f1c34b100f58a7b63f01;p=lyx.git diff --git a/src/bufferlist.C b/src/bufferlist.C index 448a01af27..060e6269fc 100644 --- a/src/bufferlist.C +++ b/src/bufferlist.C @@ -4,27 +4,22 @@ * LyX, The Document Word Processor * * Copyright 1995 Matthias Ettrich - * Copyright 1995-2000 The LyX Team. + * Copyright 1995-2001 The LyX Team. * - * This file is Copyright 1996-2000 + * This file is Copyright 1996-2001 * Lars Gullik Bjønnes * * ====================================================== */ +#include + #ifdef __GNUG__ #pragma implementation #endif -#include - -#include - #include "bufferlist.h" #include "lyx_main.h" -#include "minibuffer.h" -#include "support/FileInfo.h" -#include "support/filetools.h" #include "lyx_gui_misc.h" #include "lastfiles.h" #include "debug.h" @@ -32,16 +27,33 @@ #include "lyxtext.h" #include "lyx_cb.h" #include "bufferview_funcs.h" +#include "BufferView.h" #include "gettext.h" #include "LyXView.h" #include "vc-backend.h" #include "TextCache.h" -extern BufferView * current_view; // called too many times in this file... +#include "frontends/Alert.h" + +#include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/lyxmanip.h" +#include "support/lyxfunctional.h" +#include "support/LAssert.h" + +#include +#include +#include + using std::vector; using std::find; using std::endl; +using std::find_if; +using std::for_each; +using std::mem_fun; + +extern BufferView * current_view; // // Class BufferStorage @@ -49,6 +61,7 @@ using std::endl; void BufferStorage::release(Buffer * buf) { + lyx::Assert(buf); Container::iterator it = find(container.begin(), container.end(), buf); if (it != container.end()) { // Make sure that we don't store a LyXText in @@ -66,8 +79,8 @@ Buffer * BufferStorage::newBuffer(string const & s, bool ronly) { Buffer * tmpbuf = new Buffer(s, ronly); tmpbuf->params.useClassDefaults(); - lyxerr.debug() << "Assigning to buffer " - << container.size() << endl; + lyxerr[Debug::INFO] << "Assigning to buffer " + << container.size() << endl; container.push_back(tmpbuf); return tmpbuf; } @@ -88,41 +101,63 @@ bool BufferList::empty() const } -extern void MenuWrite(Buffer *); +bool BufferList::qwriteOne(Buffer * buf, string const & fname, + string & unsaved_list) +{ + bool reask = true; + while (reask) { + switch (Alert::askConfirmation(_("Changes in document:"), + fname, + _("Save document?"))) { + case 1: // Yes + // FIXME: WriteAs can be asynch ! + if (buf->isUnnamed()) + reask = !WriteAs(current_view, buf); + else { + reask = !MenuWrite(current_view, buf); + } + break; + case 2: // No + // if we crash after this we could + // have no autosave file but I guess + // this is really inprobable (Jug) + if (buf->isUnnamed()) { + removeAutosaveFile(buf->fileName()); + } + + unsaved_list += MakeDisplayPath(fname, 50) + "\n"; + return true; + case 3: // Cancel + return false; + } + } + return true; +} -bool BufferList::QwriteAll() + +bool BufferList::qwriteAll() { - bool askMoreConfirmation = false; - string unsaved; - for(BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { + string unsaved; + BufferStorage::iterator it = bstore.begin(); + BufferStorage::iterator end = bstore.end(); + for (; it != end; ++it) { if (!(*it)->isLyxClean()) { - switch(AskConfirmation(_("Changes in document:"), - MakeDisplayPath((*it)->fileName(), - 50), - _("Save document?"))) { - case 1: // Yes - MenuWrite((*it)); - break; - case 2: // No - askMoreConfirmation = true; - unsaved += MakeDisplayPath((*it)->fileName(), - 50); - unsaved += "\n"; - break; - case 3: // Cancel + string fname; + if ((*it)->isUnnamed()) + fname = OnlyFilename((*it)->fileName()); + else + fname = MakeDisplayPath((*it)->fileName(), 50); + if (!qwriteOne(*it, fname, unsaved)) // cancel the request! return false; - } } } - if (askMoreConfirmation && - lyxrc.exit_confirmation && - !AskQuestion(_("Some documents were not saved:"), - unsaved, _("Exit anyway?"))) { - return false; - } - - return true; + + if (!unsaved.empty() && lyxrc.exit_confirmation) { + return Alert::askQuestion(_("Some documents were not saved:"), + unsaved, _("Exit anyway?")); + } + + return true; } @@ -140,40 +175,56 @@ void BufferList::closeAll() } -void BufferList::resize() -{ - for(BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { - (*it)->resize(); - } -} - - bool BufferList::close(Buffer * buf) { + lyx::Assert(buf); + // CHECK // Trace back why we need to use buf->getUser here. // Perhaps slight rewrite is in order? (Lgb) - if (buf->getUser()) buf->getUser()->insetUnlock(); + if (buf->getUser()) + buf->getUser()->insetUnlock(); + if (buf->paragraph && !buf->isLyxClean() && !quitting) { - if (buf->getUser()) ProhibitInput(buf->getUser()); - switch(AskConfirmation(_("Changes in document:"), - MakeDisplayPath(buf->fileName(), 50), - _("Save document?"))){ - case 1: // Yes - if (buf->save()) { - lastfiles->newFile(buf->fileName()); - } else { - if (buf->getUser()) AllowInput(buf->getUser()); + if (buf->getUser()) + buf->getUser()->owner()->prohibitInput(); + string fname; + if (buf->isUnnamed()) + fname = OnlyFilename(buf->fileName()); + else + fname = MakeDisplayPath(buf->fileName(), 50); + bool reask = true; + while (reask) { + switch (Alert::askConfirmation(_("Changes in document:"), + fname, + _("Save document?"))) { + case 1: // Yes + if (buf->isUnnamed()) + reask = !WriteAs(current_view, buf); + else if (buf->save()) { + lastfiles->newFile(buf->fileName()); + reask = false; + } else { + if (buf->getUser()) + buf->getUser()->owner()->allowInput(); + return false; + } + break; + case 2: + if (buf->isUnnamed()) { + removeAutosaveFile(buf->fileName()); + } + reask = false; + break; + case 3: // Cancel + if (buf->getUser()) + buf->getUser()->owner()->allowInput(); return false; } - break; - case 3: // Cancel - if (buf->getUser()) AllowInput(buf->getUser()); - return false; - } - if (buf->getUser()) AllowInput(buf->getUser()); + } + if (buf->getUser()) + buf->getUser()->owner()->allowInput(); } bstore.release(buf); @@ -181,13 +232,11 @@ bool BufferList::close(Buffer * buf) } -vector BufferList::getFileNames() const +vector const BufferList::getFileNames() const { vector nvec; - for(BufferStorage::const_iterator cit = bstore.begin(); - cit != bstore.end(); ++cit) { - nvec.push_back((*cit)->fileName()); - } + std::copy(bstore.begin(), bstore.end(), + lyx::back_inserter_fun(nvec, &Buffer::fileName)); return nvec; } @@ -199,7 +248,7 @@ Buffer * BufferList::first() } -Buffer * BufferList::getBuffer(int choice) +Buffer * BufferList::getBuffer(unsigned int choice) { if (choice >= bstore.size()) return 0; return bstore[choice]; @@ -208,11 +257,13 @@ Buffer * BufferList::getBuffer(int choice) int BufferList::unlockInset(UpdatableInset * inset) { - if (!inset) return 1; - for(BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { + lyx::Assert(inset); + + BufferStorage::iterator it = bstore.begin(); + BufferStorage::iterator end = bstore.end(); + for (; it != end; ++it) { if ((*it)->getUser() - && (*it)->getUser()->the_locking_inset == inset) { + && (*it)->getUser()->theLockingInset() == inset) { (*it)->getUser()->insetUnlock(); return 0; } @@ -223,8 +274,9 @@ int BufferList::unlockInset(UpdatableInset * inset) void BufferList::updateIncludedTeXfiles(string const & mastertmpdir) { - for(BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { + BufferStorage::iterator it = bstore.begin(); + BufferStorage::iterator end = bstore.end(); + for (; it != end; ++it) { if (!(*it)->isDepClean(mastertmpdir)) { string writefile = mastertmpdir; writefile += '/'; @@ -239,67 +291,86 @@ void BufferList::updateIncludedTeXfiles(string const & mastertmpdir) void BufferList::emergencyWriteAll() { - for (BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { - if (!(*it)->isLyxClean()) { - bool madeit = false; - - lyxerr <<_("lyx: Attempting to save" - " document ") - << (*it)->fileName() - << _(" as...") << endl; - - for (int i = 0; i < 3 && !madeit; ++i) { - string s; - - // We try to save three places: - // 1) Same place as document. - // 2) In HOME directory. - // 3) In "/tmp" directory. - if (i == 0) { - s = (*it)->fileName(); - } else if (i == 1) { - s = AddName(GetEnvPath("HOME"), - (*it)->fileName()); - } else { - // MakeAbsPath to prepend the current - // drive letter on OS/2 - s = AddName(MakeAbsPath("/tmp/"), - (*it)->fileName()); - } - s += ".emergency"; - - lyxerr << " " << i + 1 << ") " << s << endl; - - if ((*it)->writeFile(s, true)) { - (*it)->markLyxClean(); - lyxerr << _(" Save seems successful. " - "Phew.") << endl; - madeit = true; - } else if (i != 2) { - lyxerr << _(" Save failed! Trying...") - << endl; - } else { - lyxerr << _(" Save failed! Bummer. " - "Document is lost.") - << endl; - } - } + for_each(bstore.begin(), bstore.end(), + lyx::class_fun(*this, &BufferList::emergencyWrite)); +} + + +void BufferList::emergencyWrite(Buffer * buf) +{ + // assert(buf) // this is not good since C assert takes an int + // and a pointer is a long (JMarc) + assert(buf != 0); // use c assert to avoid a loop + + + // No need to save if the buffer has not changed. + if (buf->isLyxClean()) + return; + + lyxerr << fmt(_("lyx: Attempting to save document %s as..."), + buf->isUnnamed() ? OnlyFilename(buf->fileName()).c_str() + : buf->fileName().c_str()) << endl; + + // We try to save three places: + + // 1) Same place as document. Unless it is an unnamed doc. + if (!buf->isUnnamed()) { + string s = buf->fileName(); + s += ".emergency"; + lyxerr << " " << s << endl; + if (buf->writeFile(s, true)) { + buf->markLyxClean(); + lyxerr << _(" Save seems successful. Phew.") << endl; + return; + } else { + lyxerr << _(" Save failed! Trying...") << endl; } } + + // 2) In HOME directory. + string s = AddName(GetEnvPath("HOME"), buf->fileName()); + s += ".emergency"; + lyxerr << " " << s << endl; + if (buf->writeFile(s, true)) { + buf->markLyxClean(); + lyxerr << _(" Save seems successful. Phew.") << endl; + return; + } + + lyxerr << _(" Save failed! Trying...") << endl; + + // 3) In "/tmp" directory. + // MakeAbsPath to prepend the current + // drive letter on OS/2 + s = AddName(MakeAbsPath("/tmp/"), buf->fileName()); + s += ".emergency"; + lyxerr << " " << s << endl; + if (buf->writeFile(s, true)) { + buf->markLyxClean(); + lyxerr << _(" Save seems successful. Phew.") << endl; + return; + } + lyxerr << _(" Save failed! Bummer. Document is lost.") << endl; } + Buffer * BufferList::readFile(string const & s, bool ronly) { - Buffer * b = bstore.newBuffer(s, ronly); - - string ts = s; + string ts(s); string e = OnlyPath(s); string a = e; // File information about normal file FileInfo fileInfo2(s); + if (!fileInfo2.exist()) { + Alert::alert(_("Error!"), _("Cannot open file"), + MakeDisplayPath(s)); + return 0; + } + + Buffer * b = bstore.newBuffer(s, ronly); + // Check if emergency save file exists and is newer. e += OnlyFilename(s) + ".emergency"; FileInfo fileInfoE(e); @@ -309,7 +380,7 @@ Buffer * BufferList::readFile(string const & s, bool ronly) if (fileInfoE.exist() && fileInfo2.exist()) { if (fileInfoE.getModificationTime() > fileInfo2.getModificationTime()) { - if (AskQuestion(_("An emergency save of this document exists!"), + if (Alert::askQuestion(_("An emergency save of this document exists!"), MakeDisplayPath(s, 50), _("Try to load that instead?"))) { ts = e; @@ -319,7 +390,7 @@ Buffer * BufferList::readFile(string const & s, bool ronly) use_emergency = true; } else { // Here, we should delete the emergency save - ::unlink(e.c_str()); + lyx::unlink(e); } } } @@ -333,7 +404,7 @@ Buffer * BufferList::readFile(string const & s, bool ronly) if (fileInfoA.exist() && fileInfo2.exist()) { if (fileInfoA.getModificationTime() > fileInfo2.getModificationTime()) { - if (AskQuestion(_("Autosave file is newer."), + if (Alert::askQuestion(_("Autosave file is newer."), MakeDisplayPath(s, 50), _("Load that one instead?"))) { ts = a; @@ -342,7 +413,7 @@ Buffer * BufferList::readFile(string const & s, bool ronly) b->markDirty(); } else { // Here, we should delete the autosave - ::unlink(a.c_str()); + lyx::unlink(a); } } } @@ -361,17 +432,16 @@ Buffer * BufferList::readFile(string const & s, bool ronly) bool BufferList::exists(string const & s) const { - for (BufferStorage::const_iterator cit = bstore.begin(); - cit != bstore.end(); ++cit) { - if ((*cit)->fileName() == s) - return true; - } - return false; + return find_if(bstore.begin(), bstore.end(), + lyx::compare_memfun(&Buffer::fileName, s)) + != bstore.end(); } bool BufferList::isLoaded(Buffer const * b) const { + lyx::Assert(b); + BufferStorage::const_iterator cit = find(bstore.begin(), bstore.end(), b); return cit != bstore.end(); @@ -380,16 +450,14 @@ bool BufferList::isLoaded(Buffer const * b) const Buffer * BufferList::getBuffer(string const & s) { - for(BufferStorage::iterator it = bstore.begin(); - it != bstore.end(); ++it) { - if ((*it)->fileName() == s) - return (*it); - } - return 0; + BufferStorage::iterator it = + find_if(bstore.begin(), bstore.end(), + lyx::compare_memfun(&Buffer::fileName, s)); + return it != bstore.end() ? (*it) : 0; } -Buffer * BufferList::newFile(string const & name, string tname) +Buffer * BufferList::newFile(string const & name, string tname, bool isNamed) { // get a free buffer Buffer * b = bstore.newBuffer(name); @@ -398,27 +466,30 @@ Buffer * BufferList::newFile(string const & name, string tname) if (tname.empty()) { tname = LibFileSearch("templates", "defaults.lyx"); } - if (!tname.empty() && IsLyXFilename(tname)) { + if (!tname.empty()) { bool templateok = false; LyXLex lex(0, 0); lex.setFile(tname); - if (lex.IsOK()) { + if (lex.isOK()) { if (b->readFile(lex)) { templateok = true; } } if (!templateok) { - WriteAlert(_("Error!"), _("Unable to open template"), + Alert::alert(_("Error!"), _("Unable to open template"), MakeDisplayPath(tname)); // no template, start with empty buffer - b->paragraph = new LyXParagraph; + b->paragraph = new Paragraph; } + } else { // start with empty buffer + b->paragraph = new Paragraph; } - else { // start with empty buffer - b->paragraph = new LyXParagraph; + + if (!lyxrc.new_ask_filename && !isNamed) { + b->setUnnamed(); + b->setFileName(name); } - b->markDirty(); b->setReadonly(false); return b; @@ -427,12 +498,16 @@ Buffer * BufferList::newFile(string const & name, string tname) Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles) { - // make sure our path is absolute - string s = MakeAbsPath(filename); + // get absolute path of file and add ".lyx" to the filename if + // necessary + string s = FileSearch(string(), filename, "lyx"); + if (s.empty()) { + s = filename; + } // file already open? if (exists(s)) { - if (AskQuestion(_("Document is already open:"), + if (Alert::askQuestion(_("Document is already open:"), MakeDisplayPath(s, 50), _("Do you want to reload that document?"))) { // Reload is accomplished by closing and then loading @@ -450,11 +525,6 @@ Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles) bool ro = false; switch (IsFileWriteable(s)) { case 0: -#if 0 - current_view->owner()->getMiniBuffer()-> - Set(_("File `") + MakeDisplayPath(s, 50) + - _("' is read-only.")); -#endif ro = true; // Fall through case 1: @@ -468,7 +538,7 @@ Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles) if (LyXVC::file_not_found_hook(s)) { // Ask if the file should be checked out for // viewing/editing, if so: load it. - if (AskQuestion(_("Do you want to retrieve file under version control?"))) { + if (Alert::askQuestion(_("Do you want to retrieve file under version control?"))) { // How can we know _how_ to do the checkout? // With the current VC support it has to be, // a RCS file since CVS do not have special ,v files. @@ -476,12 +546,12 @@ Buffer * BufferList::loadLyXFile(string const & filename, bool tolastfiles) return loadLyXFile(filename, tolastfiles); } } - if (AskQuestion(_("Cannot open specified file:"), + if (Alert::askQuestion(_("Cannot open specified file:"), MakeDisplayPath(s, 50), _("Create new document with this name?"))) { // Find a free buffer - b = newFile(s, string()); + b = newFile(s, string(), true); } break; }