]> git.lyx.org Git - lyx.git/blob - src/insets/insetvspace.C
fix two crashes related to dEPM. Some crashes remain
[lyx.git] / src / insets / insetvspace.C
1 /**
2  * \file insetvspace.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author various
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "insetvspace.h"
15
16 #include "buffer.h"
17 #include "BufferView.h"
18 #include "cursor.h"
19 #include "dispatchresult.h"
20 #include "funcrequest.h"
21 #include "gettext.h"
22 #include "LColor.h"
23 #include "lyxlex.h"
24 #include "lyxtext.h"
25 #include "metricsinfo.h"
26
27 #include "frontends/font_metrics.h"
28 #include "frontends/Painter.h"
29
30 #include <sstream>
31
32 using std::istringstream;
33 using std::ostream;
34 using std::ostringstream;
35 using std::string;
36 using std::max;
37
38
39 namespace {
40
41 int const ADD_TO_VSPACE_WIDTH = 5;
42
43 } // namespace anon
44
45
46 InsetVSpace::InsetVSpace(VSpace const & space)
47         : space_(space)
48 {}
49
50
51 InsetVSpace::~InsetVSpace()
52 {
53         InsetVSpaceMailer(*this).hideDialog();
54 }
55
56
57 std::auto_ptr<InsetBase> InsetVSpace::doClone() const
58 {
59         return std::auto_ptr<InsetBase>(new InsetVSpace(*this));
60 }
61
62
63 void InsetVSpace::doDispatch(LCursor & cur, FuncRequest & cmd)
64 {
65         switch (cmd.action) {
66
67         case LFUN_INSET_MODIFY: {
68                 InsetVSpaceMailer::string2params(cmd.argument, space_);
69                 break;
70         }
71
72         case LFUN_MOUSE_PRESS:
73                 InsetVSpaceMailer(*this).showDialog(&cur.bv());
74                 break;
75
76         default:
77                 InsetBase::doDispatch(cur, cmd);
78                 break;
79         }
80 }
81
82
83 void InsetVSpace::read(Buffer const &, LyXLex & lex)
84 {
85         BOOST_ASSERT(lex.isOK());
86         string vsp;
87         lex >> vsp;
88         if (lex)
89                 space_ = VSpace(vsp);
90
91         string end_token;
92         lex >> end_token;
93         if (end_token != "\\end_inset")
94                 lex.printError("Missing \\end_inset at this point. "
95                                "Read: `$$Token'");
96 }
97
98
99 void InsetVSpace::write(Buffer const &, ostream & os) const
100 {
101         os << "VSpace " << space_.asLyXCommand();
102 }
103
104
105 string const InsetVSpace::label() const
106 {
107         static string const label = _("Vertical Space");
108         return label + " (" + space_.asGUIName() + ')';
109 }
110
111
112 namespace {
113 int const arrow_size = 4;
114 }
115
116
117 void InsetVSpace::metrics(MetricsInfo & mi, Dimension & dim) const
118 {
119         int size = 10;
120         int const space_size = space_.inPixels(*mi.base.bv);
121
122         LyXFont font;
123         font.decSize();
124         int const min_size = max(3 * arrow_size, font_metrics::maxHeight(font));
125
126         if (space_.length().len().value() < 0.0)
127                 size = min_size;
128         else
129                 size = max(min_size, space_size);
130
131         dim.asc = size / 2;
132         dim.des = size / 2;
133         int w = 0;
134         int a = 0;
135         int d = 0;
136         font.decSize();
137         font_metrics::rectText(label(), font, w, a, d);
138         dim.wid = ADD_TO_VSPACE_WIDTH + 2 * arrow_size + 5 + w;
139
140         dim_ = dim;
141 }
142
143
144 void InsetVSpace::draw(PainterInfo & pi, int x, int y) const
145 {
146         setPosCache(pi, x, y);
147
148         x += ADD_TO_VSPACE_WIDTH;
149
150         int const start = y - dim_.asc;
151         int const end   = y + dim_.des;
152
153         // the label to display (if any)
154         string const str = label();
155         // y-values for top arrow
156         int ty1, ty2;
157         // y-values for bottom arrow
158         int by1, by2;
159
160         if (space_.kind() == VSpace::VFILL) {
161                 ty1 = ty2 = start;
162                 by1 = by2 = end;
163         } else {
164                 // adding or removing space
165                 bool const added = space_.kind() != VSpace::LENGTH ||
166                                    space_.length().len().value() > 0.0;
167                 ty1 = added ? (start + arrow_size) : start;
168                 ty2 = added ? start : (start + arrow_size);
169                 by1 = added ? (end - arrow_size) : end;
170                 by2 = added ? end : (end - arrow_size);
171         }
172
173         int const midx = x + arrow_size;
174         int const rightx = midx + arrow_size;
175
176         // first the string
177         int w = 0;
178         int a = 0;
179         int d = 0;
180
181         LyXFont font;
182         font.setColor(LColor::added_space);
183         font.decSize();
184         font.decSize();
185         font_metrics::rectText(label(), font, w, a, d);
186
187         pi.pain.rectText(x + 2 * arrow_size + 5, y + d,
188                        str, font, LColor::none, LColor::none);
189
190         // top arrow
191         pi.pain.line(x, ty1, midx, ty2, LColor::added_space);
192         pi.pain.line(midx, ty2, rightx, ty1, LColor::added_space);
193
194         // bottom arrow
195         pi.pain.line(x, by1, midx, by2, LColor::added_space);
196         pi.pain.line(midx, by2, rightx, by1, LColor::added_space);
197
198         // joining line
199         pi.pain.line(midx, ty2, midx, by2, LColor::added_space);
200 }
201
202
203 int InsetVSpace::latex(Buffer const & buf, ostream & os,
204                           OutputParams const &) const
205 {
206         os << space_.asLatexCommand(buf.params()) << '\n';
207         return 1;
208 }
209
210
211 int InsetVSpace::plaintext(Buffer const &, ostream & os,
212                            OutputParams const &) const
213 {
214         os << "\n\n";
215         return 2;
216 }
217
218
219 int InsetVSpace::linuxdoc(Buffer const &, std::ostream & os,
220                           OutputParams const &) const
221 {
222         os << '\n';
223         return 1;
224 }
225
226
227 int InsetVSpace::docbook(Buffer const &, std::ostream & os,
228                          OutputParams const &) const
229 {
230         os << '\n';
231         return 1;
232 }
233
234
235 string const InsetVSpaceMailer::name_ = "vspace";
236
237
238 InsetVSpaceMailer::InsetVSpaceMailer(InsetVSpace & inset)
239         : inset_(inset)
240 {}
241
242
243 string const InsetVSpaceMailer::inset2string(Buffer const &) const
244 {
245         return params2string(inset_.space());
246 }
247
248
249 void InsetVSpaceMailer::string2params(string const & in, VSpace & vspace)
250 {
251         vspace = VSpace();
252         if (in.empty())
253                 return;
254
255         istringstream data(in);
256         LyXLex lex(0,0);
257         lex.setStream(data);
258
259         string name;
260         lex >> name;
261         if (!lex || name != name_)
262                 return print_mailer_error("InsetVSpaceMailer", in, 1, name_);
263
264         string vsp;
265         lex >> vsp;
266         if (lex)
267                 vspace = VSpace(vsp);
268 }
269
270
271 string const InsetVSpaceMailer::params2string(VSpace const & vspace)
272 {
273         ostringstream data;
274         data << name_ << ' ' << vspace.asLyXCommand();
275         return data.str();
276 }