]> git.lyx.org Git - lyx.git/blob - src/insets/insetwrap.C
the dispatch patch
[lyx.git] / src / insets / insetwrap.C
1 /**
2  * \file insetwrap.C
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  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "insetwrap.h"
14
15 #include "buffer.h"
16 #include "bufferparams.h"
17 #include "BufferView.h"
18 #include "debug.h"
19 #include "Floating.h"
20 #include "FloatList.h"
21 #include "funcrequest.h"
22 #include "gettext.h"
23 #include "LaTeXFeatures.h"
24 #include "LColor.h"
25 #include "lyxlex.h"
26 #include "paragraph.h"
27
28 #include "support/tostr.h"
29
30 #include "support/std_sstream.h"
31
32
33 using std::string;
34 using std::endl;
35 using std::auto_ptr;
36 using std::istringstream;
37 using std::ostream;
38 using std::ostringstream;
39
40
41 namespace {
42
43 // this should not be hardcoded, but be part of the definition
44 // of the float (JMarc)
45 string const caplayout("Caption");
46
47 string floatname(string const & type, BufferParams const & bp)
48 {
49         FloatList const & floats = bp.getLyXTextClass().floats();
50         FloatList::const_iterator it = floats[type];
51         if (it == floats.end())
52                 return type;
53
54         return _(it->second.name());
55 }
56
57 } // namespace anon
58
59
60 InsetWrap::InsetWrap(BufferParams const & bp, string const & type)
61         : InsetCollapsable(bp)
62 {
63         string lab(_("wrap: "));
64         lab += floatname(type, bp);
65         setLabel(lab);
66         LyXFont font(LyXFont::ALL_SANE);
67         font.decSize();
68         font.decSize();
69         font.setColor(LColor::collapsable);
70         setLabelFont(font);
71         params_.type = type;
72         params_.width = LyXLength(50, LyXLength::PCW);
73         setInsetName(type);
74         LyXTextClass const & tclass = bp.getLyXTextClass();
75         if (tclass.hasLayout(caplayout))
76                 inset.paragraphs.begin()->layout(tclass[caplayout]);
77 }
78
79
80 InsetWrap::~InsetWrap()
81 {
82         InsetWrapMailer(*this).hideDialog();
83 }
84
85
86 dispatch_result
87 InsetWrap::priv_dispatch(FuncRequest const & cmd,
88                          idx_type & idx, pos_type & pos)
89 {
90         switch (cmd.action) {
91         case LFUN_INSET_MODIFY: {
92                 InsetWrapParams params;
93                 InsetWrapMailer::string2params(cmd.argument, params);
94
95                 params_.placement = params.placement;
96                 params_.width     = params.width;
97
98                 cmd.view()->updateInset(this);
99                 return DISPATCHED;
100         }
101
102         case LFUN_INSET_DIALOG_UPDATE:
103                 InsetWrapMailer(*this).updateDialog(cmd.view());
104                 return DISPATCHED;
105
106         default:
107                 return InsetCollapsable::priv_dispatch(cmd, idx, pos);
108         }
109 }
110
111
112 void InsetWrapParams::write(ostream & os) const
113 {
114         os << "Wrap " << type << '\n';
115
116         if (!placement.empty())
117                 os << "placement " << placement << "\n";
118
119         os << "width \"" << width.asString() << "\"\n";
120 }
121
122
123 void InsetWrapParams::read(LyXLex & lex)
124 {
125         if (lex.isOK()) {
126                 lex.next();
127                 string token = lex.getString();
128                 if (token == "placement") {
129                         lex.next();
130                         placement = lex.getString();
131                 } else {
132                         // take countermeasures
133                         lex.pushToken(token);
134                 }
135         }
136         if (lex.isOK()) {
137                 lex.next();
138                 string token = lex.getString();
139                 if (token == "width") {
140                         lex.next();
141                         width = LyXLength(lex.getString());
142                 } else {
143                         lyxerr << "InsetWrap::Read:: Missing 'width'-tag!"
144                                << endl;
145                         // take countermeasures
146                         lex.pushToken(token);
147                 }
148         }
149 }
150
151
152 void InsetWrap::write(Buffer const & buf, ostream & os) const
153 {
154         params_.write(os);
155         InsetCollapsable::write(buf, os);
156 }
157
158
159 void InsetWrap::read(Buffer const & buf, LyXLex & lex)
160 {
161         params_.read(lex);
162         InsetCollapsable::read(buf, lex);
163 }
164
165
166 void InsetWrap::validate(LaTeXFeatures & features) const
167 {
168         features.require("floatflt");
169         InsetCollapsable::validate(features);
170 }
171
172
173 auto_ptr<InsetBase> InsetWrap::clone() const
174 {
175         return auto_ptr<InsetBase>(new InsetWrap(*this));
176 }
177
178
179 string const InsetWrap::editMessage() const
180 {
181         return _("Opened Wrap Inset");
182 }
183
184
185 int InsetWrap::latex(Buffer const & buf, ostream & os,
186                      LatexRunParams const & runparams) const
187 {
188         os << "\\begin{floating" << params_.type << '}';
189         if (!params_.placement.empty()) {
190                 os << '[' << params_.placement << ']';
191         }
192         os  << '{' << params_.width.asLatexString() << "}%\n";
193
194         int const i = inset.latex(buf, os, runparams);
195
196         os << "\\end{floating" << params_.type << "}%\n";
197         return i + 2;
198 }
199
200
201 int InsetWrap::docbook(Buffer const & buf, ostream & os, bool mixcont) const
202 {
203         os << '<' << params_.type << '>';
204         int const i = inset.docbook(buf, os, mixcont);
205         os << "</" << params_.type << '>';
206
207         return i;
208 }
209
210
211 bool InsetWrap::insetAllowed(InsetOld::Code code) const
212 {
213         switch(code) {
214         case FLOAT_CODE:
215         case FOOT_CODE:
216         case MARGIN_CODE:
217                 return false;
218         default:
219                 return InsetCollapsable::insetAllowed(code);
220         }
221 }
222
223
224 int InsetWrap::latexTextWidth(BufferView * bv) const
225 {
226         return params_.width.inPixels(InsetCollapsable::latexTextWidth(bv));
227 }
228
229
230 bool InsetWrap::showInsetDialog(BufferView * bv) const
231 {
232         if (!inset.showInsetDialog(bv)) {
233                 InsetWrap * tmp = const_cast<InsetWrap *>(this);
234                 InsetWrapMailer(*tmp).showDialog(bv);
235         }
236         return true;
237 }
238
239
240 void InsetWrap::addToToc(lyx::toc::TocList & toclist, Buffer const & buf) const
241 {
242         // Now find the caption in the float...
243         ParagraphList::iterator tmp = inset.paragraphs.begin();
244         ParagraphList::iterator end = inset.paragraphs.end();
245
246         for (; tmp != end; ++tmp) {
247                 if (tmp->layout()->name() == caplayout) {
248                         string const name = floatname(params_.type, buf.params());
249                         string const str =
250                                 tostr(toclist[name].size() + 1)
251                                 + ". " + tmp->asString(buf, false);
252                         lyx::toc::TocItem const item(tmp->id(), 0 , str);
253                         toclist[name].push_back(item);
254                 }
255         }
256 }
257
258
259 string const InsetWrapMailer::name_("wrap");
260
261 InsetWrapMailer::InsetWrapMailer(InsetWrap & inset)
262         : inset_(inset)
263 {}
264
265
266 string const InsetWrapMailer::inset2string(Buffer const &) const
267 {
268         return params2string(inset_.params());
269 }
270
271
272 void InsetWrapMailer::string2params(string const & in,
273                                     InsetWrapParams & params)
274 {
275         params = InsetWrapParams();
276
277         if (in.empty())
278                 return;
279
280         istringstream data(in);
281         LyXLex lex(0,0);
282         lex.setStream(data);
283
284         if (lex.isOK()) {
285                 lex.next();
286                 string const token = lex.getString();
287                 if (token != name_)
288                         return;
289         }
290
291         // This is part of the inset proper that is usually swallowed
292         // by Buffer::readInset
293         if (lex.isOK()) {
294                 lex.next();
295                 string const token = lex.getString();
296                 if (token != "Wrap" || !lex.eatLine())
297                         return;
298         }
299
300         if (lex.isOK()) {
301                 params.read(lex);
302         }
303 }
304
305
306 string const InsetWrapMailer::params2string(InsetWrapParams const & params)
307 {
308         ostringstream data;
309         data << name_ << ' ';
310         params.write(data);
311         return data.str();
312 }