3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
13 #include "BufferList.h"
17 #include "BufferParams.h"
20 #include "output_latex.h"
21 #include "ParagraphList.h"
23 #include "frontends/alert.h"
25 #include "support/ExceptionMessage.h"
26 #include "support/debug.h"
27 #include "support/filetools.h"
28 #include "support/FileName.h"
29 #include "support/gettext.h"
30 #include "support/lstrings.h"
31 #include "support/Package.h"
33 #include "support/lassert.h"
34 #include <boost/bind.hpp>
42 using namespace lyx::support;
46 namespace Alert = lyx::frontend::Alert;
49 BufferList::BufferList()
53 bool BufferList::empty() const
55 return bstore.empty();
59 BufferList::iterator BufferList::begin()
61 return bstore.begin();
65 BufferList::const_iterator BufferList::begin() const
67 return bstore.begin();
71 BufferList::iterator BufferList::end()
77 BufferList::const_iterator BufferList::end() const
83 void BufferList::release(Buffer * buf)
86 BufferStorage::iterator const it =
87 find(bstore.begin(), bstore.end(), buf);
88 if (it != bstore.end()) {
97 Buffer * BufferList::newBuffer(string const & s, bool const ronly)
99 auto_ptr<Buffer> tmpbuf;
101 tmpbuf.reset(new Buffer(s, ronly));
102 } catch (ExceptionMessage const & message) {
103 if (message.type_ == ErrorException) {
104 Alert::error(message.title_, message.details_);
106 } else if (message.type_ == WarningException) {
107 Alert::warning(message.title_, message.details_);
111 tmpbuf->params().useClassDefaults();
112 LYXERR(Debug::INFO, "Assigning to buffer " << bstore.size());
113 bstore.push_back(tmpbuf.get());
114 return tmpbuf.release();
118 void BufferList::closeAll()
120 while (!bstore.empty())
121 release(bstore.front());
125 vector<string> const BufferList::getFileNames() const
128 transform(bstore.begin(), bstore.end(),
130 boost::bind(&Buffer::absFileName, _1));
135 Buffer * BufferList::first()
139 return bstore.front();
143 Buffer * BufferList::last()
147 return bstore.back();
151 Buffer * BufferList::getBuffer(unsigned int choice)
153 if (choice >= bstore.size())
155 return bstore[choice];
159 Buffer * BufferList::next(Buffer const * buf) const
165 BufferStorage::const_iterator it = find(bstore.begin(),
167 LASSERT(it != bstore.end(), /**/);
169 if (it == bstore.end())
170 return bstore.front();
176 Buffer * BufferList::previous(Buffer const * buf) const
182 BufferStorage::const_iterator it = find(bstore.begin(),
184 LASSERT(it != bstore.end(), /**/);
185 if (it == bstore.begin())
186 return bstore.back();
192 void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
193 OutputParams const & runparams)
195 BufferStorage::iterator it = bstore.begin();
196 BufferStorage::iterator end = bstore.end();
197 for (; it != end; ++it) {
198 if (!(*it)->isDepClean(masterTmpDir)) {
199 string writefile = addName(masterTmpDir, (*it)->latexName());
200 (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
202 (*it)->markDepClean(masterTmpDir);
208 void BufferList::emergencyWriteAll()
210 for_each(bstore.begin(), bstore.end(),
211 bind(&BufferList::emergencyWrite, this, _1));
215 docstring BufferList::emergencyWrite(Buffer * buf)
217 // Use ::assert to avoid a loop, BOOST_ASSERT ends up calling ::assert
218 // compare with 0 to avoid pointer/interger comparison
219 // ::assert(buf != 0);
221 return _("No file open!");
223 // No need to save if the buffer has not changed.
227 string const doc = buf->isUnnamed()
228 ? onlyFilename(buf->absFileName()) : buf->absFileName();
230 docstring user_message = bformat(
231 _("LyX: Attempting to save document %1$s\n"), from_utf8(doc));
233 // We try to save three places:
234 // 1) Same place as document. Unless it is an unnamed doc.
235 if (!buf->isUnnamed()) {
236 string s = buf->absFileName();
238 lyxerr << " " << s << endl;
239 if (buf->writeFile(FileName(s))) {
241 user_message += _(" Save seems successful. Phew.\n");
244 user_message += _(" Save failed! Trying...\n");
248 // 2) In HOME directory.
249 string s = addName(package().home_dir().absFilename(), buf->absFileName());
251 lyxerr << ' ' << s << endl;
252 if (buf->writeFile(FileName(s))) {
254 user_message += _(" Save seems successful. Phew.\n");
258 user_message += _(" Save failed! Trying...\n");
260 // 3) In "/tmp" directory.
261 // MakeAbsPath to prepend the current
262 // drive letter on OS/2
263 s = addName(package().temp_dir().absFilename(), buf->absFileName());
265 lyxerr << ' ' << s << endl;
266 if (buf->writeFile(FileName(s))) {
268 user_message += _(" Save seems successful. Phew.\n");
272 user_message += _(" Save failed! Bummer. Document is lost.");
277 bool BufferList::exists(FileName const & fname) const
279 return getBuffer(fname) != 0;
283 bool BufferList::isLoaded(Buffer const * b) const
286 BufferStorage::const_iterator cit =
287 find(bstore.begin(), bstore.end(), b);
288 return cit != bstore.end();
292 Buffer * BufferList::getBuffer(support::FileName const & fname) const
294 BufferStorage::const_iterator it = find_if(bstore.begin(), bstore.end(),
295 bind(equal_to<FileName>(), bind(&Buffer::fileName, _1), fname));
296 return it != bstore.end() ? (*it) : 0;
300 Buffer * BufferList::getBufferFromTmp(string const & s)
302 BufferStorage::iterator it = bstore.begin();
303 BufferStorage::iterator end = bstore.end();
304 for (; it < end; ++it)
305 if (prefixIs(s, (*it)->temppath()))
311 void BufferList::setCurrentAuthor(docstring const & name, docstring const & email)
313 BufferStorage::iterator it = bstore.begin();
314 BufferStorage::iterator end = bstore.end();
315 for (; it != end; ++it)
316 (*it)->params().authors().record(0, Author(name, email));
320 int BufferList::bufferNum(string const & name) const
322 vector<string> buffers = getFileNames();
323 vector<string>::const_iterator cit =
324 find(buffers.begin(), buffers.end(), name);
325 if (cit == buffers.end())
327 return int(cit - buffers.begin());
331 bool BufferList::releaseChild(Buffer * parent, Buffer * child)
333 LASSERT(parent, return false);
334 LASSERT(child, return false);
335 LASSERT(parent->isChild(child), return false);
337 // Child document has a different parent, don't close it.
338 if (child->parent() != parent)
341 BufferStorage::iterator it = bstore.begin();
342 BufferStorage::iterator end = bstore.end();
343 for (; it != end; ++it) {
345 if (buf != parent && buf->isChild(child)) {