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/assert.hpp>
33 #include <boost/bind.hpp>
41 using namespace lyx::support;
45 namespace Alert = lyx::frontend::Alert;
48 BufferList::BufferList()
52 bool BufferList::empty() const
54 return bstore.empty();
58 BufferList::iterator BufferList::begin()
60 return bstore.begin();
64 BufferList::const_iterator BufferList::begin() const
66 return bstore.begin();
70 BufferList::iterator BufferList::end()
76 BufferList::const_iterator BufferList::end() const
82 void BufferList::release(Buffer * buf)
85 BufferStorage::iterator const it =
86 find(bstore.begin(), bstore.end(), buf);
87 if (it != bstore.end()) {
96 Buffer * BufferList::newBuffer(string const & s, bool const ronly)
98 auto_ptr<Buffer> tmpbuf;
100 tmpbuf.reset(new Buffer(s, ronly));
101 } catch (ExceptionMessage const & message) {
102 if (message.type_ == ErrorException) {
103 Alert::error(message.title_, message.details_);
105 } else if (message.type_ == WarningException) {
106 Alert::warning(message.title_, message.details_);
110 tmpbuf->params().useClassDefaults();
111 LYXERR(Debug::INFO, "Assigning to buffer " << bstore.size());
112 bstore.push_back(tmpbuf.get());
113 return tmpbuf.release();
117 void BufferList::closeAll()
119 while (!bstore.empty())
120 release(bstore.front());
124 vector<string> const BufferList::getFileNames() const
127 transform(bstore.begin(), bstore.end(),
129 boost::bind(&Buffer::absFileName, _1));
134 Buffer * BufferList::first()
138 return bstore.front();
142 Buffer * BufferList::last()
146 return bstore.back();
150 Buffer * BufferList::getBuffer(unsigned int choice)
152 if (choice >= bstore.size())
154 return bstore[choice];
158 Buffer * BufferList::next(Buffer const * buf) const
164 BufferStorage::const_iterator it = find(bstore.begin(),
166 BOOST_ASSERT(it != bstore.end());
168 if (it == bstore.end())
169 return bstore.front();
175 Buffer * BufferList::previous(Buffer const * buf) const
181 BufferStorage::const_iterator it = find(bstore.begin(),
183 BOOST_ASSERT(it != bstore.end());
184 if (it == bstore.begin())
185 return bstore.back();
191 void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
192 OutputParams const & runparams)
194 BufferStorage::iterator it = bstore.begin();
195 BufferStorage::iterator end = bstore.end();
196 for (; it != end; ++it) {
197 if (!(*it)->isDepClean(masterTmpDir)) {
198 string writefile = addName(masterTmpDir, (*it)->latexName());
199 (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
201 (*it)->markDepClean(masterTmpDir);
207 void BufferList::emergencyWriteAll()
209 for_each(bstore.begin(), bstore.end(),
210 bind(&BufferList::emergencyWrite, this, _1));
214 docstring BufferList::emergencyWrite(Buffer * buf)
216 // Use ::assert to avoid a loop, BOOST_ASSERT ends up calling ::assert
217 // compare with 0 to avoid pointer/interger comparison
218 // ::assert(buf != 0);
220 return _("No file open!");
222 // No need to save if the buffer has not changed.
226 string const doc = buf->isUnnamed()
227 ? onlyFilename(buf->absFileName()) : buf->absFileName();
229 docstring user_message = bformat(
230 _("LyX: Attempting to save document %1$s\n"), from_utf8(doc));
232 // We try to save three places:
233 // 1) Same place as document. Unless it is an unnamed doc.
234 if (!buf->isUnnamed()) {
235 string s = buf->absFileName();
237 lyxerr << " " << s << endl;
238 if (buf->writeFile(FileName(s))) {
240 user_message += _(" Save seems successful. Phew.\n");
243 user_message += _(" Save failed! Trying...\n");
247 // 2) In HOME directory.
248 string s = addName(package().home_dir().absFilename(), buf->absFileName());
250 lyxerr << ' ' << s << endl;
251 if (buf->writeFile(FileName(s))) {
253 user_message += _(" Save seems successful. Phew.\n");
257 user_message += _(" Save failed! Trying...\n");
259 // 3) In "/tmp" directory.
260 // MakeAbsPath to prepend the current
261 // drive letter on OS/2
262 s = addName(package().temp_dir().absFilename(), buf->absFileName());
264 lyxerr << ' ' << s << endl;
265 if (buf->writeFile(FileName(s))) {
267 user_message += _(" Save seems successful. Phew.\n");
271 user_message += _(" Save failed! Bummer. Document is lost.");
276 bool BufferList::exists(string const & s) const
278 return find_if(bstore.begin(), bstore.end(),
279 bind(equal_to<string>(),
280 bind(&Buffer::absFileName, _1),
286 bool BufferList::isLoaded(Buffer const * b) const
289 BufferStorage::const_iterator cit =
290 find(bstore.begin(), bstore.end(), b);
291 return cit != bstore.end();
295 Buffer * BufferList::getBuffer(string const & s)
297 BufferStorage::iterator it =
298 find_if(bstore.begin(), bstore.end(),
299 bind(equal_to<string>(),
300 bind(&Buffer::absFileName, _1),
303 return it != bstore.end() ? (*it) : 0;
307 Buffer * BufferList::getBufferFromTmp(string const & s)
309 BufferStorage::iterator it = bstore.begin();
310 BufferStorage::iterator end = bstore.end();
311 for (; it < end; ++it)
312 if (prefixIs(s, (*it)->temppath()))
318 void BufferList::setCurrentAuthor(docstring const & name, docstring const & email)
320 BufferStorage::iterator it = bstore.begin();
321 BufferStorage::iterator end = bstore.end();
322 for (; it != end; ++it)
323 (*it)->params().authors().record(0, Author(name, email));
327 int BufferList::bufferNum(string const & name) const
329 vector<string> buffers = getFileNames();
330 vector<string>::const_iterator cit =
331 find(buffers.begin(), buffers.end(), name);
332 if (cit == buffers.end())
334 return int(cit - buffers.begin());