2 * \file InsetMathSpace.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include "InsetMathSpace.h"
15 #include "MathFactory.h"
16 #include "MathStream.h"
17 #include "MathSupport.h"
19 #include "BufferView.h"
21 #include "FuncRequest.h"
22 #include "FuncStatus.h"
23 #include "LaTeXFeatures.h"
25 #include "insets/InsetSpace.h"
27 #include "frontends/Application.h"
28 #include "frontends/Painter.h"
30 #include "support/lassert.h"
41 InsetSpaceParams::Kind kind
;
47 SpaceInfo space_info
[] = {
48 // name width kind negative visible custom
49 {"!", 6, InsetSpaceParams::NEGTHIN
, true, true, false},
50 {"negthinspace", 6, InsetSpaceParams::NEGTHIN
, true, true, false},
51 {"negmedspace", 8, InsetSpaceParams::NEGMEDIUM
, true, true, false},
52 {"negthickspace", 10, InsetSpaceParams::NEGTHICK
, true, true, false},
53 {",", 6, InsetSpaceParams::THIN
, false, true, false},
54 {"thinspace", 6, InsetSpaceParams::THIN
, false, true, false},
55 {":", 8, InsetSpaceParams::MEDIUM
, false, true, false},
56 {"medspace", 8, InsetSpaceParams::MEDIUM
, false, true, false},
57 {";", 10, InsetSpaceParams::THICK
, false, true, false},
58 {"thickspace", 10, InsetSpaceParams::THICK
, false, true, false},
59 {"enskip", 10, InsetSpaceParams::ENSKIP
, false, true, false},
60 {"quad", 20, InsetSpaceParams::QUAD
, false, true, false},
61 {"qquad", 40, InsetSpaceParams::QQUAD
, false, true, false},
62 {"lyxnegspace", -2, InsetSpaceParams::NEGTHIN
, true, false, false},
63 {"lyxposspace", 2, InsetSpaceParams::THIN
, false, false, false},
64 {"hspace", 0, InsetSpaceParams::CUSTOM
, false, true, true},
67 int const nSpace
= sizeof(space_info
)/sizeof(SpaceInfo
);
68 int const defaultSpace
= 4;
72 InsetMathSpace::InsetMathSpace()
73 : space_(defaultSpace
)
78 InsetMathSpace::InsetMathSpace(string
const & name
, string
const & length
)
79 : space_(defaultSpace
)
81 for (int i
= 0; i
< nSpace
; ++i
)
82 if (space_info
[i
].name
== name
) {
86 if (space_info
[space_
].custom
) {
87 length_
= Length(length
);
88 if (length_
.zero() || length_
.empty()) {
90 length_
.unit(Length::EM
);
96 InsetMathSpace::InsetMathSpace(Length
const & length
)
97 : space_(defaultSpace
), length_(length
)
99 for (int i
= 0; i
< nSpace
; ++i
)
100 if (space_info
[i
].name
== "hspace") {
107 InsetMathSpace::~InsetMathSpace()
109 hideDialogs("mathspace", this);
113 Inset
* InsetMathSpace::clone() const
115 return new InsetMathSpace(*this);
119 void InsetMathSpace::metrics(MetricsInfo
& mi
, Dimension
& dim
) const
123 if (space_info
[space_
].custom
)
124 dim
.wid
= abs(length_
.inPixels(
126 mathed_char_width(mi
.base
.font
, 'M')));
128 dim
.wid
= space_info
[space_
].width
;
132 void InsetMathSpace::draw(PainterInfo
& pi
, int x
, int y
) const
134 // Sadly, HP-UX CC can't handle that kind of initialization.
135 // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
136 if (!space_info
[space_
].visible
)
139 Dimension
const dim
= dimension(*pi
.base
.bv
);
144 xp
[0] = ++x
; yp
[0] = y
- 3;
145 xp
[1] = x
; yp
[1] = y
;
146 xp
[2] = x
+ w
- 2; yp
[2] = y
;
147 xp
[3] = x
+ w
- 2; yp
[3] = y
- 3;
149 pi
.pain
.lines(xp
, yp
, 4,
150 space_info
[space_
].custom
?
152 (isNegative() ? Color_latex
: Color_math
));
156 void InsetMathSpace::incSpace()
158 int const oldwidth
= space_info
[space_
].width
;
160 space_
= (space_
+ 1) % nSpace
;
161 while ((space_info
[space_
].width
== oldwidth
&& !space_info
[space_
].custom
) ||
162 !space_info
[space_
].visible
);
163 if (space_info
[space_
].custom
&& (length_
.zero() || length_
.empty())) {
165 length_
.unit(Length::EM
);
170 void InsetMathSpace::validate(LaTeXFeatures
& features
) const
172 if (space_info
[space_
].name
== "negmedspace" ||
173 space_info
[space_
].name
== "negthickspace")
174 features
.require("amsmath");
178 void InsetMathSpace::maple(MapleStream
& os
) const
183 void InsetMathSpace::mathematica(MathematicaStream
& os
) const
189 void InsetMathSpace::octave(OctaveStream
& os
) const
195 void InsetMathSpace::normalize(NormalStream
& os
) const
197 os
<< "[space " << int(space_
) << "] ";
201 void InsetMathSpace::write(WriteStream
& os
) const
203 // no MathEnsurer - all kinds work in text and math mode
204 os
<< '\\' << space_info
[space_
].name
.c_str();
205 if (space_info
[space_
].custom
)
206 os
<< '{' << length_
.asLatexString().c_str() << '}';
208 os
.pendingSpace(true);
212 string
const InsetMathSpace::createDialogStr() const
214 LASSERT(space_info
[space_
].visible
, /**/);
215 InsetSpaceParams
isp(true);
216 isp
.kind
= space_info
[space_
].kind
;
217 isp
.length
= GlueLength(length_
);
218 return InsetSpace::params2string(isp
);
222 docstring
InsetMathSpace::contextMenu(BufferView
const &, int, int) const
224 return from_ascii("context-mathspace");
228 bool InsetMathSpace::getStatus(Cursor
& cur
, FuncRequest
const & cmd
,
229 FuncStatus
& status
) const
231 switch (cmd
.action
) {
233 case LFUN_INSET_MODIFY
:
234 case LFUN_INSET_DIALOG_UPDATE
:
235 case LFUN_MOUSE_RELEASE
:
236 case LFUN_MOUSE_PRESS
:
237 case LFUN_MOUSE_MOTION
:
238 status
.setEnabled(true);
241 bool retval
= InsetMath::getStatus(cur
, cmd
, status
);
247 void InsetMathSpace::doDispatch(Cursor
& cur
, FuncRequest
& cmd
)
249 switch (cmd
.action
) {
250 case LFUN_INSET_MODIFY
:
251 if (cmd
.getArg(0) == "mathspace") {
253 if (createInsetMath_fromDialogStr(cmd
.argument(), ar
)) {
254 *this = *ar
[0].nucleus()->asSpaceInset();
261 case LFUN_INSET_DIALOG_UPDATE
:
262 cur
.bv().updateDialog("mathspace", createDialogStr());
265 case LFUN_MOUSE_RELEASE
:
266 if (cmd
.button() == mouse_button::button1
) {
267 string
const data
= createDialogStr();
268 cur
.bv().showDialog("mathspace", data
, this);
274 case LFUN_MOUSE_PRESS
:
275 case LFUN_MOUSE_MOTION
:
276 // eat other mouse commands
280 InsetMath::doDispatch(cur
, cmd
);
286 bool InsetMathSpace::isNegative() const
288 if (space_info
[space_
].custom
)
289 return length_
.value() < 0;
290 return space_info
[space_
].negative
;