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