2 * \file math_nestinset.C
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 "math_nestinset.h"
14 #include "math_cursor.h"
15 #include "math_mathmlstream.h"
16 #include "math_parser.h"
17 #include "BufferView.h"
18 #include "dispatchresult.h"
20 #include "funcrequest.h"
24 #include "frontends/Painter.h"
27 MathNestInset::MathNestInset(idx_type nargs)
28 : cells_(nargs), lock_(false)
32 MathInset::idx_type MathNestInset::nargs() const
38 MathArray & MathNestInset::cell(idx_type i)
44 MathArray const & MathNestInset::cell(idx_type i) const
50 void MathNestInset::getScreenPos(idx_type idx, pos_type pos, int & x, int & y) const
52 MathArray const & ar = cell(idx);
53 x = ar.xo() + ar.pos2x(pos);
55 // move cursor visually into empty cells ("blue rectangles");
56 if (cell(idx).empty())
61 void MathNestInset::substitute(MathMacro const & m)
63 for (idx_type i = 0; i < nargs(); ++i)
64 cell(i).substitute(m);
68 void MathNestInset::metrics(MetricsInfo const & mi) const
71 for (idx_type i = 0; i < nargs(); ++i)
76 bool MathNestInset::idxNext(LCursor & cur) const
78 if (cur.idx() + 1 >= nargs())
86 bool MathNestInset::idxRight(LCursor & cur) const
92 bool MathNestInset::idxPrev(LCursor & cur) const
97 cur.pos() = cur.lastpos();
102 bool MathNestInset::idxLeft(LCursor & cur) const
108 bool MathNestInset::idxFirst(LCursor & cur) const
118 bool MathNestInset::idxLast(LCursor & cur) const
122 cur.idx() = nargs() - 1;
123 cur.pos() = cur.lastpos();
128 bool MathNestInset::idxHome(LCursor & cur) const
137 bool MathNestInset::idxEnd(LCursor & cur) const
139 if (cur.lastpos() == cur.lastpos())
141 cur.pos() = cur.lastpos();
146 void MathNestInset::dump() const
148 WriteStream os(lyxerr);
149 os << "---------------------------------------------\n";
152 for (idx_type i = 0; i < nargs(); ++i)
153 os << cell(i) << "\n";
154 os << "---------------------------------------------\n";
158 //void MathNestInset::draw(PainterInfo & pi, int x, int y) const
159 void MathNestInset::draw(PainterInfo &, int, int) const
163 pi.pain.fillRectangle(x, y - ascent(), width(), height(),
169 void MathNestInset::drawSelection(PainterInfo & pi,
170 idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
173 MathArray const & c = cell(idx1);
174 int x1 = c.xo() + c.pos2x(pos1);
175 int y1 = c.yo() - c.ascent();
176 int x2 = c.xo() + c.pos2x(pos2);
177 int y2 = c.yo() + c.descent();
178 pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
180 for (idx_type i = 0; i < nargs(); ++i) {
181 if (idxBetween(i, idx1, idx2)) {
182 MathArray const & c = cell(i);
184 int y1 = c.yo() - c.ascent();
185 int x2 = c.xo() + c.width();
186 int y2 = c.yo() + c.descent();
187 pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
194 void MathNestInset::validate(LaTeXFeatures & features) const
196 for (idx_type i = 0; i < nargs(); ++i)
197 cell(i).validate(features);
201 void MathNestInset::replace(ReplaceData & rep)
203 for (idx_type i = 0; i < nargs(); ++i)
204 cell(i).replace(rep);
208 bool MathNestInset::contains(MathArray const & ar) const
210 for (idx_type i = 0; i < nargs(); ++i)
211 if (cell(i).contains(ar))
217 bool MathNestInset::editing() const
219 return inMathed() && mathcursor::isInside(this);
223 bool MathNestInset::lock() const
229 void MathNestInset::lock(bool l)
235 bool MathNestInset::isActive() const
241 MathArray MathNestInset::glue() const
244 for (size_t i = 0; i < nargs(); ++i)
250 void MathNestInset::write(WriteStream & os) const
252 os << '\\' << name().c_str();
253 for (size_t i = 0; i < nargs(); ++i)
254 os << '{' << cell(i) << '}';
256 os.pendingSpace(true);
257 if (lock_ && !os.latex()) {
259 os.pendingSpace(true);
264 void MathNestInset::normalize(NormalStream & os) const
266 os << '[' << name().c_str();
267 for (size_t i = 0; i < nargs(); ++i)
268 os << ' ' << cell(i);
273 void MathNestInset::notifyCursorLeaves(idx_type idx)
275 cell(idx).notifyCursorLeaves();
280 MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
282 //lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
283 // << " arg: '" << cmd.argument
284 // << "' x: '" << cmd.x
285 // << " y: '" << cmd.y
286 // << "' button: " << cmd.button() << endl;
288 switch (cmd.action) {
292 mathed_parse_cell(ar, cmd.argument);
293 cur.cell().insert(cur.pos(), ar);
294 cur.pos() += ar.size();
295 return DispatchResult(true, true);
298 case LFUN_PASTESELECTION:
299 return dispatch(cur, FuncRequest(LFUN_PASTE, cur.bv().getClipboard()));
301 case LFUN_MOUSE_PRESS:
302 if (cmd.button() == mouse_button::button2)
303 return priv_dispatch(cur, FuncRequest(LFUN_PASTESELECTION));
304 return DispatchResult(false);
307 cur.selection() = true; // fall through...
309 return mathcursor::right(cur, cur.selection()) ?
310 DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
311 //lyxerr << "calling scroll 20" << endl;
312 //scroll(&cur.bv(), 20);
313 // write something to the minibuffer
314 //cur.bv().owner()->message(mathcursor::info());
317 cur.selection() = true; // fall through
319 return mathcursor::left(cur, cur.selection()) ?
320 DispatchResult(true, true) : DispatchResult(false, FINISHED);
323 cur.selection() = true; // fall through
325 return mathcursor::up(cur, cur.selection()) ?
326 DispatchResult(true, true) : DispatchResult(false, FINISHED_UP);
329 cur.selection() = true; // fall through
331 return mathcursor::down(cur, cur.selection()) ?
332 DispatchResult(true, true) : DispatchResult(false, FINISHED_DOWN);
334 case LFUN_SELFINSERT:
335 if (!cmd.argument.empty()) {
336 recordUndo(cur, Undo::ATOMIC);
337 if (cmd.argument.size() == 1) {
338 if (mathcursor::interpret(cur, cmd.argument[0]))
339 return DispatchResult(true, true);
341 return DispatchResult(false, FINISHED_RIGHT);
343 mathcursor::insert(cur, cmd.argument);
348 return MathInset::priv_dispatch(cur, cmd);
353 void MathNestInset::metricsMarkers(int) const
360 void MathNestInset::metricsMarkers2(int) const
367 void MathNestInset::drawMarkers(PainterInfo & pi, int x, int y) const
371 int t = x + dim_.width() - 1;
372 int d = y + dim_.descent();
373 pi.pain.line(x, d - 3, x, d, LColor::mathframe);
374 pi.pain.line(t, d - 3, t, d, LColor::mathframe);
375 pi.pain.line(x, d, x + 3, d, LColor::mathframe);
376 pi.pain.line(t - 3, d, t, d, LColor::mathframe);
380 void MathNestInset::drawMarkers2(PainterInfo & pi, int x, int y) const
384 drawMarkers(pi, x, y);
385 int t = x + dim_.width() - 1;
386 int a = y - dim_.ascent();
387 pi.pain.line(x, a + 3, x, a, LColor::mathframe);
388 pi.pain.line(t, a + 3, t, a, LColor::mathframe);
389 pi.pain.line(x, a, x + 3, a, LColor::mathframe);
390 pi.pain.line(t - 3, a, t, a, LColor::mathframe);