]> git.lyx.org Git - lyx.git/blob - src/insets/insetinclude.C
fix compilation pb ; update eu.po
[lyx.git] / src / insets / insetinclude.C
1
2 #include <config.h>
3
4 #include <cstdlib>
5
6 #ifdef __GNUG__
7 #pragma implementation
8 #endif
9
10 #include "frontends/Dialogs.h"
11
12 #include "insetinclude.h"
13 #include "buffer.h"
14 #include "bufferlist.h"
15 #include "debug.h"
16 #include "support/filetools.h"
17 #include "lyxrc.h"
18 #include "LyXView.h"
19 #include "LaTeXFeatures.h"
20 #include "gettext.h"
21 #include "support/FileInfo.h"
22 #include "layout.h"
23
24 using std::ostream;
25 using std::endl;
26 using std::vector;
27 using std::pair;
28
29 extern BufferList bufferlist;
30
31 namespace {
32
33 string const unique_id()
34 {
35         static unsigned int seed = 1000;
36
37         std::ostringstream ost;
38         ost << "file" << ++seed;
39
40         // Needed if we use lyxstring.
41         return ost.str().c_str();
42 }
43
44 } // namespace anon
45
46
47 InsetInclude::InsetInclude(Params const & p)
48         : params_(p), include_label(unique_id())
49 {}
50
51
52 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
53 {
54         params_.cparams = p;
55         params_.masterFilename_ = b.fileName();
56         include_label = unique_id();
57 }
58
59
60 InsetInclude::~InsetInclude()
61 {
62         hideDialog();
63 }
64
65
66 InsetInclude::Params const & InsetInclude::params() const
67 {
68         return params_;
69 }
70
71
72 bool InsetInclude::Params::operator==(Params const & o) const
73 {
74         if (cparams == o.cparams && flag == o.flag &&
75             noload == o.noload && masterFilename_ == o.masterFilename_)
76                 return true;
77         
78         return false;
79 }
80
81
82 bool InsetInclude::Params::operator!=(Params const & o) const
83 {
84         return !(*this == o);
85 }
86
87
88 void InsetInclude::set(Params const & p)
89 {
90         params_ = p;
91
92         // Just to be safe...
93         string command;
94  
95         switch (params_.flag) {
96                 case INCLUDE:
97                         command="include";
98                         break;
99                 case VERB:
100                         command="verbatiminput";
101                         break;
102                 case INPUT:
103                         command="input";
104                         break;
105                 case VERBAST:
106                         command="verbatiminput*";
107                         break;
108         }
109  
110         params_.cparams.setCmdName(command);
111 }
112
113
114 Inset * InsetInclude::Clone(Buffer const & buffer) const
115 {
116         Params p(params_);
117         p.masterFilename_ = buffer.fileName();
118
119         return new InsetInclude(p);
120 }
121
122
123 void InsetInclude::Edit(BufferView * bv, int, int, unsigned int)
124 {
125         bv->owner()->getDialogs()->showInclude(this);
126 }
127
128
129 void InsetInclude::Write(Buffer const *, ostream & os) const
130 {
131         os << "Include " << params_.cparams.getCommand() << "\n";
132 }
133
134
135 void InsetInclude::Read(Buffer const *, LyXLex & lex)
136 {
137         params_.cparams.Read(lex);
138    
139         if (params_.cparams.getCmdName() == "include")
140                 params_.flag = INCLUDE;
141         else if (params_.cparams.getCmdName() == "input")
142                 params_.flag = INPUT;
143         /* FIXME: is this logic necessary now ? */
144         else if (contains(params_.cparams.getCmdName(), "verbatim")) {
145                 params_.flag = VERB;
146                 if (params_.cparams.getCmdName() == "verbatiminput*")
147                         params_.flag = VERBAST;
148         }
149 }
150
151
152 bool InsetInclude::display() const
153 {
154         return !(params_.flag == INPUT);
155 }
156
157
158 string const InsetInclude::getScreenLabel() const
159 {
160         string temp;
161
162         switch (params_.flag) {
163                 case INPUT: temp += _("Input"); break;
164                 case VERB: temp += _("Verbatim Input"); break;
165                 case VERBAST: temp += _("Verbatim Input*"); break;
166                 case INCLUDE: temp += _("Include"); break;
167         }
168
169         temp += ": ";
170         
171         if (params_.cparams.getContents().empty())
172                 temp += "???";
173         else
174                 temp += params_.cparams.getContents();
175
176         return temp;
177 }
178
179
180 string const InsetInclude::getRelFileBaseName() const
181 {
182         return OnlyFilename(ChangeExtension(params_.cparams.getContents(), string()));
183 }
184
185  
186 string const InsetInclude::getFileName() const
187 {
188         return MakeAbsPath(params_.cparams.getContents(),
189                            OnlyPath(getMasterFilename()));
190 }
191
192
193 string const InsetInclude::getMasterFilename() const
194 {
195         return params_.masterFilename_;
196 }
197
198
199 bool InsetInclude::loadIfNeeded() const
200 {
201         if (params_.noload || isVerbatim())
202                 return false;
203
204         if (!IsLyXFilename(getFileName()))
205                 return false;
206         
207         if (bufferlist.exists(getFileName()))
208                 return true;
209         
210         // the readonly flag can/will be wrong, not anymore I think.
211         FileInfo finfo(getFileName());
212         bool const ro = !finfo.writable();
213         return bufferlist.readFile(getFileName(), ro) != 0;
214 }
215
216
217 int InsetInclude::Latex(Buffer const * buffer, ostream & os,
218                         bool /*fragile*/, bool /*fs*/) const
219 {
220         string incfile(params_.cparams.getContents());
221         
222         // Do nothing if no file name has been specified
223         if (incfile.empty())
224                 return 0;
225    
226         if (loadIfNeeded()) {
227                 Buffer * tmp = bufferlist.getBuffer(getFileName());
228
229                 // FIXME: this should be a GUI warning
230                 if (tmp->params.textclass != buffer->params.textclass) {
231                         lyxerr << "WARNING: Included file `"
232                                << MakeDisplayPath(getFileName())
233                                << "' has textclass `"
234                                << textclasslist.NameOfClass(tmp->params.textclass)
235                                << "' while parent file has textclass `"
236                                << textclasslist.NameOfClass(buffer->params.textclass)
237                                << "'." << endl;
238                         //return 0;
239                 }
240                 
241                 // write it to a file (so far the complete file)
242                 string writefile = ChangeExtension(getFileName(), ".tex");
243
244                 if (!buffer->tmppath.empty()
245                     && !buffer->niceFile) {
246                         incfile = subst(incfile, '/','@');
247 #ifdef __EMX__
248                         incfile = subst(incfile, ':', '$');
249 #endif
250                         writefile = AddName(buffer->tmppath, incfile);
251                 } else
252                         writefile = getFileName();
253                 writefile = ChangeExtension(writefile, ".tex");
254                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
255                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
256                 
257                 tmp->markDepClean(buffer->tmppath);
258                 
259                 tmp->makeLaTeXFile(writefile,
260                                    OnlyPath(getMasterFilename()),
261                                    buffer->niceFile, true);
262         }
263
264         if (isVerbatim()) {
265                 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
266         } else if (params_.flag == INPUT) {
267                 // \input wants file with extension (default is .tex)
268                 if (!IsLyXFilename(getFileName())) {
269                         os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
270                 } else {
271                         os << '\\' << params_.cparams.getCmdName() << '{'
272                            << ChangeExtension(incfile, ".tex")
273                            <<  '}';
274                 }
275         } else {
276                 // \include don't want extension and demands that the
277                 // file really have .tex
278                 os << '\\' << params_.cparams.getCmdName() << '{'
279                    << ChangeExtension(incfile, string())
280                    << '}';
281         }
282
283         return 0;
284 }
285
286
287 int InsetInclude::Ascii(Buffer const *, std::ostream & os, int) const
288 {
289         if (isVerbatim())
290                 os << GetFileContents(getFileName());
291         return 0;
292 }
293
294
295 int InsetInclude::Linuxdoc(Buffer const * buffer, ostream & os) const
296 {
297         string incfile(params_.cparams.getContents());
298         
299         // Do nothing if no file name has been specified
300         if (incfile.empty())
301                 return 0;
302    
303         if (loadIfNeeded()) {
304                 Buffer * tmp = bufferlist.getBuffer(getFileName());
305
306                 // write it to a file (so far the complete file)
307                 string writefile = ChangeExtension(getFileName(), ".sgml");
308                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
309                         incfile = subst(incfile, '/','@');
310                         writefile = AddName(buffer->tmppath, incfile);
311                 } else
312                         writefile = getFileName();
313
314                 if (IsLyXFilename(getFileName()))
315                         writefile = ChangeExtension(writefile, ".sgml");
316
317                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
318                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
319                 
320                 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
321         }
322
323         if (isVerbatim()) {
324                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
325                    << "\" format=\"linespecific\">"
326                    << "</inlinegraphic>";
327         } else
328                 os << '&' << include_label << ';';
329         
330         return 0;
331 }
332
333
334 int InsetInclude::DocBook(Buffer const * buffer, ostream & os) const
335 {
336         string incfile(params_.cparams.getContents());
337
338         // Do nothing if no file name has been specified
339         if (incfile.empty())
340                 return 0;
341    
342         if (loadIfNeeded()) {
343                 Buffer * tmp = bufferlist.getBuffer(getFileName());
344
345                 // write it to a file (so far the complete file)
346                 string writefile = ChangeExtension(getFileName(), ".sgml");
347                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
348                         incfile = subst(incfile, '/','@');
349                         writefile = AddName(buffer->tmppath, incfile);
350                 } else
351                         writefile = getFileName();
352                 if (IsLyXFilename(getFileName()))
353                         writefile = ChangeExtension(writefile, ".sgml");
354
355                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
356                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
357                 
358                 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
359         }
360
361         if (isVerbatim()) {
362                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
363                    << "\" format=\"linespecific\">"
364                    << "</inlinegraphic>";
365         } else
366                 os << '&' << include_label << ';';
367         
368         return 0;
369 }
370
371
372 void InsetInclude::Validate(LaTeXFeatures & features) const
373 {
374
375         string incfile(params_.cparams.getContents());
376         string writefile;
377
378         Buffer const * const b = bufferlist.getBuffer(getMasterFilename());
379
380         if (b && !b->tmppath.empty() && b->niceFile) {
381                 incfile = subst(incfile, '/','@');
382                 writefile = AddName(b->tmppath, incfile);
383         } else
384                 writefile = getFileName();
385
386         if (IsLyXFilename(getFileName()))
387                 writefile = ChangeExtension(writefile, ".sgml");
388
389         features.IncludedFiles[include_label] = writefile;
390
391         if (isVerbatim())
392                 features.verbatim = true;
393
394         // Here we must do the fun stuff...
395         // Load the file in the include if it needs
396         // to be loaded:
397         if (loadIfNeeded()) {
398                 // a file got loaded
399                 Buffer const * const tmp = bufferlist.getBuffer(getFileName());
400                 if (tmp)
401                         tmp->validate(features);
402         }
403 }
404
405
406 vector<string> const InsetInclude::getLabelList() const
407 {
408         vector<string> l;
409
410         if (loadIfNeeded()) {
411                 Buffer * tmp = bufferlist.getBuffer(getFileName());
412                 tmp->setParentName("");
413                 l = tmp->getLabelList();
414                 tmp->setParentName(getMasterFilename());
415         }
416
417         return l;
418 }
419
420
421 vector<pair<string,string> > const InsetInclude::getKeys() const
422 {
423         vector<pair<string,string> > keys;
424         
425         if (loadIfNeeded()) {
426                 Buffer * tmp = bufferlist.getBuffer(getFileName());
427                 tmp->setParentName("");
428                 keys = tmp->getBibkeyList();
429                 tmp->setParentName(getMasterFilename());
430         }
431         
432         return keys;
433 }