*/
#include <config.h>
+#include <lyxrc.h>
#ifdef __GNUG__
#pragma implementation
#include "support/LAssert.h"
#include "debug.h"
#include "LColor.h"
-#include "Painter.h"
+#include "frontends/Painter.h"
#include "math_cursor.h"
#include "formulabase.h"
#include "math_arrayinset.h"
#include "math_factory.h"
#include "math_hullinset.h"
#include "math_iterator.h"
+#include "math_macroarg.h"
+#include "math_macrotemplate.h"
#include "math_mathmlstream.h"
#include "math_parser.h"
#include "math_replace.h"
using std::min;
using std::max;
using std::swap;
-using std::isalnum;
+using std::vector;
+using std::ostringstream;
namespace {
c1 = p->col(i1.idx_);
c2 = p->col(i2.idx_);
if (c1 > c2)
- std::swap(c1, c2);
+ swap(c1, c2);
r1 = p->row(i1.idx_);
r2 = p->row(i2.idx_);
if (r1 > r2)
- std::swap(r1, r2);
+ swap(r1, r2);
}
void grab(MathCursor const & cursor)
{
MathCursorPos i1;
MathCursorPos i2;
- cursor.getSelection(i1, i2);
+ cursor.getSelection(i1, i2);
// shouldn'tt we assert on i1.par_ == i2.par_?
if (i1.idx_ == i2.idx_) {
data_ = MathGridInset(1, 1);
} else {
row_type r1, r2;
col_type c1, c2;
- region(i1, i2, r1, r2, c1, c2);
+ region(i1, i2, r1, r2, c1, c2);
data_ = MathGridInset(c2 - c1 + 1, r2 - r1 + 1);
- for (row_type row = 0; row < data_.nrows(); ++row)
+ for (row_type row = 0; row < data_.nrows(); ++row)
for (col_type col = 0; col < data_.ncols(); ++col) {
idx_type i = i1.par_->index(row + r1, col + c1);
data_.cell(data_.index(row, col)) = i1.par_->cell(i);
{
MathCursorPos i1;
MathCursorPos i2;
- cursor.getSelection(i1, i2);
+ cursor.getSelection(i1, i2);
if (i1.idx_ == i2.idx_)
i1.cell().erase(i1.pos_, i2.pos_);
else {
MathInset * p = i1.par_;
row_type r1, r2;
col_type c1, c2;
- region(i1, i2, r1, r2, c1, c2);
- for (row_type row = r1; row <= r2; ++row)
+ region(i1, i2, r1, r2, c1, c2);
+ for (row_type row = r1; row <= r2; ++row)
for (col_type col = c1; col <= c2; ++col)
p->cell(p->index(row, col)).erase();
}
{
if (data_.nargs() == 1) {
// single cell/part of cell
- cursor.insert(data_.cell(0));
+ cursor.paste(data_.cell(0));
} else {
// mulitple cells
- idx_type idx;
+ idx_type idx; // index of upper left cell
MathGridInset * p = cursor.enclosingGrid(idx);
col_type const numcols = min(data_.ncols(), p->ncols() - p->col(idx));
row_type const numrows = min(data_.nrows(), p->nrows() - p->row(idx));
- for (row_type row = 0; row < numrows; ++row)
+ for (row_type row = 0; row < numrows; ++row) {
for (col_type col = 0; col < numcols; ++col) {
idx_type i = p->index(row + p->row(idx), col + p->col(idx));
p->cell(i).push_back(data_.cell(data_.index(row, col)));
}
+ // append the left over horizontal cells to the last column
+ idx_type i = p->index(row + p->row(idx), p->ncols() - 1);
+ for (col_type col = numcols; col < data_.ncols(); ++col)
+ p->cell(i).push_back(data_.cell(data_.index(row, col)));
+ }
+ // append the left over vertical cells to the last _cell_
+ idx_type i = p->nargs() - 1;
+ for (row_type row = numrows; row < data_.nrows(); ++row)
+ for (col_type col = 0; col < data_.ncols(); ++col)
+ p->cell(i).push_back(data_.cell(data_.index(row, col)));
}
}
MathCursor::MathCursor(InsetFormulaBase * formula, bool left)
- : formula_(formula), lastcode_(LM_TC_VAR), selection_(false)
+ : formula_(formula), lastcode_(LM_TC_MIN), selection_(false)
{
left ? first() : last();
}
bool MathCursor::popLeft()
{
- //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " left\n";
+ //cerr << "Leaving atom to the left\n";
if (Cursor_.size() <= 1)
return false;
- if (par()->asScriptInset())
- par()->asScriptInset()->removeEmptyScripts();
Cursor_.pop_back();
return true;
}
//cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n";
if (Cursor_.size() <= 1)
return false;
- if (par()->asScriptInset())
- par()->asScriptInset()->removeEmptyScripts();
Cursor_.pop_back();
posRight();
return true;
#endif
-UpdatableInset * MathCursor::asHyperActiveInset() const
-{
- return par()->asHyperActiveInset();
-}
-
-
bool MathCursor::isInside(MathInset const * p) const
{
- for (unsigned i = 0; i < Cursor_.size(); ++i)
- if (Cursor_[i].par_ == p)
+ for (unsigned i = 0; i < Cursor_.size(); ++i)
+ if (Cursor_[i].par_ == p)
return true;
return false;
}
bool MathCursor::openable(MathAtom const & t, bool sel) const
{
- if (t->isHyperActive())
- return true;
-
if (!t->isActive())
return false;
dump("Left 1");
if (inMacroMode()) {
macroModeClose();
- lastcode_ = LM_TC_VAR;
+ lastcode_ = LM_TC_MIN;
return true;
}
selHandle(sel);
- lastcode_ = LM_TC_VAR;
+ lastcode_ = LM_TC_MIN;
if (hasPrevAtom() && openable(prevAtom(), sel)) {
- if (prevAtom()->isHyperActive()) {
- lyxerr << "entering hyperactive inset\n";
- }
pushRight(prevAtom());
return true;
- }
+ }
return posLeft() || idxLeft() || popLeft() || selection_;
}
dump("Right 1");
if (inMacroMode()) {
macroModeClose();
- lastcode_ = LM_TC_VAR;
+ lastcode_ = LM_TC_MIN;
return true;
}
selHandle(sel);
- lastcode_ = LM_TC_VAR;
+ lastcode_ = LM_TC_MIN;
if (hasNextAtom() && openable(nextAtom(), sel)) {
- if (nextAtom()->isHyperActive()) {
- lyxerr << "entering hyperactive inset\n";
- int x, y;
- getPos(x, y);
- nextAtom()->edit(formula()->view(), x, y, 0);
- }
pushLeft(nextAtom());
return true;
}
bool positionable(MathCursor::cursor_type const & cursor,
- MathCursor::cursor_type const & anchor)
+ MathCursor::cursor_type const & anchor)
{
// avoid deeper nested insets when selecting
if (cursor.size() > anchor.size())
dump("home 1");
selHandle(sel);
macroModeClose();
- lastcode_ = LM_TC_VAR;
- if (!par()->idxHome(idx(), pos()))
+ lastcode_ = LM_TC_MIN;
+ if (!par()->idxHome(idx(), pos()))
popLeft();
dump("home 2");
}
dump("end 1");
selHandle(sel);
macroModeClose();
- lastcode_ = LM_TC_VAR;
+ lastcode_ = LM_TC_MIN;
if (!par()->idxEnd(idx(), pos()))
popRight();
dump("end 2");
}
+void MathCursor::markInsert()
+{
+ //lyxerr << "inserting mark\n";
+ array().insert(pos(), MathAtom(new MathCharInset(0, lastcode_)));
+}
+
+
+void MathCursor::markErase()
+{
+ //lyxerr << "deleting mark\n";
+ array().erase(pos());
+}
+
+
void MathCursor::plainInsert(MathAtom const & t)
{
array().insert(pos(), t);
void MathCursor::insert(char c, MathTextCodes t)
{
//lyxerr << "inserting '" << c << "'\n";
+ selClearOrDel();
plainInsert(MathAtom(new MathCharInset(c, t)));
}
+void MathCursor::insert(char c)
+{
+ insert(c, lastcode_);
+}
+
+
void MathCursor::insert(MathAtom const & t)
{
macroModeClose();
if (t->nargs())
selCut();
else
- selDel();
+ selClearOrDel();
}
plainInsert(t);
}
-void MathCursor::niceInsert(MathAtom const & t)
+void MathCursor::niceInsert(MathAtom const & t)
{
selCut();
insert(t); // inserting invalidates the pointer!
if (pos() == 0) {
pullArg(false);
return;
- }
+ }
if (selection_) {
selDel();
MathScriptInset * p = prevAtom()->asScriptInset();
if (p) {
p->removeScript(p->hasUp());
- // Don't delete if there is anything left
+ // Don't delete if there is anything left
if (p->hasUp() || p->hasDown())
return;
}
return;
}
- // delete empty cells if necessary
- if (array().empty()) {
- bool popit;
- bool removeit;
- par()->idxDelete(idx(), popit, removeit);
- if (popit && popLeft() && removeit)
- plainErase();
- return;
- }
+ // delete empty cells if possible
+ if (array().empty())
+ if (par()->idxDelete(idx()))
+ return;
- if (pos() == size())
+ // old behaviour when in last position of cell
+ if (pos() == size()) {
+ par()->idxGlue(idx());
return;
+ }
MathScriptInset * p = nextAtom()->asScriptInset();
if (p) {
p->removeScript(p->hasUp());
- // Don't delete if there is anything left
+ // Don't delete if there is anything left
if (p->hasUp() || p->hasDown())
return;
}
par()->asGridInset()->delRow(hullRow());
}
- if (idx() > par()->nargs())
- idx() = par()->nargs();
+ if (idx() >= par()->nargs())
+ idx() = par()->nargs() - 1;
if (pos() > size())
pos() = size();
void MathCursor::macroModeClose()
{
+ MathInset::difference_type const t = macroNamePos();
+ if (t == -1)
+ return;
string s = macroName();
- if (s.size()) {
- size_type old = pos();
- pos() -= s.size();
- array().erase(pos(), old);
+ array().erase(t, pos());
+ pos() = t;
+ if (s != "\\")
interpret(s);
- }
}
-int MathCursor::macroNamePos() const
+MathInset::difference_type MathCursor::macroNamePos() const
{
- for (int i = pos() - 1; i >= 0; --i) {
+ for (MathInset::difference_type i = pos() - 1; i >= 0; --i) {
MathAtom & p = array().at(i);
if (p->code() == LM_TC_TEX && p->getChar() == '\\')
return i;
string MathCursor::macroName() const
{
string s;
- for (int i = macroNamePos(); i >= 0 && i < int(pos()); ++i)
+ MathInset::difference_type i = macroNamePos();
+ for (; i >= 0 && i < int(pos()); ++i)
s += array().at(i)->getChar();
return s;
}
dump("selCopy");
if (selection_) {
theSelection.grab(*this);
- selClear();
+ //selClear();
}
}
void MathCursor::selPaste()
{
dump("selPaste");
+ selClearOrDel();
theSelection.paste(*this);
//theSelection.grab(*this);
- //selClear();
+ selClear();
}
}
+void MathCursor::selClearOrDel()
+{
+ if (lyxrc.auto_region_delete)
+ selDel();
+ else
+ selClear();
+}
+
+
void MathCursor::selGet(MathArray & ar)
{
dump("selGet");
int y2 = c.yo() + c.descent();
pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
} else {
- std::vector<MathInset::idx_type> indices
+ vector<MathInset::idx_type> indices
= i1.par_->idxBetween(i1.idx_, i2.idx_);
for (unsigned i = 0; i < indices.size(); ++i) {
MathXArray & c = i1.xcell(indices[i]);
if (selection_) {
MathCursorPos i1;
MathCursorPos i2;
- getSelection(i1, i2);
+ getSelection(i1, i2);
if (i1.idx_ == i2.idx_) {
MathArray & ar = i1.cell();
for (MathInset::pos_type pos = i1.pos_; pos != i2.pos_; ++pos)
ar.at(pos)->handleFont(t);
}
- } else
+ } else
lastcode_ = (lastcode_ == t) ? LM_TC_VAR : t;
}
#warning This should probably take cellXOffset and cellYOffset into account
#endif
x = xarray().xo() + xarray().pos2x(pos());
+ // move cursor visually into empty cells ("blue rectangles");
+ if (array().empty())
+ x += 2;
y = xarray().yo();
}
}
+bool MathCursor::inMacroArgMode() const
+{
+ return pos() > 0 && prevAtom()->getChar() == '#';
+}
+
+
bool MathCursor::selection() const
{
return selection_;
MathGridInset * MathCursor::enclosingGrid(MathCursor::idx_type & idx) const
{
- for (int i = Cursor_.size() - 1; i >= 0; --i) {
+ for (MathInset::difference_type i = Cursor_.size() - 1; i >= 0; --i) {
MathGridInset * p = Cursor_[i].par_->asGridInset();
if (p) {
idx = Cursor_[i].idx_;
return p;
+ lyxerr << "found grid and idx: " << idx << "\n";
}
}
return 0;
}
+void MathCursor::popToEnclosingGrid()
+{
+ while (Cursor_.size() && !Cursor_.back().par_->asGridInset())
+ Cursor_.pop_back();
+}
+
+
void MathCursor::pullArg(bool goright)
{
dump("pullarg");
if (popLeft()) {
plainErase();
array().insert(pos(), a);
- if (goright)
+ if (goright)
pos() += a.size();
+ } else {
+ formula()->mutateToText();
}
}
+void MathCursor::touch()
+{
+ cursor_type::const_iterator it = Cursor_.begin();
+ cursor_type::const_iterator et = Cursor_.end();
+ for ( ; it != et; ++it)
+ it->xcell().touch();
+}
+
+
void MathCursor::normalize()
{
+#if 0
// rebreak
{
MathIterator it = ibegin(formula()->par().nucleus());
MathIterator et = iend(formula()->par().nucleus());
- for ( ; it != et; ++it)
+ for (; it != et; ++it)
if (it.par()->asBoxInset())
it.par()->asBoxInset()->rebreak();
}
+#endif
- if (idx() >= par()->nargs()) {
+ if (idx() >= par()->nargs()) {
lyxerr << "this should not really happen - 1: "
<< idx() << " " << par()->nargs() << "\n";
dump("error 2");
}
- idx() = min(idx(), par()->nargs() - 1);
+ idx() = min(idx(), par()->nargs() - 1);
if (pos() > size()) {
lyxerr << "this should not really happen - 2: "
<< pos() << " " << size() << " in idx: " << idx()
<< " in atom: '";
- WriteStream wi(lyxerr, false);
+ WriteStream wi(lyxerr, false, true);
par()->write(wi);
lyxerr << "\n";
dump("error 4");
}
pos() = min(pos(), size());
+
+ // remove empty scripts if possible
+ if (1) {
+ for (pos_type i = 0; i < size(); ++i) {
+ MathScriptInset * p = array().at(i)->asScriptInset();
+ if (p) {
+ p->removeEmptyScripts();
+ //if (p->empty())
+ // array().erase(i);
+ }
+ }
+ }
+
+ // fix again position
+ pos() = min(pos(), size());
}
void MathCursor::splitCell()
{
- if (idx() + 1 == par()->nargs())
+ if (idx() + 1 == par()->nargs())
return;
MathArray ar = array();
ar.erase(0, pos());
bool MathCursor::goUpDown(bool up)
{
+ // Be warned: The 'logic' implemented in this function is highly fragile.
+ // A distance of one pixel or a '<' vs '<=' _really_ matters.
+ // So fiddle around with it only if you know what you are doing!
int xlow, xhigh, ylow, yhigh;
int xo, yo;
getPos(xo, yo);
- // try current cell first
- xarray().boundingBox(xlow, xhigh, ylow, yhigh);
- if (up)
- yhigh = yo - 4;
- else
- ylow = yo + 4;
- if (bruteFind(xo, yo, xlow, xhigh, ylow, yhigh))
- return true;
+ // try neigbouring script insets
+ // try left
+ if (hasPrevAtom()) {
+ MathScriptInset * p = prevAtom()->asScriptInset();
+ if (p && p->has(up)) {
+ --pos();
+ push(nextAtom());
+ idx() = up; // the superscript has index 1
+ pos() = size();
+ ///lyxerr << "updown: handled by scriptinset to the left\n";
+ return true;
+ }
+ }
+
+ // try right
+ if (hasNextAtom()) {
+ MathScriptInset * p = nextAtom()->asScriptInset();
+ if (p && p->has(up)) {
+ push(nextAtom());
+ idx() = up;
+ pos() = 0;
+ ///lyxerr << "updown: handled by scriptinset to the right\n";
+ return true;
+ }
+ }
+
+ // try current cell
+ //xarray().boundingBox(xlow, xhigh, ylow, yhigh);
+ //if (up)
+ // yhigh = yo - 4;
+ //else
+ // ylow = yo + 4;
+ //if (bruteFind(xo, yo, xlow, xhigh, ylow, yhigh)) {
+ // lyxerr << "updown: handled by brute find in the same cell\n";
+ // return true;
+ //}
// try to find an inset that knows better then we
while (1) {
- // we found a cell that think something "below" us.
- if (up) {
- if (par()->idxUp(idx()))
- break;
- } else {
- if (par()->idxDown(idx()))
- break;
+ ///lyxerr << "updown: We are in " << *par() << " idx: " << idx() << '\n';
+ // ask inset first
+ if (par()->idxUpDown(idx(), up)) {
+ // we found a cell that thinks it has something "below" us.
+ ///lyxerr << "updown: found inset that handles UpDown\n";
+ xarray().boundingBox(xlow, xhigh, ylow, yhigh);
+ // project (xo,yo) onto proper box
+ ///lyxerr << "\n xo: " << xo << " yo: " << yo
+ /// << "\n xlow: " << xlow << " ylow: " << ylow
+ /// << "\n xhigh: " << xhigh << " yhigh: " << yhigh;
+ xo = min(max(xo, xlow), xhigh);
+ yo = min(max(yo, ylow), yhigh);
+ ///lyxerr << "\n xo2: " << xo << " yo2: " << yo << "\n";
+ bruteFind(xo, yo, xlow, xhigh, ylow, yhigh);
+ ///lyxerr << "updown: handled by final brute find\n";
+ return true;
}
+ // leave inset
if (!popLeft()) {
// no such inset found, just take something "above"
+ ///lyxerr << "updown: handled by strange case\n";
return
bruteFind(xo, yo,
formula()->xlow(),
up ? yo - 4 : formula()->yhigh()
);
}
+
+ // any improvement so far?
+ int xnew, ynew;
+ getPos(xnew, ynew);
+ if (up ? ynew < yo : ynew > yo)
+ return true;
}
- xarray().boundingBox(xlow, xhigh, ylow, yhigh);
- bruteFind(xo, yo, xlow, xhigh, ylow, yhigh);
- return true;
}
-bool MathCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh)
+bool MathCursor::bruteFind
+ (int x, int y, int xlow, int xhigh, int ylow, int yhigh)
{
cursor_type best_cursor;
double best_dist = 1e10;
MathIterator it = ibegin(formula()->par().nucleus());
MathIterator et = iend(formula()->par().nucleus());
- for ( ; it != et; ++it) {
- // avoid invalid nesting hen selecting
- if (selection_ && !positionable(it.cursor(), Anchor_))
- continue;
- int xo = it.position().xpos();
- int yo = it.position().ypos();
- if (xlow - 2 <= xo && xo <= xhigh + 2 &&
- ylow - 2 <= yo && yo <= yhigh + 2)
- {
- double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
- if (d < best_dist) {
- best_dist = d;
- best_cursor = it.cursor();
+ while (1) {
+ // avoid invalid nesting when selecting
+ if (!selection_ || positionable(it.cursor(), Anchor_)) {
+ MathCursorPos const & top = it.position();
+ int xo = top.xpos();
+ int yo = top.ypos();
+ if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
+ double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
+ // '<=' in order to take the last possible position
+ // this is important for clicking behind \sum in e.g. '\sum_i a'
+ if (d <= best_dist) {
+ best_dist = d;
+ best_cursor = it.cursor();
+ }
}
}
+
+ if (it == et)
+ break;
+ ++it;
}
+
if (best_dist < 1e10)
Cursor_ = best_cursor;
return best_dist < 1e10;
if (s.empty())
return true;
- if (s.size() == 1)
- return interpret(s[0]);
-
//lyxerr << "char: '" << s[0] << "' int: " << int(s[0]) << endl;
- //owner_->getIntl()->getTrans().TranslateAndInsert(s[0], lt);
+ //owner_->getIntl()->getTrans().TranslateAndInsert(s[0], lt);
//lyxerr << "trans: '" << s[0] << "' int: " << int(s[0]) << endl;
if (s.size() >= 5 && s.substr(0, 5) == "cases") {
unsigned int n = 1;
istringstream is(s.substr(5).c_str());
is >> n;
- n = std::max(1u, n);
+ n = max(1u, n);
niceInsert(MathAtom(new MathCasesInset(n)));
return true;
}
string h_align;
istringstream is(s.substr(6).c_str());
is >> m >> n >> v_align >> h_align;
- m = std::max(1u, m);
- n = std::max(1u, n);
+ m = max(1u, m);
+ n = max(1u, n);
v_align += 'c';
- niceInsert(MathAtom(new MathArrayInset(m, n, v_align[0], h_align)));
+ niceInsert(MathAtom(new MathArrayInset("array", m, n, v_align[0], h_align)));
return true;
}
return true;
}
- if (s == "\\over" || s == "\\choose" || s == "\\atop") {
+ string name = s.substr(1);
+
+ if (name == "over" || name == "choose" || name == "atop") {
MathArray ar = array();
- MathAtom t(createMathInset(s.substr(1)));
+ MathAtom t(createMathInset(name));
t->asNestInset()->cell(0).swap(array());
pos() = 0;
niceInsert(t);
return true;
}
- latexkeys const * l = in_word_set(s.substr(1));
+ latexkeys const * l = in_word_set(name);
if (l && (l->token == LM_TK_FONT || l->token == LM_TK_OLDFONT)) {
lastcode_ = static_cast<MathTextCodes>(l->id);
return true;
}
- niceInsert(createMathInset(s.substr(1)));
+ // prevent entering of recursive macros
+ if (formula()->lyxCode() == Inset::MATHMACRO_CODE
+ && formula()->getInsetName() == name)
+ {
+ lyxerr << "can't enter recursive macro\n";
+ return true;
+ }
+
+ niceInsert(createMathInset(name));
return true;
}
bool MathCursor::script(bool up)
{
+ // Hack to get \\^ and \\_ working
+ if (inMacroMode() && macroName() == "\\") {
+ if (up)
+ interpret("\\mathcircumflex");
+ else
+ interpret('_');
+ return true;
+ }
+
macroModeClose();
selCut();
if (hasPrevAtom() && prevAtom()->asScriptInset()) {
bool MathCursor::interpret(char c)
{
-
- // Removed super/subscript handling from here to ::script -MV
+ //lyxerr << "interpret 2: '" << c << "'\n";
+ if (inMacroArgMode()) {
+ --pos();
+ plainErase();
+ int n = c - '0';
+ MathMacroTemplate * p = formula()->par()->asMacroTemplate();
+ if (p && 1 <= n && n <= p->numargs())
+ insert(MathAtom(new MathMacroArgument(c - '0', lastcode_)));
+ else {
+ insert(MathAtom(new MathSpecialCharInset('#')));
+ interpret(c); // try again
+ }
+ return true;
+ }
// handle macroMode
if (inMacroMode()) {
string name = macroName();
+ //lyxerr << "interpret name: '" << name << "'\n";
- if (name == "\\" && c == '#') {
+ // extend macro name if possible
+ if (isalpha(c)) {
insert(c, LM_TC_TEX);
return true;
}
- if (name == "\\" && c == '\\') {
- backspace();
- interpret("\\backslash");
- return true;
- }
-
- if (name == "\\#" && '1' <= c && c <= '9') {
- insert(c, LM_TC_TEX);
+ // leave macro mode if explicitly requested
+ if (c == ' ') {
macroModeClose();
return true;
}
- if (isalpha(c)) {
- insert(c, LM_TC_TEX);
- return true;
- }
-
+ // handle 'special char' macros
if (name == "\\") {
- insert(c, LM_TC_TEX);
- macroModeClose();
+ // remove the '\\'
+ backspace();
+ if (c == '\\')
+ interpret("\\backslash");
+ else
+ interpret(string("\\") + c);
return true;
}
+ // leave macro mode and try again
macroModeClose();
+ interpret(c);
return true;
}
- if (selection_) {
+ // just clear selection on pressing the space par
+ if (selection_ && c == ' ') {
selClear();
- if (c == ' ')
- return true;
- // fall through in the other cases
+ return true;
}
+ selClearOrDel();
+
if (lastcode_ == LM_TC_TEXTRM || par()->asBoxInset()) {
// suppress direct insertion of two spaces in a row
// the still allows typing '<space>a<space>' and deleting the 'a', but
return pos() != size();
}
+ if (c == '#') {
+ insert(c, LM_TC_TEX);
+ return true;
+ }
+
/*
- if (strchr("{}", c)) {
+ if (c == '{' || c == '}', c)) {
insert(c, LM_TC_TEX);
return true;
}
return true;
}
- if (strchr("#$%", c)) {
- insert(MathAtom(new MathSpecialCharInset(c)));
+ if (c == '$' || c == '%') {
+ insert(MathAtom(new MathSpecialCharInset(c)));
lastcode_ = LM_TC_VAR;
return true;
}
if (c == '\\') {
insert(c, LM_TC_TEX);
//bv->owner()->message(_("TeX mode"));
- return true;
+ return true;
}
// no special circumstances, so insert the character without any fuss
- insert(c, lastcode_);
+ insert(c, lastcode_ == LM_TC_MIN ? MathCharInset::nativeCode(c) : lastcode_);
lastcode_ = LM_TC_MIN;
return true;
}
// delete everything behind this position
ar.erase(et - ar.begin(), ar.size());
- pos() = ar.size();
+ pos() = ar.size();
}
Cursor_ = where;
cursor().pos_ += n;
}
+
+
+string MathCursor::info() const
+{
+ ostringstream os;
+ if (pos() > 0)
+ prevAtom()->infoize(os);
+ return os.str().c_str(); // .c_str() needed for lyxstring
+}