]> git.lyx.org Git - lyx.git/blob - src/BufferList.cpp
LYX_CXX_GLOBAL_CSTD is not really useful anymore
[lyx.git] / src / BufferList.cpp
1 /**
2  * \file BufferList.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "BufferList.h"
14
15 #include "Author.h"
16 #include "Buffer.h"
17 #include "BufferParams.h"
18 #include "Session.h"
19 #include "LyX.h"
20 #include "output_latex.h"
21 #include "ParagraphList.h"
22
23 #include "frontends/alert.h"
24
25 #include "support/debug.h"
26 #include "support/filetools.h"
27 #include "support/gettext.h"
28 #include "support/lstrings.h"
29 #include "support/Package.h"
30
31 #include <boost/bind.hpp>
32
33 #include <algorithm>
34 #include <functional>
35
36 using boost::bind;
37
38 using namespace std;
39 using namespace lyx::support;
40
41 namespace lyx {
42
43 namespace Alert = lyx::frontend::Alert;
44
45
46 BufferList::BufferList()
47 {}
48
49
50 bool BufferList::empty() const
51 {
52         return bstore.empty();
53 }
54
55
56 BufferList::iterator BufferList::begin()
57 {
58         return bstore.begin();
59 }
60
61
62 BufferList::const_iterator BufferList::begin() const
63 {
64         return bstore.begin();
65 }
66
67
68 BufferList::iterator BufferList::end()
69 {
70         return bstore.end();
71 }
72
73
74 BufferList::const_iterator BufferList::end() const
75 {
76         return bstore.end();
77 }
78
79
80 void BufferList::release(Buffer * buf)
81 {
82         BOOST_ASSERT(buf);
83         BufferStorage::iterator const it =
84                 find(bstore.begin(), bstore.end(), buf);
85         if (it != bstore.end()) {
86                 Buffer * tmp = (*it);
87                 BOOST_ASSERT(tmp);
88                 bstore.erase(it);
89                 delete tmp;
90         }
91 }
92
93
94 Buffer * BufferList::newBuffer(string const & s, bool const ronly)
95 {
96         auto_ptr<Buffer> tmpbuf(new Buffer(s, ronly));
97         tmpbuf->params().useClassDefaults();
98         LYXERR(Debug::INFO, "Assigning to buffer " << bstore.size());
99         bstore.push_back(tmpbuf.get());
100         return tmpbuf.release();
101 }
102
103
104 void BufferList::closeAll()
105 {
106         while (!bstore.empty())
107                 release(bstore.front());
108 }
109
110
111 vector<string> const BufferList::getFileNames() const
112 {
113         vector<string> nvec;
114         transform(bstore.begin(), bstore.end(),
115                   back_inserter(nvec),
116                   boost::bind(&Buffer::absFileName, _1));
117         return nvec;
118 }
119
120
121 Buffer * BufferList::first()
122 {
123         if (bstore.empty())
124                 return 0;
125         return bstore.front();
126 }
127
128
129 Buffer * BufferList::last()
130 {
131         if (bstore.empty())
132                 return 0;
133         return bstore.back();
134 }
135
136
137 Buffer * BufferList::getBuffer(unsigned int choice)
138 {
139         if (choice >= bstore.size())
140                 return 0;
141         return bstore[choice];
142 }
143
144
145 Buffer * BufferList::next(Buffer const * buf) const
146 {
147         BOOST_ASSERT(buf);
148
149         if (bstore.empty())
150                 return 0;
151         BufferStorage::const_iterator it = find(bstore.begin(),
152                                                 bstore.end(), buf);
153         BOOST_ASSERT(it != bstore.end());
154         ++it;
155         if (it == bstore.end())
156                 return bstore.front();
157         else
158                 return *it;
159 }
160
161
162 Buffer * BufferList::previous(Buffer const * buf) const
163 {
164         BOOST_ASSERT(buf);
165
166         if (bstore.empty())
167                 return 0;
168         BufferStorage::const_iterator it = find(bstore.begin(),
169                                                 bstore.end(), buf);
170         BOOST_ASSERT(it != bstore.end());
171         if (it == bstore.begin())
172                 return bstore.back();
173         else
174                 return *(it - 1);
175 }
176
177
178 void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
179                                         OutputParams const & runparams)
180 {
181         BufferStorage::iterator it = bstore.begin();
182         BufferStorage::iterator end = bstore.end();
183         for (; it != end; ++it) {
184                 if (!(*it)->isDepClean(masterTmpDir)) {
185                         string writefile = addName(masterTmpDir, (*it)->latexName());
186                         (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
187                                              runparams, false);
188                         (*it)->markDepClean(masterTmpDir);
189                 }
190         }
191 }
192
193
194 void BufferList::emergencyWriteAll()
195 {
196         for_each(bstore.begin(), bstore.end(),
197                  bind(&BufferList::emergencyWrite, this, _1));
198 }
199
200
201 void BufferList::emergencyWrite(Buffer * buf)
202 {
203         // Use ::assert to avoid a loop, BOOST_ASSERT ends up calling ::assert
204         // compare with 0 to avoid pointer/interger comparison
205         // ::assert(buf != 0);
206         if (!buf)
207                 return;
208
209         // No need to save if the buffer has not changed.
210         if (buf->isClean())
211                 return;
212
213         string const doc = buf->isUnnamed()
214                 ? onlyFilename(buf->absFileName()) : buf->absFileName();
215
216         lyxerr << to_utf8(
217                 bformat(_("LyX: Attempting to save document %1$s"), from_utf8(doc)))
218                 << endl;
219
220         // We try to save three places:
221         // 1) Same place as document. Unless it is an unnamed doc.
222         if (!buf->isUnnamed()) {
223                 string s = buf->absFileName();
224                 s += ".emergency";
225                 lyxerr << "  " << s << endl;
226                 if (buf->writeFile(FileName(s))) {
227                         buf->markClean();
228                         lyxerr << to_utf8(_("  Save seems successful. Phew.")) << endl;
229                         return;
230                 } else {
231                         lyxerr << to_utf8(_("  Save failed! Trying...")) << endl;
232                 }
233         }
234
235         // 2) In HOME directory.
236         string s = addName(package().home_dir().absFilename(), buf->absFileName());
237         s += ".emergency";
238         lyxerr << ' ' << s << endl;
239         if (buf->writeFile(FileName(s))) {
240                 buf->markClean();
241                 lyxerr << to_utf8(_("  Save seems successful. Phew.")) << endl;
242                 return;
243         }
244
245         lyxerr << to_utf8(_("  Save failed! Trying...")) << endl;
246
247         // 3) In "/tmp" directory.
248         // MakeAbsPath to prepend the current
249         // drive letter on OS/2
250         s = addName(package().temp_dir().absFilename(), buf->absFileName());
251         s += ".emergency";
252         lyxerr << ' ' << s << endl;
253         if (buf->writeFile(FileName(s))) {
254                 buf->markClean();
255                 lyxerr << to_utf8(_("  Save seems successful. Phew.")) << endl;
256                 return;
257         }
258         lyxerr << to_utf8(_("  Save failed! Bummer. Document is lost.")) << endl;
259 }
260
261
262 bool BufferList::exists(string const & s) const
263 {
264         return find_if(bstore.begin(), bstore.end(),
265                        bind(equal_to<string>(),
266                             bind(&Buffer::absFileName, _1),
267                             s))
268                 != bstore.end();
269 }
270
271
272 bool BufferList::isLoaded(Buffer const * b) const
273 {
274         BOOST_ASSERT(b);
275         BufferStorage::const_iterator cit =
276                 find(bstore.begin(), bstore.end(), b);
277         return cit != bstore.end();
278 }
279
280
281 Buffer * BufferList::getBuffer(string const & s)
282 {
283         BufferStorage::iterator it =
284                 find_if(bstore.begin(), bstore.end(),
285                         bind(equal_to<string>(),
286                              bind(&Buffer::absFileName, _1),
287                              s));
288
289         return it != bstore.end() ? (*it) : 0;
290 }
291
292
293 Buffer * BufferList::getBufferFromTmp(string const & s)
294 {
295         BufferStorage::iterator it = bstore.begin();
296         BufferStorage::iterator end = bstore.end();
297         for (; it < end; ++it)
298                 if (prefixIs(s, (*it)->temppath()))
299                         return *it;
300         return 0;
301 }
302
303
304 void BufferList::setCurrentAuthor(docstring const & name, docstring const & email)
305 {
306         BufferStorage::iterator it = bstore.begin();
307         BufferStorage::iterator end = bstore.end();
308         for (; it != end; ++it)
309                 (*it)->params().authors().record(0, Author(name, email));
310 }
311
312
313 int BufferList::bufferNum(string const & name) const
314 {
315         vector<string> buffers = getFileNames();
316         vector<string>::const_iterator cit =
317                 find(buffers.begin(), buffers.end(), name);
318         if (cit == buffers.end())
319                 return 0;
320         return int(cit - buffers.begin());
321 }
322
323
324 } // namespace lyx