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/gettext.h"
29 #include "support/lstrings.h"
30 #include "support/Package.h"
32 #include <boost/bind.hpp>
40 using namespace lyx::support;
44 namespace Alert = lyx::frontend::Alert;
47 BufferList::BufferList()
51 bool BufferList::empty() const
53 return bstore.empty();
57 BufferList::iterator BufferList::begin()
59 return bstore.begin();
63 BufferList::const_iterator BufferList::begin() const
65 return bstore.begin();
69 BufferList::iterator BufferList::end()
75 BufferList::const_iterator BufferList::end() const
81 void BufferList::release(Buffer * buf)
84 BufferStorage::iterator const it =
85 find(bstore.begin(), bstore.end(), buf);
86 if (it != bstore.end()) {
95 Buffer * BufferList::newBuffer(string const & s, bool const ronly)
97 auto_ptr<Buffer> tmpbuf;
98 try { tmpbuf.reset(new Buffer(s, ronly));
99 } catch (ExceptionMessage const & message) {
100 if (message.type_ == ErrorException) {
101 Alert::error(message.title_, message.details_);
103 } else if (message.type_ == WarningException) {
104 Alert::warning(message.title_, message.details_);
108 tmpbuf->params().useClassDefaults();
109 LYXERR(Debug::INFO, "Assigning to buffer " << bstore.size());
110 bstore.push_back(tmpbuf.get());
111 return tmpbuf.release();
115 void BufferList::closeAll()
117 while (!bstore.empty())
118 release(bstore.front());
122 vector<string> const BufferList::getFileNames() const
125 transform(bstore.begin(), bstore.end(),
127 boost::bind(&Buffer::absFileName, _1));
132 Buffer * BufferList::first()
136 return bstore.front();
140 Buffer * BufferList::last()
144 return bstore.back();
148 Buffer * BufferList::getBuffer(unsigned int choice)
150 if (choice >= bstore.size())
152 return bstore[choice];
156 Buffer * BufferList::next(Buffer const * buf) const
162 BufferStorage::const_iterator it = find(bstore.begin(),
164 BOOST_ASSERT(it != bstore.end());
166 if (it == bstore.end())
167 return bstore.front();
173 Buffer * BufferList::previous(Buffer const * buf) const
179 BufferStorage::const_iterator it = find(bstore.begin(),
181 BOOST_ASSERT(it != bstore.end());
182 if (it == bstore.begin())
183 return bstore.back();
189 void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
190 OutputParams const & runparams)
192 BufferStorage::iterator it = bstore.begin();
193 BufferStorage::iterator end = bstore.end();
194 for (; it != end; ++it) {
195 if (!(*it)->isDepClean(masterTmpDir)) {
196 string writefile = addName(masterTmpDir, (*it)->latexName());
197 (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
199 (*it)->markDepClean(masterTmpDir);
205 void BufferList::emergencyWriteAll()
207 for_each(bstore.begin(), bstore.end(),
208 bind(&BufferList::emergencyWrite, this, _1));
212 void BufferList::emergencyWrite(Buffer * buf)
214 // Use ::assert to avoid a loop, BOOST_ASSERT ends up calling ::assert
215 // compare with 0 to avoid pointer/interger comparison
216 // ::assert(buf != 0);
220 // No need to save if the buffer has not changed.
224 string const doc = buf->isUnnamed()
225 ? onlyFilename(buf->absFileName()) : buf->absFileName();
228 bformat(_("LyX: Attempting to save document %1$s"), from_utf8(doc)))
231 // We try to save three places:
232 // 1) Same place as document. Unless it is an unnamed doc.
233 if (!buf->isUnnamed()) {
234 string s = buf->absFileName();
236 lyxerr << " " << s << endl;
237 if (buf->writeFile(FileName(s))) {
239 lyxerr << to_utf8(_(" Save seems successful. Phew.")) << endl;
242 lyxerr << to_utf8(_(" Save failed! Trying...")) << endl;
246 // 2) In HOME directory.
247 string s = addName(package().home_dir().absFilename(), buf->absFileName());
249 lyxerr << ' ' << s << endl;
250 if (buf->writeFile(FileName(s))) {
252 lyxerr << to_utf8(_(" Save seems successful. Phew.")) << endl;
256 lyxerr << to_utf8(_(" Save failed! Trying...")) << endl;
258 // 3) In "/tmp" directory.
259 // MakeAbsPath to prepend the current
260 // drive letter on OS/2
261 s = addName(package().temp_dir().absFilename(), buf->absFileName());
263 lyxerr << ' ' << s << endl;
264 if (buf->writeFile(FileName(s))) {
266 lyxerr << to_utf8(_(" Save seems successful. Phew.")) << endl;
269 lyxerr << to_utf8(_(" Save failed! Bummer. Document is lost.")) << endl;
273 bool BufferList::exists(string const & s) const
275 return find_if(bstore.begin(), bstore.end(),
276 bind(equal_to<string>(),
277 bind(&Buffer::absFileName, _1),
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(string const & s)
294 BufferStorage::iterator it =
295 find_if(bstore.begin(), bstore.end(),
296 bind(equal_to<string>(),
297 bind(&Buffer::absFileName, _1),
300 return it != bstore.end() ? (*it) : 0;
304 Buffer * BufferList::getBufferFromTmp(string const & s)
306 BufferStorage::iterator it = bstore.begin();
307 BufferStorage::iterator end = bstore.end();
308 for (; it < end; ++it)
309 if (prefixIs(s, (*it)->temppath()))
315 void BufferList::setCurrentAuthor(docstring const & name, docstring const & email)
317 BufferStorage::iterator it = bstore.begin();
318 BufferStorage::iterator end = bstore.end();
319 for (; it != end; ++it)
320 (*it)->params().authors().record(0, Author(name, email));
324 int BufferList::bufferNum(string const & name) const
326 vector<string> buffers = getFileNames();
327 vector<string>::const_iterator cit =
328 find(buffers.begin(), buffers.end(), name);
329 if (cit == buffers.end())
331 return int(cit - buffers.begin());