using std::istringstream;
+namespace {
+
+// local global
+int first_x;
+int first_y;
+
+} // namespace anon
+
+
+
+
MathNestInset::MathNestInset(idx_type nargs)
: cells_(nargs), lock_(false)
{}
void MathNestInset::getCursorPos(CursorSlice const & cur,
int & x, int & y) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
MathArray const & ar = cur.cell();
x = ar.xo() + ar.pos2x(cur.pos());
y = ar.yo();
bool MathNestInset::idxNext(LCursor & cur) const
{
- if (cur.idx() + 1 >= nargs())
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
+ if (cur.idx() == cur.lastidx())
return false;
++cur.idx();
cur.pos() = 0;
bool MathNestInset::idxPrev(LCursor & cur) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
if (cur.idx() == 0)
return false;
--cur.idx();
bool MathNestInset::idxFirst(LCursor & cur) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
if (nargs() == 0)
return false;
cur.idx() = 0;
bool MathNestInset::idxLast(LCursor & cur) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
if (nargs() == 0)
return false;
- cur.idx() = nargs() - 1;
+ cur.idx() = cur.lastidx();
cur.pos() = cur.lastpos();
return true;
}
bool MathNestInset::idxHome(LCursor & cur) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
if (cur.pos() == 0)
return false;
cur.pos() = 0;
bool MathNestInset::idxEnd(LCursor & cur) const
{
+ BOOST_ASSERT(ptr_cmp(cur.inset(), this));
if (cur.lastpos() == cur.lastpos())
return false;
cur.pos() = cur.lastpos();
}
-void MathNestInset::drawSelection(PainterInfo & pi,
- idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
+void MathNestInset::drawSelection(PainterInfo & pi, int, int) const
{
- if (idx1 == idx2) {
- MathArray const & c = cell(idx1);
- int x1 = c.xo() + c.pos2x(pos1);
+ // this should use the x/y values given, not the cached values
+ LCursor & cur = pi.base.bv->cursor();
+ if (!cur.selection())
+ return;
+ if (!ptr_cmp(cur.inset(), this))
+ return;
+ CursorSlice & s1 = cur.selBegin();
+ CursorSlice & s2 = cur.selEnd();
+ if (s1.idx() == s2.idx()) {
+ MathArray const & c = cell(s1.idx());
+ int x1 = c.xo() + c.pos2x(s1.pos());
int y1 = c.yo() - c.ascent();
- int x2 = c.xo() + c.pos2x(pos2);
+ int x2 = c.xo() + c.pos2x(s2.pos());
int y2 = c.yo() + c.descent();
pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
} else {
for (idx_type i = 0; i < nargs(); ++i) {
- if (idxBetween(i, idx1, idx2)) {
+ if (idxBetween(i, s1.idx(), s2.idx())) {
MathArray const & c = cell(i);
int x1 = c.xo();
int y1 = c.yo() - c.ascent();
{
// this whole function is a hack and won't work for incremental font
// changes...
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
if (cur.inset()->asMathInset()->name() == font)
cur.handleFont(font);
void MathNestInset::handleFont2(LCursor & cur, string const & arg)
{
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
LyXFont font;
bool b;
bv_funcs::string2font(arg, font, b);
DispatchResult
MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
- lyxerr << "*** MathNestInset: request: " << cmd << std::endl;
- //lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
- // << " arg: '" << cmd.argument
- // << "' x: '" << cmd.x
- // << " y: '" << cmd.y
- // << "' button: " << cmd.button() << endl;
+ lyxerr << "MathNestInset: request: " << cmd << std::endl;
switch (cmd.action) {
is >> n;
if (was_macro)
cur.macroModeClose();
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.selPaste(n);
return DispatchResult(true, true);
}
return dispatch(cur, FuncRequest(LFUN_PASTE, cur.bv().getClipboard()));
case LFUN_MOUSE_PRESS:
- if (cmd.button() == mouse_button::button2)
- return priv_dispatch(cur, FuncRequest(LFUN_PASTESELECTION));
- return DispatchResult(false);
+ return lfunMousePress(cur, cmd);
+ case LFUN_MOUSE_MOTION:
+ return lfunMouseMotion(cur, cmd);
+ case LFUN_MOUSE_RELEASE:
+ return lfunMouseRelease(cur, cmd);
+ case LFUN_MOUSE_DOUBLE:
+ return dispatch(cur, FuncRequest(LFUN_WORDSEL));
case LFUN_RIGHTSEL:
- cur.selection() = true; // fall through...
case LFUN_RIGHT:
+ cur.selHandle(cmd.action == LFUN_RIGHTSEL);
return cur.right() ?
DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
- //lyxerr << "calling scroll 20" << endl;
- //scroll(&cur.bv(), 20);
- // write something to the minibuffer
- //cur.bv().owner()->message(cur.info());
case LFUN_LEFTSEL:
- cur.selection() = true; // fall through
case LFUN_LEFT:
+ cur.selHandle(cmd.action == LFUN_LEFTSEL);
return cur.left() ?
DispatchResult(true, true) : DispatchResult(false, FINISHED);
case LFUN_UPSEL:
- cur.selection() = true; // fall through
case LFUN_UP:
+ cur.selHandle(cmd.action == LFUN_UPSEL);
return cur.up() ?
DispatchResult(true, true) : DispatchResult(false, FINISHED_UP);
case LFUN_DOWNSEL:
- cur.selection() = true; // fall through
case LFUN_DOWN:
+ cur.selHandle(cmd.action == LFUN_DOWNSEL);
return cur.down() ?
DispatchResult(true, true) : DispatchResult(false, FINISHED_DOWN);
case LFUN_WORDSEL:
cur.home();
+ cur.resetAnchor();
cur.selection() = true;
cur.end();
return DispatchResult(true, true);
case LFUN_DOWN_PARAGRAPH:
return DispatchResult(true, FINISHED);
- case LFUN_HOMESEL:
case LFUN_WORDLEFTSEL:
- cur.selection() = true; // fall through
- case LFUN_HOME:
case LFUN_WORDLEFT:
+ cur.selHandle(cmd.action == LFUN_WORDLEFTSEL);
return cur.home()
? DispatchResult(true, true) : DispatchResult(true, FINISHED);
- case LFUN_ENDSEL:
case LFUN_WORDRIGHTSEL:
- cur.selection() = true; // fall through
- case LFUN_END:
case LFUN_WORDRIGHT:
+ cur.selHandle(cmd.action == LFUN_WORDRIGHTSEL);
+ return cur.end()
+ ? DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
+
+ case LFUN_HOMESEL:
+ case LFUN_HOME:
+ cur.selHandle(cmd.action == LFUN_HOMESEL);
+ return cur.home()
+ ? DispatchResult(true, true) : DispatchResult(true, FINISHED);
+
+ case LFUN_ENDSEL:
+ case LFUN_END:
+ cur.selHandle(cmd.action == LFUN_ENDSEL);
return cur.end()
? DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
case LFUN_DELETE_WORD_BACKWARD:
case LFUN_BACKSPACE:
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.backspace();
return DispatchResult(true, true);
case LFUN_DELETE_WORD_FORWARD:
case LFUN_DELETE:
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.erase();
return DispatchResult(true, FINISHED);
case LFUN_SELFINSERT:
if (!cmd.argument.empty()) {
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
if (cmd.argument.size() == 1) {
if (cur.interpret(cmd.argument[0]))
return DispatchResult(true, true);
//
// this needs to be incorporated
//
- //lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
- // << " arg: '" << cmd.argument
- // << "' x: '" << cmd.x
- // << " y: '" << cmd.y
- // << "' button: " << cmd.button() << endl;
-
// delete empty mathbox (LFUN_BACKSPACE and LFUN_DELETE)
bool remove_inset = false;
- switch (cmd.action) {
- case LFUN_MOUSE_PRESS:
- //lyxerr << "Mouse single press" << endl;
- return lfunMousePress(cur, cmd);
- case LFUN_MOUSE_MOTION:
- //lyxerr << "Mouse motion" << endl;
- return lfunMouseMotion(cur, cmd);
- case LFUN_MOUSE_RELEASE:
- //lyxerr << "Mouse single release" << endl;
- return lfunMouseRelease(cur, cmd);
- case LFUN_MOUSE_DOUBLE:
- //lyxerr << "Mouse double" << endl;
- return dispatch(cur, FuncRequest(LFUN_WORDSEL));
- default:
- break;
- }
-
DispatchResult result(true);
bool was_macro = cur.inMacroMode();
cur.normalize();
cur.touch();
-
- switch (cmd.action) {
-
- case LFUN_MATH_LIMITS:
- recordUndo(cur, Undo::ATOMIC);
- cur.dispatch(cmd);
- break;
#endif
// case LFUN_GETXY:
}
case LFUN_CUT:
- recordUndo(cur, Undo::DELETE);
+ //recordUndo(cur, Undo::DELETE);
cur.selCut();
return DispatchResult(true, true);
if (cmd.argument.empty()) {
// do superscript if LyX handles
// deadkeys
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.script(true);
}
return DispatchResult(true, true);
cur.selClearOrDel();
cur.plainInsert(MathAtom(new MathMBoxInset(cur.bv())));
cur.posLeft();
- cur.pushLeft(cur.nextAtom().nucleus());
+ cur.pushLeft(cur.nextInset());
#else
if (cur.currentMode() == InsetBase::TEXT_MODE)
cur.niceInsert(MathAtom(new MathHullInset("simple")));
case LFUN_MATH_SIZE:
#if 0
if (!arg.empty()) {
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.setSize(arg);
}
#endif
return DispatchResult(true, true);
case LFUN_INSERT_MATRIX: {
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
unsigned int m = 1;
unsigned int n = 1;
string v_align;
}
case LFUN_MATH_DELIM: {
- //lyxerr << "formulabase::LFUN_MATH_DELIM, arg: '" << arg << "'" << endl;
+ lyxerr << "MathNestInset::LFUN_MATH_DELIM" << endl;
string ls;
string rs = lyx::support::split(cmd.argument, ls, ' ');
// Reasonable default values
ls = '(';
if (rs.empty())
rs = ')';
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.handleNest(MathAtom(new MathDelimInset(ls, rs)));
return DispatchResult(true, true);
}
case LFUN_SPACE_INSERT:
case LFUN_MATH_SPACE:
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.insert(MathAtom(new MathSpaceInset(",")));
return DispatchResult(true, true);
case LFUN_INSET_ERT:
// interpret this as if a backslash was typed
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.interpret('\\');
return DispatchResult(true, true);
-#if 0
- case LFUN_BREAKPARAGRAPH:
- case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
- case LFUN_BREAKPARAGRAPH_SKIP:
- cmd.argument = "\n";
- recordUndo(cur, Undo::ATOMIC);
- cur.niceInsert(argument);
- return DispatchResult(true, true);
-#endif
-
// FIXME: We probably should swap parts of "math-insert" and "self-insert"
// handling such that "self-insert" works on "arbitrary stuff" too, and
// math-insert only handles special math things like "matrix".
case LFUN_INSERT_MATH:
- recordUndo(cur, Undo::ATOMIC);
+ //recordUndo(cur, Undo::ATOMIC);
cur.niceInsert(cmd.argument);
return DispatchResult(true, true);
searchForward(&cur.bv(), cmd.getArg(0), false, false)
? DispatchResult(true, true) : DispatchResult(false);
- case LFUN_INSERT_MATH:
- case LFUN_INSERT_MATRIX:
- case LFUN_MATH_DELIM: {
- MathHullInset * f = new MathHullInset;
- if (openNewInset(cur, f)) {
- cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
- cur.inset()->dispatch(cur, cmd);
- }
- return DispatchResult(true, true);
- }
-
cur.normalize();
cur.touch();
}
-void MathNestInset::edit(LCursor & cur, int x, int y)
+void MathNestInset::edit(LCursor & cur, bool left)
{
- lyxerr << "Called MathHullInset::edit with '" << x << ' ' << y << "'" << endl;
cur.push(this);
+ cur.idx() = left ? 0 : cur.lastidx();
+ cur.pos() = left ? 0 : cur.lastpos();
+ cur.resetAnchor();
+}
+
+
+void MathNestInset::edit(LCursor & cur, int x, int y)
+{
int idx_min = 0;
int dist_min = 1000000;
for (idx_type i = 0; i < nargs(); ++i) {
ar[i].nucleus()->edit(cur, x, y);
}
}
+
+
+DispatchResult
+MathNestInset::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
+{
+ //lyxerr << "lfunMouseRelease: buttons: " << cmd.button() << endl;
+
+ if (cmd.button() == mouse_button::button1) {
+ // try to dispatch to enclosed insets first
+ //cur.bv().stuffClipboard(cur.grabSelection());
+ return DispatchResult(true, true);
+ }
+
+ if (cmd.button() == mouse_button::button2) {
+ MathArray ar;
+ asArray(cur.bv().getClipboard(), ar);
+ cur.selClear();
+ cur.setScreenPos(cmd.x, cmd.y);
+ cur.insert(ar);
+ cur.bv().update();
+ return DispatchResult(true, true);
+ }
+
+ if (cmd.button() == mouse_button::button3) {
+ // try to dispatch to enclosed insets first
+ cur.bv().owner()->getDialogs().show("mathpanel");
+ return DispatchResult(true, true);
+ }
+
+ return DispatchResult(false);
+}
+
+
+DispatchResult
+MathNestInset::lfunMousePress(LCursor & cur, FuncRequest const & cmd)
+{
+ lyxerr << "lfunMousePress: buttons: " << cmd.button() << endl;
+ if (cmd.button() == mouse_button::button1) {
+ first_x = cmd.x;
+ first_y = cmd.y;
+ cur.selClear();
+ //cur.setScreenPos(cmd.x + xo_, cmd.y + yo_);
+ lyxerr << "lfunMousePress: setting cursor to: " << cur << endl;
+ cur.bv().cursor() = cur;
+ return DispatchResult(true, true);
+ }
+
+ if (cmd.button() == mouse_button::button2) {
+ return priv_dispatch(cur, FuncRequest(LFUN_PASTESELECTION));
+ }
+
+ if (cmd.button() == mouse_button::button3) {
+ return DispatchResult(true, true);
+ }
+
+ return DispatchResult(true, true);
+}
+
+
+DispatchResult
+MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest const & cmd)
+{
+ // only select with button 1
+ if (cmd.button() != mouse_button::button1)
+ return DispatchResult(true, true);
+
+ if (abs(cmd.x - first_x) < 2 && abs(cmd.y - first_y) < 2)
+ return DispatchResult(true, true);
+
+ first_x = cmd.x;
+ first_y = cmd.y;
+
+ if (!cur.selection())
+ cur.selBegin();
+
+ //cur.setScreenPos(cmd.x + xo_, cmd.y + yo_);
+ cur.bv().cursor().cursor_ = cur.cursor_;
+ cur.bv().cursor().selection() = true;
+ return DispatchResult(true, true);
+}