]> git.lyx.org Git - features.git/blob - src/insets/InsetERT.cpp
Use new display() values to remove some inset hardcoding.
[features.git] / src / insets / InsetERT.cpp
1 /**
2  * \file InsetERT.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetERT.h"
15
16 #include "Buffer.h"
17 #include "BufferParams.h"
18 #include "BufferView.h"
19 #include "Cursor.h"
20 #include "CutAndPaste.h"
21 #include "DispatchResult.h"
22 #include "Format.h"
23 #include "FuncRequest.h"
24 #include "FuncStatus.h"
25 #include "Language.h"
26 #include "Layout.h"
27 #include "Lexer.h"
28 #include "LyXAction.h"
29 #include "OutputParams.h"
30 #include "ParagraphParameters.h"
31 #include "Paragraph.h"
32 #include "TextClass.h"
33
34 #include "support/docstream.h"
35 #include "support/FileName.h"
36 #include "support/gettext.h"
37 #include "support/lstrings.h"
38 #include "support/TempFile.h"
39
40 #include <sstream>
41
42 using namespace std;
43 using namespace lyx::support;
44
45 namespace lyx {
46
47 InsetERT::InsetERT(Buffer * buf, CollapseStatus status)
48         : InsetCollapsible(buf)
49 {
50         status_ = status;
51 }
52
53
54 // Do not copy the temp file on purpose: If a copy of an inset which is
55 // currently being edited is made, then we simply copy the current contents.
56 InsetERT::InsetERT(InsetERT const & that) : InsetCollapsible(that)
57 {}
58
59
60 InsetERT & InsetERT::operator=(InsetERT const & that)
61 {
62         if (&that == this)
63                 return *this;
64         tempfile_.reset();
65         return *this;
66 }
67
68
69 void InsetERT::write(ostream & os) const
70 {
71         os << "ERT" << "\n";
72         InsetCollapsible::write(os);
73 }
74
75
76 int InsetERT::plaintext(odocstringstream & os,
77         OutputParams const & rp, size_t max_length) const
78 {
79         if (!rp.inIndexEntry)
80                 // do not output TeX code
81                 return 0;
82
83         ParagraphList::const_iterator par = paragraphs().begin();
84         ParagraphList::const_iterator end = paragraphs().end();
85
86         while (par != end && os.str().size() <= max_length) {
87                 pos_type siz = par->size();
88                 for (pos_type i = 0; i < siz; ++i) {
89                         char_type const c = par->getChar(i);
90                         // output the active characters
91                         switch (c) {
92                         case '|':
93                         case '!':
94                         case '@':
95                                 os.put(c);
96                                 break;
97                         default:
98                                 break;
99                         }
100                 }
101                 ++par;
102         }
103         return 0;
104 }
105
106
107 int InsetERT::docbook(odocstream & os, OutputParams const &) const
108 {
109         // FIXME can we do the same thing here as for LaTeX?
110         ParagraphList::const_iterator par = paragraphs().begin();
111         ParagraphList::const_iterator end = paragraphs().end();
112
113         int lines = 0;
114         while (par != end) {
115                 pos_type siz = par->size();
116                 for (pos_type i = 0; i < siz; ++i)
117                         os.put(par->getChar(i));
118                 ++par;
119                 if (par != end) {
120                         os << "\n";
121                         ++lines;
122                 }
123         }
124
125         return lines;
126 }
127
128
129 void InsetERT::doDispatch(Cursor & cur, FuncRequest & cmd)
130 {
131         switch (cmd.action()) {
132         case LFUN_INSET_EDIT: {
133                 cur.push(*this);
134                 text().selectAll(cur);
135                 string const format =
136                         cur.buffer()->params().documentClass().outputFormat();
137                 string const ext = theFormats().extension(format);
138                 tempfile_.reset(new TempFile("ert_editXXXXXX." + ext));
139                 FileName const tempfilename = tempfile_->name();
140                 string const name = tempfilename.toFilesystemEncoding();
141                 ofdocstream os(name.c_str());
142                 os << cur.selectionAsString(false);
143                 os.close();
144                 // Since we lock the inset while the external file is edited,
145                 // we need to move the cursor outside and clear any selection inside
146                 cur.clearSelection();
147                 cur.pop();
148                 cur.leaveInset(*this);
149                 theFormats().edit(buffer(), tempfilename, format);
150                 break;
151         }
152         case LFUN_INSET_END_EDIT: {
153                 FileName const tempfilename = tempfile_->name();
154                 docstring const s = tempfilename.fileContents("UTF-8");
155                 cur.recordUndoInset(this);
156                 cur.push(*this);
157                 text().selectAll(cur);
158                 cap::replaceSelection(cur);
159                 cur.text()->insertStringAsLines(cur, s, cur.current_font);
160                 // FIXME it crashes without this
161                 cur.fixIfBroken();
162                 tempfile_.reset();
163                 cur.pop();
164                 break;
165         }
166         case LFUN_INSET_MODIFY:
167                 if (cmd.getArg(0) == "ert") {
168                         cur.recordUndoInset(this);
169                         setStatus(cur, string2params(to_utf8(cmd.argument())));
170                         break;
171                 }
172                 //fall-through
173         default:
174                 InsetCollapsible::doDispatch(cur, cmd);
175                 break;
176         }
177
178 }
179
180
181 bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd,
182         FuncStatus & status) const
183 {
184         switch (cmd.action()) {
185         case LFUN_INSET_EDIT:
186                 status.setEnabled(tempfile_ == 0);
187                 return true;
188         case LFUN_INSET_END_EDIT:
189                 status.setEnabled(tempfile_ != 0);
190                 return true;
191         case LFUN_INSET_INSERT:
192                 status.setEnabled(false);
193                 return true;
194         case LFUN_INSET_MODIFY:
195                 if (cmd.getArg(0) == "ert") {
196                         status.setEnabled(true);
197                         return true;
198                 }
199                 //fall through
200
201         default:
202                 return InsetCollapsible::getStatus(cur, cmd, status);
203         }
204 }
205
206
207 bool InsetERT::editable() const
208 {
209         if (tempfile_)
210                 return false;
211         return InsetCollapsible::editable();
212 }
213
214
215 bool InsetERT::descendable(BufferView const & bv) const
216 {
217         if (tempfile_)
218                 return false;
219         return InsetCollapsible::descendable(bv);
220 }
221
222
223 docstring const InsetERT::buttonLabel(BufferView const & bv) const
224 {
225         if (decoration() == InsetLayout::CLASSIC)
226                 return isOpen(bv) ? _("ERT") : getNewLabel(_("ERT"));
227         else
228                 return getNewLabel(_("ERT"));
229 }
230
231
232 InsetCollapsible::CollapseStatus InsetERT::string2params(string const & in)
233 {
234         if (in.empty())
235                 return Collapsed;
236         istringstream data(in);
237         Lexer lex;
238         lex.setStream(data);
239         lex.setContext("InsetERT::string2params");
240         lex >> "ert";
241         int s;
242         lex >> s;
243         return static_cast<CollapseStatus>(s);
244 }
245
246
247 string InsetERT::params2string(CollapseStatus status)
248 {
249         ostringstream data;
250         data << "ert" << ' ' << status;
251         return data.str();
252 }
253
254
255 docstring InsetERT::xhtml(XHTMLStream &, OutputParams const &) const
256 {
257         return docstring();
258 }
259
260 } // namespace lyx