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