]> git.lyx.org Git - lyx.git/blob - src/insets/insetexternal.C
More header file include dependency work
[lyx.git] / src / insets / insetexternal.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *      
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2001 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include <cstdio>
18 #include <utility>
19
20 #include "insetexternal.h"
21 #include "ExternalTemplate.h"
22 #include "BufferView.h"
23 #include "buffer.h"
24 #include "LyXView.h"
25 #include "frontends/Dialogs.h"
26 #include "lyx_main.h"
27 #include "LaTeXFeatures.h"
28 #include "support/filetools.h"
29 #include "support/lstrings.h"
30 #include "support/path.h"
31 #include "support/syscall.h"
32 #include "gettext.h"
33 #include "debug.h"
34
35 using std::endl;
36
37 InsetExternal::InsetExternal() 
38         : view_(0)
39 {
40         tempname_ = lyx::tempName(string(), "lyxext");
41         //ExternalTemplateManager::Templates::const_iterator i1;
42         params_.templ = ExternalTemplateManager::get().getTemplates().begin()->second;
43 }
44
45
46 InsetExternal::~InsetExternal()
47 {
48         lyx::unlink(tempname_);
49         hideDialog();
50 }
51
52
53 InsetExternal::Params InsetExternal::params() const
54 {
55         return params_;
56 }
57  
58  
59 void InsetExternal::setFromParams(Params const & p)
60 {
61         params_.filename = p.filename;
62         params_.parameters = p.parameters;
63         params_.templ = p.templ;
64 }      
65
66
67 string const InsetExternal::editMessage() const
68 {
69         return doSubstitution(0, params_.templ.guiName);
70 }
71
72
73 void InsetExternal::edit(BufferView * bv,
74                          int /*x*/, int /*y*/, unsigned int /*button*/)
75 {
76         view_ = bv;
77         view_->owner()->getDialogs()->showExternal(this);
78 }
79
80
81 void InsetExternal::edit(BufferView * bv, bool)
82 {
83         edit(bv, 0, 0, 0);
84 }
85
86
87 void InsetExternal::write(Buffer const *, std::ostream & os) const
88 {
89         os << "External " << params_.templ.lyxName << ",\"" << params_.filename 
90            << "\",\"" << params_.parameters << "\"\n";
91 }
92
93
94 void InsetExternal::read(Buffer const *, LyXLex & lex)
95 {
96         string format;
97         string token;
98
99         // Read inset data from lex and store in format
100         if (lex.EatLine()) {
101                 format = lex.GetString();
102         } else
103                 lex.printError("InsetExternal: Parse error: `$$Token'");
104         while (lex.IsOK()) {
105                 lex.nextToken();
106                 token = lex.GetString();
107                 if (token == "\\end_inset")
108                         break;
109         }
110         if (token != "\\end_inset") {
111                 lex.printError("Missing \\end_inset at this point. "
112                                "Read: `$$Token'");
113         }
114
115         // Parse string format...
116         string::size_type const pos1 = format.find(",");
117         params_.templ = ExternalTemplateManager::get().getTemplateByName(format.substr(0, pos1));
118         string::size_type const pos2 = format.find("\",\"", pos1);
119         params_.filename = format.substr(pos1 + 2, pos2 - (pos1 + 2));
120         params_.parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4));
121
122         lyxerr[Debug::INFO] << "InsetExternal::Read: " << params_.templ.lyxName
123                             << " " << params_.filename
124                             << " " << params_.parameters << endl;
125 }
126
127
128 int InsetExternal::write(string const & format,
129                          Buffer const * buf, std::ostream & os) const
130 {
131         ExternalTemplate const & et = params_.templ;
132         ExternalTemplate::Formats::const_iterator cit =
133                 et.formats.find(format);
134         if (cit == et.formats.end()) {
135                 lyxerr << "External template format '" << format
136                        << "' not specified in template " << params_.templ.lyxName
137                        << endl;
138                 return 0;
139         }
140         
141         if (et.automaticProduction) {
142                 executeCommand(doSubstitution(buf,
143                                               cit->second.updateCommand),
144                                buf);
145         }
146         
147         os << doSubstitution(buf, cit->second.product);
148         return 0; // CHECK  (FIXME check what ? - jbl)
149 }
150
151
152 int InsetExternal::latex(Buffer const * buf,
153                          std::ostream & os, bool, bool) const
154 {
155         return write("LaTeX", buf, os);
156 }
157
158
159 int InsetExternal::ascii(Buffer const * buf, std::ostream & os, int) const
160 {
161         return write("Ascii", buf, os);
162 }
163
164
165 int InsetExternal::linuxdoc(Buffer const * buf, std::ostream & os) const
166 {
167         return write("LinuxDoc", buf, os);
168 }
169
170
171 int InsetExternal::docBook(Buffer const * buf, std::ostream & os) const
172 {
173         return write("DocBook", buf, os);
174 }
175
176
177 void InsetExternal::validate(LaTeXFeatures & features) const
178 {
179         ExternalTemplate const & et = params_.templ;
180         ExternalTemplate::Formats::const_iterator cit =
181                 et.formats.find("LaTeX");
182
183         if (cit == et.formats.end())
184                 return;
185         
186         if (!cit->second.requirement.empty()) {
187                 features.require(cit->second.requirement);
188         }
189         if (!cit->second.preamble.empty()) {
190                 features.externalPreambles += cit->second.preamble + "\n";
191         }
192 }
193
194
195 Inset * InsetExternal::clone(Buffer const &, bool same_id) const
196 {
197         InsetExternal * inset = new InsetExternal();
198         inset->params_ = params_;
199         inset->view_ = view_;
200         if (same_id)
201                 inset->id_ = id_;
202         return inset;
203 }
204
205
206 string const InsetExternal::getScreenLabel(Buffer const *) const
207 {
208         ExternalTemplate const & et = params_.templ;
209         if (et.guiName.empty())
210                 return _("External");
211         else
212                 return doSubstitution(0, et.guiName);
213 }
214
215
216 void InsetExternal::executeCommand(string const & s,
217                                    Buffer const * buffer) const
218 {
219         string buf = MakeAbsPath(buffer->fileName());
220         string path = OnlyPath(buf);
221         Path p(path);
222         Systemcalls one;
223         if (lyxerr.debugging()) {
224                 lyxerr << "Executing '" << s << "' in '"
225                        << path << "'" << endl;
226         }
227         one.startscript(Systemcalls::Wait, s);
228 }
229
230
231 string const InsetExternal::doSubstitution(Buffer const * buffer,
232                                      string const & s) const
233 {
234         string result;
235         string const basename = ChangeExtension(params_.filename, string());
236         result = subst(s, "$$FName", params_.filename);
237         result = subst(result, "$$Basename", basename);
238         result = subst(result, "$$Parameters", params_.parameters);
239         result = ReplaceEnvironmentPath(result);
240         result = subst(result, "$$Tempname", tempname_);
241         result = subst(result, "$$Sysdir", system_lyxdir);
242         
243         // Handle the $$Contents(filename) syntax
244         if (contains(result, "$$Contents(\"")) {
245
246                 string::size_type const pos = result.find("$$Contents(\"");
247                 string::size_type const end = result.find("\")", pos);
248                 string const file = result.substr(pos + 12, end - (pos + 12));
249                 string contents;
250                 if (buffer) {
251                         // Make sure we are in the directory of the buffer
252                         string const buf = MakeAbsPath(buffer->fileName());
253                         string const path = OnlyPath(buf);
254                         Path p(path);
255                         contents = GetFileContents(file);
256                 } else {
257                         contents = GetFileContents(file);
258                 }
259                 result = subst(result,
260                                ("$$Contents(\"" + file + "\")").c_str(),
261                                contents);
262         }
263
264         return result;
265 }
266
267
268 void InsetExternal::updateExternal() const
269 {
270         ExternalTemplate const & et = params_.templ;
271         ExternalTemplate::Formats::const_iterator cit =
272                 et.formats.find("LaTeX");
273         if (cit == et.formats.end())
274                 return;
275         
276         executeCommand(doSubstitution(view_->buffer(),
277                                       cit->second.updateCommand),
278                        view_->buffer());
279 }
280
281
282 void InsetExternal::viewExternal() const
283 {
284         ExternalTemplate const & et = params_.templ;
285         if (et.automaticProduction)
286                 updateExternal();
287
288         executeCommand(doSubstitution(view_->buffer(),
289                                       et.viewCommand),
290                        view_->buffer());
291 }
292
293
294 void InsetExternal::editExternal() const
295 {
296         ExternalTemplate const & et = params_.templ;
297         if (et.automaticProduction)
298                 updateExternal();
299
300         executeCommand(doSubstitution(view_->buffer(),
301                                       et.editCommand),
302                        view_->buffer());
303 }
304
305
306 bool operator==(InsetExternal::Params const & left,
307                 InsetExternal::Params const & right)
308 {
309         return ((left.filename   == right.filename) &&
310                 (left.parameters == right.parameters) &&
311                 (left.templ.lyxName == right.templ.lyxName));
312 }
313
314
315 bool operator!=(InsetExternal::Params const & left,
316                 InsetExternal::Params const & right)
317 {
318         return  !(left == right);
319 }
320