]> git.lyx.org Git - lyx.git/blob - src/insets/insetminipage.C
Revert this change as it sneaked in and wasn't discussed yet.
[lyx.git] / src / insets / insetminipage.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *          Copyright 1998 The LyX Team.
7  *
8  *======================================================*/
9
10 #include <config.h>
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include "insetminipage.h"
17 #include "gettext.h"
18 #include "lyxfont.h"
19 #include "BufferView.h"
20 #include "LyXView.h"
21 #include "frontends/Dialogs.h"
22 #include "lyxtext.h"
23 #include "insets/insettext.h"
24 #include "support/LOstream.h"
25 #include "support/lstrings.h"
26 #include "debug.h"
27 #include "gettext.h"
28 #include "lyxlex.h"
29
30 using std::ostream;
31 using std::endl;
32
33
34 // Some information about Minipages in LaTeX:
35 // A minipage is a complete miniversion of a page and can contain
36 // its own footnotes, paragraphs, and array, tabular, and multicols
37 // environments. However it cannot contain floats or \marginpar's,
38 // but it can appear inside floats.
39 //
40 // The minipage environment is defined like this:
41 //
42 // \begin{minipage}[pos][height][inner-pos]{width} <text> \end{minipage}
43 //
44 // Where:
45 //     pos [opt] = is the vertical placement of the box with respect
46 //                 to the text baseline, [c], [t] and [b].
47 //     height [opt] = the height of the box
48 //     inner-pos [opt] = the position of the text within the box.
49 //                 It can be t, c, b or s, if unspecified the value
50 //                 of pos is used.
51 //     width = the width of the box
52 //
53 // In LyX we should try to support all these parameters, settable in a
54 // pop-up dialog.
55 // In this pop-up diallog it should also be possible to set all margin
56 // values that is usable in the minipage.
57 // With regard to different formats (like DocBook) I guess a minipage
58 // can be used there also. Perhaps not in the latex way, but we do not
59 // have to output "" for minipages.
60 // (Lgb)
61
62 InsetMinipage::InsetMinipage(BufferParams const & bp)
63         : InsetCollapsable(bp), pos_(center),
64           inner_pos_(inner_center), width_(100, LyXLength::PW)
65 {
66         setLabel(_("minipage"));
67         LyXFont font(LyXFont::ALL_SANE);
68         font.decSize();
69         font.decSize();
70         font.setColor(LColor::collapsable);
71         setLabelFont(font);
72 #if 0
73         setAutoCollapse(false);
74 #endif
75
76 #if 0
77 #ifdef WITH_WARNINGS
78 #warning Remove this color definitions before 1.2.0 final!
79 #endif
80         // just for experimentation :)
81         setBackgroundColor(LColor::green);
82 #endif
83
84         inset.setFrameColor(0, LColor::blue);
85         setInsetName("Minipage");
86 }
87
88
89 InsetMinipage::InsetMinipage(InsetMinipage const & in, bool same_id)
90         : InsetCollapsable(in, same_id),
91           pos_(in.pos_), inner_pos_(in.inner_pos_),
92           height_(in.height_), width_(in.width_)
93 {}
94
95
96 Inset * InsetMinipage::clone(Buffer const &, bool same_id) const
97 {
98         return new InsetMinipage(*const_cast<InsetMinipage *>(this), same_id);
99 }
100
101
102 InsetMinipage::~InsetMinipage()
103 {
104         hideDialog();
105 }
106
107
108 void InsetMinipage::write(Buffer const * buf, ostream & os) const
109 {
110         os << getInsetName() << "\n"
111            << "position " << pos_ << "\n"
112            << "inner_position " << inner_pos_ << "\n"
113            << "height \"" << height_.asString() << "\"\n"
114            << "width \"" << width_.asString() << "\"\n";
115         InsetCollapsable::write(buf, os);
116 }
117
118
119 void InsetMinipage::read(Buffer const * buf, LyXLex & lex)
120 {
121         if (lex.isOK()) {
122                 lex.next();
123                 string const token = lex.getString();
124                 if (token == "position") {
125                         lex.next();
126                         pos_ = static_cast<Position>(lex.getInteger());
127                 } else {
128                         lyxerr << "InsetMinipage::Read: Missing 'position'-tag!"
129                                    << endl;
130                         // take countermeasures
131                         lex.pushToken(token);
132                 }
133         }
134         if (lex.isOK()) {
135                 lex.next();
136                 string const token = lex.getString();
137                 if (token == "inner_position") {
138                         lex.next();
139                         inner_pos_ = static_cast<InnerPosition>(lex.getInteger());
140                 } else {
141                         lyxerr << "InsetMinipage::Read: Missing 'inner_position'-tag!"
142                                    << endl;
143                         // take countermeasures
144                         lex.pushToken(token);
145                 }
146         }
147         if (lex.isOK()) {
148                 lex.next();
149                 string const token = lex.getString();
150                 if (token == "height") {
151                         lex.next();
152                         height_ = LyXLength(lex.getString());
153                 } else {
154                         lyxerr << "InsetMinipage::Read: Missing 'height'-tag!"
155                                    << endl;
156                         // take countermeasures
157                         lex.pushToken(token);
158                 }
159         }
160         if (lex.isOK()) {
161                 lex.next();
162                 string const token = lex.getString();
163                 if (token == "width") {
164                         lex.next();
165                         width_ = LyXLength(lex.getString());
166                 } else {
167                         lyxerr << "InsetMinipage::Read: Missing 'width'-tag!"
168                                    << endl;
169                         // take countermeasures
170                         lex.pushToken(token);
171                 }
172         }
173         InsetCollapsable::read(buf, lex);
174 }
175
176
177 int InsetMinipage::ascent(BufferView * bv, LyXFont const & font) const
178 {
179         if (collapsed_)
180                 return ascent_collapsed();
181         else {
182                 // Take placement into account.
183                 int i = 0;
184                 switch (pos_) {
185                 case top:
186                         i = InsetCollapsable::ascent(bv, font);
187                         break;
188                 case center:
189                         i = (InsetCollapsable::ascent(bv, font)
190                              + InsetCollapsable::descent(bv, font)) / 2;
191                         break;
192                 case bottom:
193                         i = InsetCollapsable::descent(bv, font);
194                         break;
195                 }
196                 return i;
197         }
198 }
199
200
201 int InsetMinipage::descent(BufferView * bv, LyXFont const & font) const
202 {
203         if (collapsed_)
204                 return descent_collapsed();
205         else {
206                 // Take placement into account.
207                 int i = 0;
208                 switch (pos_) {
209                 case top:
210                         i = InsetCollapsable::descent(bv, font);
211                         break;
212                 case center:
213                         i = (InsetCollapsable::ascent(bv, font)
214                              + InsetCollapsable::descent(bv, font)) / 2;
215                         break;
216                 case bottom:
217                         i = InsetCollapsable::ascent(bv, font);
218                         break;
219                 }
220                 return i;
221         }
222 }
223
224
225 string const InsetMinipage::editMessage() const
226 {
227         return _("Opened Minipage Inset");
228 }
229
230
231 int InsetMinipage::latex(Buffer const * buf,
232                          ostream & os, bool fragile, bool fp) const
233 {
234         string s_pos;
235         switch (pos_) {
236         case top:
237                 s_pos += "t";
238                 break;
239         case center:
240                 s_pos += "c";
241                 break;
242         case bottom:
243                 s_pos += "b";
244                 break;
245         }
246         os << "\\begin{minipage}[" << s_pos << "]{"
247            << width_.asLatexString() << "}%\n";
248
249         int i = inset.latex(buf, os, fragile, fp);
250
251         os << "\\end{minipage}%\n";
252         return i + 2;
253 }
254
255
256 bool InsetMinipage::insetAllowed(Inset::Code code) const
257 {
258         if ((code == Inset::FLOAT_CODE) || (code == Inset::MARGIN_CODE))
259                 return false;
260
261         return InsetCollapsable::insetAllowed(code);
262 }
263
264
265 InsetMinipage::Position InsetMinipage::pos() const
266 {
267         return pos_;
268 }
269
270
271 void InsetMinipage::pos(InsetMinipage::Position p)
272 {
273         if (pos_ != p) {
274                 pos_ = p;
275                 need_update = FULL;
276         }
277 }
278
279
280 InsetMinipage::InnerPosition InsetMinipage::innerPos() const
281 {
282         return inner_pos_;
283 }
284
285
286 void InsetMinipage::innerPos(InsetMinipage::InnerPosition ip)
287 {
288         inner_pos_ = ip;
289 }
290
291
292 LyXLength const & InsetMinipage::pageHeight() const
293 {
294         return height_;
295 }
296
297
298 void InsetMinipage::pageHeight(LyXLength const & ll)
299 {
300         if (height_ != ll) {
301                 height_ = ll;
302                 need_update = FULL;
303         }
304 }
305
306
307 LyXLength const & InsetMinipage::pageWidth() const
308 {
309         return width_;
310 }
311
312
313 void InsetMinipage::pageWidth(LyXLength const & ll)
314 {
315         if (ll != width_) {
316                 width_ = ll;
317                 need_update = FULL;
318         }
319 }
320
321
322 bool InsetMinipage::showInsetDialog(BufferView * bv) const
323 {
324         if (!inset.showInsetDialog(bv))
325                 bv->owner()->getDialogs()->showMinipage(const_cast<InsetMinipage *>(this));
326         return true;
327 }
328
329
330 int InsetMinipage::getMaxWidth(BufferView * bv, UpdatableInset const * inset)
331         const
332 {
333         if (owner() &&
334             static_cast<UpdatableInset*>(owner())->getMaxWidth(bv, inset) < 0) {
335                 return -1;
336         }
337         if (!width_.zero()) {
338                 int ww1 = latexTextWidth(bv);
339                 int ww2 = InsetCollapsable::getMaxWidth(bv, inset);
340                 if (ww2 > 0 && ww2 < ww1) {
341                         return ww2;
342                 }
343                 return ww1;
344         }
345         // this should not happen!
346         return InsetCollapsable::getMaxWidth(bv, inset);
347 }
348
349
350 int InsetMinipage::latexTextWidth(BufferView * bv) const
351 {
352         return width_.inPixels(InsetCollapsable::latexTextWidth(bv),
353                                bv->text->defaultHeight());
354 }