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/FileName.h"
28 #include "support/FileNameList.h"
29 #include "support/filetools.h"
30 #include "support/gettext.h"
31 #include "support/lstrings.h"
32 #include "support/Package.h"
34 #include "support/lassert.h"
41 using namespace lyx::support;
45 namespace Alert = lyx::frontend::Alert;
48 BufferList::BufferList()
52 BufferList::~BufferList()
54 BufferStorage::iterator it = binternal.begin();
55 BufferStorage::iterator end = binternal.end();
56 for (; it != end; ++it)
61 bool BufferList::empty() const
63 return bstore.empty();
67 BufferList::iterator BufferList::begin()
69 return bstore.begin();
73 BufferList::const_iterator BufferList::begin() const
75 return bstore.begin();
79 BufferList::iterator BufferList::end()
85 BufferList::const_iterator BufferList::end() const
91 void BufferList::release(Buffer * buf)
93 // We may leak here, but we probably do not need to
96 BufferStorage::iterator const it =
97 find(bstore.begin(), bstore.end(), buf);
98 if (it != bstore.end()) {
101 LASSERT(tmp, return);
107 Buffer * BufferList::newInternalBuffer(string const & s)
109 Buffer * const buf = createNewBuffer(s);
111 buf->setInternal(true);
112 binternal.push_back(buf);
118 Buffer * BufferList::newBuffer(string const & s)
120 Buffer * const buf = createNewBuffer(s);
122 LYXERR(Debug::INFO, "Assigning to buffer " << bstore.size());
123 bstore.push_back(buf);
129 Buffer * BufferList::createNewBuffer(string const & s)
131 unique_ptr<Buffer> tmpbuf;
133 tmpbuf = make_unique<Buffer>(s);
134 } catch (ExceptionMessage const & message) {
135 if (message.type_ == ErrorException) {
136 Alert::error(message.title_, message.details_);
138 } else if (message.type_ == WarningException) {
139 Alert::warning(message.title_, message.details_);
143 tmpbuf->params().useClassDefaults();
144 return tmpbuf.release();
148 void BufferList::closeAll()
150 while (!bstore.empty())
151 release(bstore.front());
155 FileNameList BufferList::fileNames() const
158 BufferStorage::const_iterator it = bstore.begin();
159 BufferStorage::const_iterator end = bstore.end();
160 for (; it != end; ++it) {
162 nvec.push_back(buf->fileName());
168 Buffer * BufferList::first()
172 return bstore.front();
176 Buffer * BufferList::last()
180 return bstore.back();
184 Buffer * BufferList::getBuffer(unsigned int choice)
186 if (choice >= bstore.size())
188 return bstore[choice];
192 Buffer * BufferList::next(Buffer const * buf) const
194 // Something is wrong, but we can probably survive it.
195 LASSERT(buf, return 0);
199 BufferStorage::const_iterator it =
200 find(bstore.begin(), bstore.end(), buf);
201 LASSERT(it != bstore.end(), return 0);
203 Buffer * nextbuf = (it == bstore.end()) ? bstore.front() : *it;
208 Buffer * BufferList::previous(Buffer const * buf) const
210 // Something is wrong, but we can probably survive it.
211 LASSERT(buf, return 0);
215 BufferStorage::const_iterator it =
216 find(bstore.begin(), bstore.end(), buf);
217 LASSERT(it != bstore.end(), return 0);
219 Buffer * previousbuf = (it == bstore.begin()) ? bstore.back() : *(it - 1);
224 void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
225 OutputParams const & runparams_in)
227 OutputParams runparams = runparams_in;
228 runparams.is_child = true;
229 BufferStorage::iterator it = bstore.begin();
230 BufferStorage::iterator end = bstore.end();
231 for (; it != end; ++it) {
232 if (!(*it)->isDepClean(masterTmpDir)) {
233 string writefile = addName(masterTmpDir, (*it)->latexName());
234 (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
235 runparams, Buffer::OnlyBody);
236 (*it)->markDepClean(masterTmpDir);
239 runparams.is_child = false;
243 void BufferList::emergencyWriteAll()
245 BufferStorage::const_iterator it = bstore.begin();
246 BufferStorage::const_iterator const en = bstore.end();
247 for (; it != en; ++it)
248 (*it)->emergencyWrite();
252 bool BufferList::exists(FileName const & fname) const
254 return getBuffer(fname) != 0;
258 bool BufferList::isLoaded(Buffer const * b) const
262 BufferStorage::const_iterator cit =
263 find(bstore.begin(), bstore.end(), b);
264 return cit != bstore.end();
268 bool BufferList::isOthersChild(Buffer * parent, Buffer * child)
270 LASSERT(parent, return false);
271 LASSERT(child, return false);
272 LASSERT(parent->isChild(child), return false);
274 // Does child document have a different parent?
275 Buffer const * parent_ = child->parent();
276 if (parent_ && parent_ != parent)
279 for(Buffer * buf : bstore)
280 if (buf != parent && buf->isChild(child))
286 Buffer * BufferList::getBuffer(support::FileName const & fname, bool internal) const
288 // 1) cheap test, using string comparison of file names
289 for (Buffer * b : bstore)
290 if (b->fileName() == fname)
292 // 2) possibly expensive test, using equivalence test of file names
293 for (Buffer * b : bstore)
294 if (equivalent(b->fileName(), fname))
297 // 1) cheap test, using string comparison of file names
298 for (Buffer * b : binternal)
299 if (b->fileName() == fname)
301 // 2) possibly expensive test, using equivalence test of file names
302 for (Buffer * b : binternal)
303 if (equivalent(b->fileName(), fname))
310 Buffer * BufferList::getBufferFromTmp(string const & s)
312 BufferStorage::iterator it = bstore.begin();
313 BufferStorage::iterator end = bstore.end();
314 for (; it < end; ++it) {
315 if (prefixIs(s, (*it)->temppath())) {
316 // check whether the filename matches the master
317 string const master_name = (*it)->latexName();
318 if (suffixIs(s, master_name))
320 // if not, try with the children
321 ListOfBuffers clist = (*it)->getDescendents();
322 ListOfBuffers::const_iterator cit = clist.begin();
323 ListOfBuffers::const_iterator cend = clist.end();
324 for (; cit != cend; ++cit) {
325 string const mangled_child_name = DocFileName(
326 changeExtension((*cit)->absFileName(),
327 ".tex")).mangledFileName();
328 if (suffixIs(s, mangled_child_name))
337 void BufferList::recordCurrentAuthor(Author const & author)
339 BufferStorage::iterator it = bstore.begin();
340 BufferStorage::iterator end = bstore.end();
341 for (; it != end; ++it)
342 (*it)->params().authors().recordCurrentAuthor(author);
346 void BufferList::updatePreviews()
348 BufferStorage::iterator it = bstore.begin();
349 BufferStorage::iterator end = bstore.end();
350 for (; it != end; ++it)
351 (*it)->updatePreviews();
355 int BufferList::bufferNum(FileName const & fname) const
357 FileNameList const buffers(fileNames());
358 FileNameList::const_iterator cit =
359 find(buffers.begin(), buffers.end(), fname);
360 if (cit == buffers.end())
362 return int(cit - buffers.begin());
366 void BufferList::changed(bool update_metrics) const
368 BufferStorage::const_iterator it = bstore.begin();
369 BufferStorage::const_iterator end = bstore.end();
370 for (; it != end; ++it)
371 (*it)->changed(update_metrics);
372 it = binternal.begin();
373 end = binternal.end();
374 for (; it != end; ++it)
375 (*it)->changed(update_metrics);