10 #include "frontends/Dialogs.h"
12 #include "insetinclude.h"
14 #include "bufferlist.h"
15 #include "BufferView.h"
17 #include "support/filetools.h"
20 #include "LaTeXFeatures.h"
22 #include "support/FileInfo.h"
30 extern BufferList bufferlist;
34 string const unique_id()
36 static unsigned int seed = 1000;
39 ost << "file" << ++seed;
41 // Needed if we use lyxstring.
42 return ost.str().c_str();
48 InsetInclude::InsetInclude(Params const & p)
49 : params_(p), include_label(unique_id())
53 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
56 params_.masterFilename_ = b.fileName();
57 include_label = unique_id();
61 InsetInclude::~InsetInclude()
67 InsetInclude::Params const & InsetInclude::params() const
73 bool InsetInclude::Params::operator==(Params const & o) const
75 if (cparams == o.cparams && flag == o.flag &&
76 noload == o.noload && masterFilename_ == o.masterFilename_)
83 bool InsetInclude::Params::operator!=(Params const & o) const
89 void InsetInclude::set(Params const & p)
96 switch (params_.flag) {
101 command="verbatiminput";
107 command="verbatiminput*";
111 params_.cparams.setCmdName(command);
115 Inset * InsetInclude::clone(Buffer const & buffer, bool) const
118 p.masterFilename_ = buffer.fileName();
120 return new InsetInclude(p);
124 void InsetInclude::edit(BufferView * bv, int, int, unsigned int)
126 bv->owner()->getDialogs()->showInclude(this);
130 void InsetInclude::edit(BufferView * bv, bool)
136 void InsetInclude::write(Buffer const *, ostream & os) const
138 os << "Include " << params_.cparams.getCommand() << "\n";
142 void InsetInclude::read(Buffer const *, LyXLex & lex)
144 params_.cparams.read(lex);
146 if (params_.cparams.getCmdName() == "include")
147 params_.flag = INCLUDE;
148 else if (params_.cparams.getCmdName() == "input")
149 params_.flag = INPUT;
150 /* FIXME: is this logic necessary now ? */
151 else if (contains(params_.cparams.getCmdName(), "verbatim")) {
153 if (params_.cparams.getCmdName() == "verbatiminput*")
154 params_.flag = VERBAST;
159 bool InsetInclude::display() const
161 return !(params_.flag == INPUT);
165 string const InsetInclude::getScreenLabel() const
169 switch (params_.flag) {
170 case INPUT: temp += _("Input"); break;
171 case VERB: temp += _("Verbatim Input"); break;
172 case VERBAST: temp += _("Verbatim Input*"); break;
173 case INCLUDE: temp += _("Include"); break;
178 if (params_.cparams.getContents().empty())
181 temp += params_.cparams.getContents();
187 string const InsetInclude::getRelFileBaseName() const
189 return OnlyFilename(ChangeExtension(params_.cparams.getContents(), string()));
193 string const InsetInclude::getFileName() const
195 return MakeAbsPath(params_.cparams.getContents(),
196 OnlyPath(getMasterFilename()));
200 string const InsetInclude::getMasterFilename() const
202 return params_.masterFilename_;
206 bool InsetInclude::loadIfNeeded() const
208 if (params_.noload || isVerbatim())
211 if (!IsLyXFilename(getFileName()))
214 if (bufferlist.exists(getFileName()))
217 // the readonly flag can/will be wrong, not anymore I think.
218 FileInfo finfo(getFileName());
219 bool const ro = !finfo.writable();
220 return bufferlist.readFile(getFileName(), ro) != 0;
224 int InsetInclude::latex(Buffer const * buffer, ostream & os,
225 bool /*fragile*/, bool /*fs*/) const
227 string incfile(params_.cparams.getContents());
229 // Do nothing if no file name has been specified
233 if (loadIfNeeded()) {
234 Buffer * tmp = bufferlist.getBuffer(getFileName());
236 // FIXME: this should be a GUI warning
237 if (tmp->params.textclass != buffer->params.textclass) {
238 lyxerr << "WARNING: Included file `"
239 << MakeDisplayPath(getFileName())
240 << "' has textclass `"
241 << textclasslist.NameOfClass(tmp->params.textclass)
242 << "' while parent file has textclass `"
243 << textclasslist.NameOfClass(buffer->params.textclass)
248 // write it to a file (so far the complete file)
249 string writefile = ChangeExtension(getFileName(), ".tex");
251 if (!buffer->tmppath.empty()
252 && !buffer->niceFile) {
253 incfile = subst(incfile, '/','@');
255 incfile = subst(incfile, ':', '$');
257 writefile = AddName(buffer->tmppath, incfile);
259 writefile = getFileName();
260 writefile = ChangeExtension(writefile, ".tex");
261 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
262 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
264 tmp->markDepClean(buffer->tmppath);
266 tmp->makeLaTeXFile(writefile,
267 OnlyPath(getMasterFilename()),
268 buffer->niceFile, true);
272 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
273 } else if (params_.flag == INPUT) {
274 // \input wants file with extension (default is .tex)
275 if (!IsLyXFilename(getFileName())) {
276 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
278 os << '\\' << params_.cparams.getCmdName() << '{'
279 << ChangeExtension(incfile, ".tex")
283 // \include don't want extension and demands that the
284 // file really have .tex
285 os << '\\' << params_.cparams.getCmdName() << '{'
286 << ChangeExtension(incfile, string())
294 int InsetInclude::ascii(Buffer const *, std::ostream & os, int) const
297 os << GetFileContents(getFileName());
302 int InsetInclude::linuxdoc(Buffer const * buffer, ostream & os) const
304 string incfile(params_.cparams.getContents());
306 // Do nothing if no file name has been specified
310 if (loadIfNeeded()) {
311 Buffer * tmp = bufferlist.getBuffer(getFileName());
313 // write it to a file (so far the complete file)
314 string writefile = ChangeExtension(getFileName(), ".sgml");
315 if (!buffer->tmppath.empty() && !buffer->niceFile) {
316 incfile = subst(incfile, '/','@');
317 writefile = AddName(buffer->tmppath, incfile);
319 writefile = getFileName();
321 if (IsLyXFilename(getFileName()))
322 writefile = ChangeExtension(writefile, ".sgml");
324 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
325 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
327 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
331 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
332 << "\" format=\"linespecific\">"
333 << "</inlinegraphic>";
335 os << '&' << include_label << ';';
341 int InsetInclude::docBook(Buffer const * buffer, ostream & os) const
343 string incfile(params_.cparams.getContents());
345 // Do nothing if no file name has been specified
349 if (loadIfNeeded()) {
350 Buffer * tmp = bufferlist.getBuffer(getFileName());
352 // write it to a file (so far the complete file)
353 string writefile = ChangeExtension(getFileName(), ".sgml");
354 if (!buffer->tmppath.empty() && !buffer->niceFile) {
355 incfile = subst(incfile, '/','@');
356 writefile = AddName(buffer->tmppath, incfile);
358 writefile = getFileName();
359 if (IsLyXFilename(getFileName()))
360 writefile = ChangeExtension(writefile, ".sgml");
362 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
363 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
365 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
369 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
370 << "\" format=\"linespecific\">"
371 << "</inlinegraphic>";
373 os << '&' << include_label << ';';
379 void InsetInclude::validate(LaTeXFeatures & features) const
382 string incfile(params_.cparams.getContents());
385 Buffer const * const b = bufferlist.getBuffer(getMasterFilename());
387 if (b && !b->tmppath.empty() && b->niceFile) {
388 incfile = subst(incfile, '/','@');
389 writefile = AddName(b->tmppath, incfile);
391 writefile = getFileName();
393 if (IsLyXFilename(getFileName()))
394 writefile = ChangeExtension(writefile, ".sgml");
396 features.IncludedFiles[include_label] = writefile;
399 features.verbatim = true;
401 // Here we must do the fun stuff...
402 // Load the file in the include if it needs
404 if (loadIfNeeded()) {
406 Buffer const * const tmp = bufferlist.getBuffer(getFileName());
408 tmp->validate(features);
413 vector<string> const InsetInclude::getLabelList() const
417 if (loadIfNeeded()) {
418 Buffer * tmp = bufferlist.getBuffer(getFileName());
419 tmp->setParentName("");
420 l = tmp->getLabelList();
421 tmp->setParentName(getMasterFilename());
428 vector<pair<string,string> > const InsetInclude::getKeys() const
430 vector<pair<string,string> > keys;
432 if (loadIfNeeded()) {
433 Buffer * tmp = bufferlist.getBuffer(getFileName());
434 tmp->setParentName("");
435 keys = tmp->getBibkeyList();
436 tmp->setParentName(getMasterFilename());