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