]> git.lyx.org Git - lyx.git/blob - src/buffer_funcs.C
move some selection related stuff over to textcursor.C
[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 #include "bufferlist.h"
17 #include "buffer.h"
18 #include "errorlist.h"
19 #include "gettext.h"
20 #include "vc-backend.h"
21 #include "lyxlex.h"
22 #include "LaTeX.h"
23 #include "ParagraphList.h"
24 #include "paragraph.h"
25
26 #include "frontends/Alert.h"
27
28 #include "support/filetools.h"
29 #include "support/FileInfo.h"
30 #include "support/lyxlib.h"
31
32
33 extern BufferList bufferlist;
34
35
36 namespace {
37
38 bool readFile(Buffer * b, string const & s)
39 {
40         string ts(s);
41         string e = OnlyPath(s);
42         string a = e;
43         // File information about normal file
44         FileInfo fileInfo(s);
45
46         if (!fileInfo.exist()) {
47                 string const file = MakeDisplayPath(s, 50);
48                 string text = bformat(_("The specified document\n%1$s"
49                                         "\ncould not be read."), file);
50                 Alert::error(_("Could not read document"), text);
51                 return false;
52         }
53
54         // Check if emergency save file exists and is newer.
55         e += OnlyFilename(s) + ".emergency";
56         FileInfo fileInfoE(e);
57
58         bool use_emergency = false;
59
60         if (fileInfoE.exist() && fileInfo.exist()) {
61                 if (fileInfoE.getModificationTime()
62                     > fileInfo.getModificationTime()) {
63                         string const file = MakeDisplayPath(s, 20);
64                         string text = bformat(_("An emergency save of the document %1$s exists.\n"
65                                 "\nRecover emergency save?"), file);
66                         int const ret = Alert::prompt(_("Load emergency save?"),
67                                 text, 0, 1, _("&Recover"), _("&Load Original"));
68
69                         if (ret == 0) {
70                                 ts = e;
71                                 // the file is not saved if we load the
72                                 // emergency file.
73                                 b->markDirty();
74                                 use_emergency = true;
75                         }
76                 }
77         }
78
79         if (!use_emergency) {
80                 // Now check if autosave file is newer.
81                 a += '#';
82                 a += OnlyFilename(s);
83                 a += '#';
84                 FileInfo fileInfoA(a);
85                 if (fileInfoA.exist() && fileInfo.exist()) {
86                         if (fileInfoA.getModificationTime()
87                             > fileInfo.getModificationTime()) {
88                                 string const file = MakeDisplayPath(s, 20);
89                                 string text = bformat(_("The backup of the document %1$s is newer.\n\n"
90                                         "Load the backup instead?"), file);
91                                 int const ret = Alert::prompt(_("Load backup?"),
92                                         text, 0, 1, _("&Load backup"), _("Load &original"));
93
94                                 if (ret == 0) {
95                                         ts = a;
96                                         // the file is not saved if we load the
97                                         // autosave file.
98                                         b->markDirty();
99                                 } else {
100                                         // Here, we should delete the autosave
101                                         lyx::unlink(a);
102                                 }
103                         }
104                 }
105         }
106         // not sure if this is the correct place to begin LyXLex
107         LyXLex lex(0, 0);
108         lex.setFile(ts);
109
110         return b->readFile(lex, 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                 bool templateok = false;
168                 LyXLex lex(0, 0);
169                 lex.setFile(tname);
170                 if (lex.isOK()) {
171                         if (b->readFile(lex, tname)) {
172                                 templateok = true;
173                         }
174                 }
175                 if (!templateok) {
176                         string const file = MakeDisplayPath(tname, 50);
177                         string text  = bformat(_("The specified document template\n%1$s\n"
178                                 "could not be read."), file);
179                         Alert::error(_("Could not read template"), text);
180                         // no template, start with empty buffer
181                         b->paragraphs.push_back(Paragraph());
182                         b->paragraphs.begin()->layout(b->params.getLyXTextClass().defaultLayout());
183                 }
184         } else {  // start with empty buffer
185                 b->paragraphs.push_back(Paragraph());
186                 b->paragraphs.begin()->layout(b->params.getLyXTextClass().defaultLayout());
187         }
188
189         if (!isNamed) {
190                 b->setUnnamed();
191                 b->setFileName(filename);
192         }
193
194         b->setReadonly(false);
195         b->updateDocLang(b->params.language);
196
197         return b;
198 }
199
200
201 void parseErrors(Buffer const & buf, TeXErrors const & terr) 
202 {
203         TeXErrors::Errors::const_iterator cit = terr.begin();
204         TeXErrors::Errors::const_iterator end = terr.end();
205
206         for (; cit != end; ++cit) {
207                 int par_id = -1;
208                 int posstart = -1;
209                 int const errorrow = cit->error_in_line;
210                 buf.texrow.getIdFromRow(errorrow, par_id, posstart);
211                 int posend = -1;
212                 buf.texrow.getIdFromRow(errorrow + 1, par_id, posend);
213                 buf.parseError(ErrorItem(cit->error_desc,
214                                          cit->error_text,
215                                          par_id, posstart, posend));
216         }
217 }
218
219
220 void parseErrors(Buffer const & buf, ErrorList const & el) 
221 {
222         ErrorList::const_iterator it = el.begin();
223         ErrorList::const_iterator end = el.end();
224
225         for (; it != end; ++it) 
226                 buf.parseError(*it);
227 }
228
229
230 string const BufferFormat(Buffer const & buffer)
231 {
232         if (buffer.isLinuxDoc())
233                 return "linuxdoc";
234         else if (buffer.isDocBook())
235                 return "docbook";
236         else if (buffer.isLiterate())
237                 return "literate";
238         else
239                 return "latex";
240 }