]> git.lyx.org Git - lyx.git/blob - src/buffer_funcs.C
e06b32ad843e0d6354117c149f9c1ff62d75b142
[lyx.git] / src / buffer_funcs.C
1 /**
2  * \file buffer_funcs.C
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  * \author Alfredo Braunstein
8  *
9  * Full author contact details are available in file CREDITS.
10  *
11  */
12
13 #include <config.h>
14
15 #include "buffer_funcs.h"
16
17 #include "buffer.h"
18 #include "bufferlist.h"
19 #include "bufferparams.h"
20 #include "errorlist.h"
21 #include "gettext.h"
22 #include "LaTeX.h"
23 #include "paragraph.h"
24 #include "lyxvc.h"
25 #include "texrow.h"
26 #include "vc-backend.h"
27
28 #include "frontends/Alert.h"
29
30 #include "support/FileInfo.h"
31 #include "support/filetools.h"
32 #include "support/lyxlib.h"
33
34
35 extern BufferList bufferlist;
36
37 using namespace lyx::support;
38
39
40 namespace {
41
42 bool readFile(Buffer * b, string const & s)
43 {
44         string ts(s);
45         string e = OnlyPath(s);
46         string a = e;
47         // File information about normal file
48         FileInfo fileInfo(s);
49
50         if (!fileInfo.exist()) {
51                 string const file = MakeDisplayPath(s, 50);
52                 string text = bformat(_("The specified document\n%1$s"
53                                         "\ncould not be read."), file);
54                 Alert::error(_("Could not read document"), text);
55                 return false;
56         }
57
58         // Check if emergency save file exists and is newer.
59         e += OnlyFilename(s) + ".emergency";
60         FileInfo fileInfoE(e);
61
62         bool use_emergency = false;
63
64         if (fileInfoE.exist() && fileInfo.exist()) {
65                 if (fileInfoE.getModificationTime()
66                     > fileInfo.getModificationTime()) {
67                         string const file = MakeDisplayPath(s, 20);
68                         string text = bformat(_("An emergency save of the document %1$s exists.\n"
69                                 "\nRecover emergency save?"), file);
70                         int const ret = Alert::prompt(_("Load emergency save?"),
71                                 text, 0, 1, _("&Recover"), _("&Load Original"));
72
73                         if (ret == 0) {
74                                 ts = e;
75                                 // the file is not saved if we load the
76                                 // emergency file.
77                                 b->markDirty();
78                                 use_emergency = true;
79                         }
80                 }
81         }
82
83         if (!use_emergency) {
84                 // Now check if autosave file is newer.
85                 a += '#';
86                 a += OnlyFilename(s);
87                 a += '#';
88                 FileInfo fileInfoA(a);
89                 if (fileInfoA.exist() && fileInfo.exist()) {
90                         if (fileInfoA.getModificationTime()
91                             > fileInfo.getModificationTime()) {
92                                 string const file = MakeDisplayPath(s, 20);
93                                 string text = bformat(_("The backup of the document %1$s is newer.\n\n"
94                                         "Load the backup instead?"), file);
95                                 int const ret = Alert::prompt(_("Load backup?"),
96                                         text, 0, 1, _("&Load backup"), _("Load &original"));
97
98                                 if (ret == 0) {
99                                         ts = a;
100                                         // the file is not saved if we load the
101                                         // autosave file.
102                                         b->markDirty();
103                                 } else {
104                                         // Here, we should delete the autosave
105                                         unlink(a);
106                                 }
107                         }
108                 }
109         }
110         return b->readFile(ts);
111 }
112
113
114 } // namespace anon
115
116
117
118 bool loadLyXFile(Buffer * b, string const & s)
119 {
120         switch (IsFileWriteable(s)) {
121         case 0:
122                 b->setReadonly(true);
123                 // Fall through
124         case 1:
125                 if (readFile(b, s)) {
126                         b->lyxvc().file_found_hook(s);
127                         return true;
128                 }
129                 break;
130         case -1:
131                 string const file = MakeDisplayPath(s, 20);
132                 // Here we probably should run
133                 if (LyXVC::file_not_found_hook(s)) {
134                         string text = bformat(_("Do you want to retrieve the document"
135                                 " %1$s from version control?"), file);
136                         int const ret = Alert::prompt(_("Retrieve from version control?"),
137                                 text, 0, 1, _("&Retrieve"), _("&Cancel"));
138
139                         if (ret == 0) {
140                                 // How can we know _how_ to do the checkout?
141                                 // With the current VC support it has to be,
142                                 // a RCS file since CVS do not have special ,v files.
143                                 RCS::retrieve(s);
144                                 return loadLyXFile(b, s);
145                         }
146                 }
147                 break;
148         }
149         return false;
150 }
151
152
153 Buffer * newFile(string const & filename, string const & templatename,
154                  bool isNamed)
155 {
156         // get a free buffer
157         Buffer * b = bufferlist.newBuffer(filename);
158
159         string tname;
160         // use defaults.lyx as a default template if it exists.
161         if (templatename.empty())
162                 tname = LibFileSearch("templates", "defaults.lyx");
163         else
164                 tname = templatename;
165
166         if (!tname.empty()) {
167                 if (!b->readFile(tname)) {
168                         string const file = MakeDisplayPath(tname, 50);
169                         string const text  = bformat(_("The specified document template\n%1$s\ncould not be read."), file);
170                         Alert::error(_("Could not read template"), text);
171                         // no template, start with empty buffer
172                         b->paragraphs().push_back(Paragraph());
173                         b->paragraphs().begin()->layout(b->params().getLyXTextClass().defaultLayout());
174                 }
175         } else {  // start with empty buffer
176                 b->paragraphs().push_back(Paragraph());
177                 b->paragraphs().begin()->layout(b->params().getLyXTextClass().defaultLayout());
178         }
179
180         if (!isNamed) {
181                 b->setUnnamed();
182                 b->setFileName(filename);
183         }
184
185         b->setReadonly(false);
186         b->updateDocLang(b->params().language);
187
188         return b;
189 }
190
191
192 void bufferErrors(Buffer const & buf, TeXErrors const & terr)
193 {
194         TeXErrors::Errors::const_iterator cit = terr.begin();
195         TeXErrors::Errors::const_iterator end = terr.end();
196
197         for (; cit != end; ++cit) {
198                 int par_id = -1;
199                 int posstart = -1;
200                 int const errorrow = cit->error_in_line;
201                 buf.texrow().getIdFromRow(errorrow, par_id, posstart);
202                 int posend = -1;
203                 buf.texrow().getIdFromRow(errorrow + 1, par_id, posend);
204                 buf.error(ErrorItem(cit->error_desc,
205                                          cit->error_text,
206                                          par_id, posstart, posend));
207         }
208 }
209
210
211 void bufferErrors(Buffer const & buf, ErrorList const & el)
212 {
213         ErrorList::const_iterator it = el.begin();
214         ErrorList::const_iterator end = el.end();
215
216         for (; it != end; ++it)
217                 buf.error(*it);
218 }
219
220
221 string const BufferFormat(Buffer const & buffer)
222 {
223         if (buffer.isLinuxDoc())
224                 return "linuxdoc";
225         else if (buffer.isDocBook())
226                 return "docbook";
227         else if (buffer.isLiterate())
228                 return "literate";
229         else
230                 return "latex";
231 }