]> git.lyx.org Git - lyx.git/blob - src/insets/InsetWrap.cpp
a9f92cedc27714061916675735cc9cc28363c77c
[lyx.git] / src / insets / InsetWrap.cpp
1 /**
2  * \file InsetWrap.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Dekel Tsur
7  * \author Uwe Stöhr
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetWrap.h"
15
16 #include "Buffer.h"
17 #include "BufferParams.h"
18 #include "BufferView.h"
19 #include "Counters.h"
20 #include "Cursor.h"
21 #include "DispatchResult.h"
22 #include "Floating.h"
23 #include "FloatList.h"
24 #include "FuncRequest.h"
25 #include "FuncStatus.h"
26 #include "LaTeXFeatures.h"
27 #include "Lexer.h"
28 #include "OutputParams.h"
29 #include "TextClass.h"
30 #include "TocBackend.h"
31
32 #include "support/convert.h"
33 #include "support/docstream.h"
34 #include "support/debug.h"
35 #include "support/gettext.h"
36
37 #include "frontends/Application.h"
38
39 using namespace std;
40
41 namespace lyx {
42
43
44 InsetWrap::InsetWrap(Buffer const & buf, string const & type)
45         : InsetCollapsable(buf), name_(from_utf8(type))
46 {
47         setLabel(_("wrap: ") + floatName(type, buf.params()));
48         params_.type = type;
49         params_.lines = 0;
50         params_.placement = "o";
51         params_.overhang = Length(0, Length::PCW);
52         params_.width = Length(50, Length::PCW);
53 }
54
55
56 InsetWrap::~InsetWrap()
57 {
58         hideDialogs("wrap", this);
59 }
60
61
62 void InsetWrap::doDispatch(Cursor & cur, FuncRequest & cmd)
63 {
64         switch (cmd.action) {
65         case LFUN_INSET_MODIFY: {
66                 InsetWrapParams params;
67                 InsetWrap::string2params(to_utf8(cmd.argument()), params);
68                 params_.lines = params.lines;
69                 params_.placement = params.placement;
70                 params_.overhang = params.overhang;
71                 params_.width = params.width;
72                 break;
73         }
74
75         case LFUN_INSET_DIALOG_UPDATE:
76                 cur.bv().updateDialog("wrap", params2string(params()));
77                 break;
78
79         default:
80                 InsetCollapsable::doDispatch(cur, cmd);
81                 break;
82         }
83 }
84
85
86 bool InsetWrap::getStatus(Cursor & cur, FuncRequest const & cmd,
87                 FuncStatus & flag) const
88 {
89         switch (cmd.action) {
90         case LFUN_INSET_MODIFY:
91         case LFUN_INSET_DIALOG_UPDATE:
92                 flag.enabled(true);
93                 return true;
94
95         default:
96                 return InsetCollapsable::getStatus(cur, cmd, flag);
97         }
98 }
99
100
101 void InsetWrap::updateLabels(ParIterator const & it)
102 {
103         setLabel(_("wrap: ") + floatName(params_.type, buffer().params()));
104         Counters & cnts = buffer().params().documentClass().counters();
105         string const saveflt = cnts.current_float();
106
107         // Tell to captions what the current float is
108         cnts.current_float(params().type);
109
110         InsetCollapsable::updateLabels(it);
111
112         // reset afterwards
113         cnts.current_float(saveflt);
114 }
115
116
117 void InsetWrapParams::write(ostream & os) const
118 {
119         os << "Wrap " << type << '\n';
120         os << "lines " << lines << "\n";
121         os << "placement " << placement << "\n";
122         os << "overhang " << overhang.asString() << "\n";
123         os << "width \"" << width.asString() << "\"\n";
124 }
125
126
127 void InsetWrapParams::read(Lexer & lex)
128 {
129         string token;
130
131         lex >> token;
132         if (token == "lines")
133                 lex >> lines;
134         else {
135                 lyxerr << "InsetWrap::Read:: Missing 'lines'-tag!"
136                         << endl;
137                 // take countermeasures
138                 lex.pushToken(token);
139         }
140         if (!lex)
141                 return;
142         lex >> token;
143         if (token == "placement")
144                 lex >> placement;
145         else {
146                 lyxerr << "InsetWrap::Read:: Missing 'placement'-tag!"
147                         << endl;
148                 lex.pushToken(token);
149         }
150         if (!lex)
151                 return;
152         lex >> token;
153         if (token == "overhang") {
154                 lex.next();
155                 overhang = Length(lex.getString());
156         } else {
157                 lyxerr << "InsetWrap::Read:: Missing 'overhang'-tag!"
158                         << endl;
159                 lex.pushToken(token);
160         }
161         if (!lex)
162                 return;
163         lex >> token;
164         if (token == "width") {
165                 lex.next();
166                 width = Length(lex.getString());
167         } else {
168                 lyxerr << "InsetWrap::Read:: Missing 'width'-tag!"
169                         << endl;
170                 lex.pushToken(token);
171         }
172 }
173
174
175 void InsetWrap::write(ostream & os) const
176 {
177         params_.write(os);
178         InsetCollapsable::write(os);
179 }
180
181
182 void InsetWrap::read(Lexer & lex)
183 {
184         params_.read(lex);
185         InsetCollapsable::read(lex);
186 }
187
188
189 void InsetWrap::validate(LaTeXFeatures & features) const
190 {
191         features.require("wrapfig");
192         InsetCollapsable::validate(features);
193 }
194
195
196 docstring InsetWrap::editMessage() const
197 {
198         return _("Opened Wrap Inset");
199 }
200
201
202 int InsetWrap::latex(odocstream & os, OutputParams const & runparams) const
203 {
204         os << "\\begin{wrap" << from_ascii(params_.type) << '}';
205         // no optional argument when lines are zero
206         if (params_.lines != 0)
207                 os << '[' << params_.lines << ']';
208         os << '{' << from_ascii(params_.placement) << '}';
209         Length over(params_.overhang);
210         // no optional argument when the value is zero
211         if (over.value() != 0)
212                 os << '[' << from_ascii(params_.overhang.asLatexString()) << ']';
213         os << '{' << from_ascii(params_.width.asLatexString()) << "}%\n";
214         int const i = InsetText::latex(os, runparams);
215         os << "\\end{wrap" << from_ascii(params_.type) << "}%\n";
216         return i + 2;
217 }
218
219
220 int InsetWrap::plaintext(odocstream & os, OutputParams const & runparams) const
221 {
222         os << '[' << buffer().B_("wrap") << ' '
223                 << floatName(params_.type, buffer().params()) << ":\n";
224         InsetText::plaintext(os, runparams);
225         os << "\n]";
226
227         return PLAINTEXT_NEWLINE + 1; // one char on a separate line
228 }
229
230
231 int InsetWrap::docbook(odocstream & os, OutputParams const & runparams) const
232 {
233         // FIXME UNICODE
234         os << '<' << from_ascii(params_.type) << '>';
235         int const i = InsetText::docbook(os, runparams);
236         os << "</" << from_ascii(params_.type) << '>';
237         return i;
238 }
239
240
241 bool InsetWrap::insetAllowed(InsetCode code) const
242 {
243         switch(code) {
244         case FLOAT_CODE:
245         case FOOT_CODE:
246         case MARGIN_CODE:
247                 return false;
248         default:
249                 return InsetCollapsable::insetAllowed(code);
250         }
251 }
252
253
254 bool InsetWrap::showInsetDialog(BufferView * bv) const
255 {
256         if (!InsetText::showInsetDialog(bv))
257                 bv->showDialog("wrap", params2string(params()),
258                         const_cast<InsetWrap *>(this));
259         return true;
260 }
261
262
263 void InsetWrap::string2params(string const & in, InsetWrapParams & params)
264 {
265         params = InsetWrapParams();
266         if (in.empty())
267                 return;
268
269         istringstream data(in);
270         Lexer lex;
271         lex.setStream(data);
272
273         string name;
274         lex >> name;
275         if (!lex || name != "wrap") {
276                 LYXERR0("Expected arg 1 to be \"wrap\" in " << in);
277                 return;
278         }
279
280         // This is part of the inset proper that is usually swallowed
281         // by Text::readInset
282         string id;
283         lex >> id;
284         if (!lex || id != "Wrap") {
285                 LYXERR0("Expected arg 2 to be \"Wrap\" in " << in);
286                 return;
287         }
288
289         // We have to read the type here!
290         lex >> params.type;
291         params.read(lex);
292 }
293
294
295 string InsetWrap::params2string(InsetWrapParams const & params)
296 {
297         ostringstream data;
298         data << "wrap" << ' ';
299         params.write(data);
300         return data.str();
301 }
302
303
304 } // namespace lyx