#include "math_cursor.h"
#include "math_arrayinset.h"
#include "math_bigopinset.h"
+#include "math_symbolinset.h"
#include "math_decorationinset.h"
#include "math_deliminset.h"
#include "math_dotsinset.h"
#include "math_fracinset.h"
#include "math_funcinset.h"
+#include "math_funcliminset.h"
#include "math_gridinset.h"
#include "math_macro.h"
#include "math_macroarg.h"
}
+MathCursor::~MathCursor()
+{
+ delete imacro_;
+}
+
void MathCursor::push(MathInset * par, bool first)
{
MathCursorPos p;
}
-void MathCursor::seldump(char const *) const
+void MathCursor::seldump(char const * str) const
{
//lyxerr << "SEL: " << str << ": '" << theSelection << "'\n";
//dump(" Pos");
return;
- //lyxerr << "\n\n\\n=================vvvvvvvvvvvvv======================= "
- // << str << "\ntheSelection: " << theSelection;
- //for (unsigned int i = 0; i < Cursor_.size(); ++i)
- // lyxerr << Cursor_[i].par_ << "\n'" << Cursor_[i].cell() << "'\n";
+ lyxerr << "\n\n\n=================vvvvvvvvvvvvv======================= "
+ << str << "\ntheSelection: " << selection_
+ << " '" << theSelection.glue() << "'\n";
+ for (unsigned int i = 0; i < Cursor_.size(); ++i)
+ lyxerr << Cursor_[i].par_ << "\n'" << Cursor_[i].cell() << "'\n";
+ lyxerr << "\n";
+ for (unsigned int i = 0; i < Anchor_.size(); ++i)
+ lyxerr << Anchor_[i].par_ << "\n'" << Anchor_[i].cell() << "'\n";
//lyxerr << "\ncursor.pos_: " << cursor().pos_;
//lyxerr << "\nanchor.pos_: " << anchor().pos_;
- //lyxerr << "\n===================^^^^^^^^^^^^=====================\n\n\n";
+ lyxerr << "\n===================^^^^^^^^^^^^=====================\n\n\n";
}
-bool MathCursor::isInside(MathInset * p) const
+bool MathCursor::isInside(MathInset const * p) const
{
for (unsigned i = 0; i < Cursor_.size(); ++i)
if (parInset(i) == p)
{
if (!p)
return false;
+
if (!(p->isActive() || (useupdown && p->isScriptInset())))
return false;
}
-bool MathCursor::plainLeft()
+void MathCursor::plainLeft()
+{
+ --cursor().pos_;
+}
+
+
+void MathCursor::plainRight()
{
- return array().prev(cursor().pos_);
+ ++cursor().pos_;
}
push(p, false);
return true;
}
- if (plainLeft())
+ if (cursor().pos_) {
+ plainLeft();
return true;
+ }
if (cursor().par_->idxLeft(cursor().idx_, cursor().pos_))
return true;
if (pop())
}
-bool MathCursor::plainRight()
-{
- return array().next(cursor().pos_);
-}
-
-
bool MathCursor::right(bool sel)
{
dump("Right 1");
push(p, true);
return true;
}
- if (array().next(cursor().pos_))
+ if (cursor().pos_ != array().size()) {
+ plainRight();
return true;
- if (cursor().par_->idxRight(cursor().idx_, cursor().pos_))
+ }
+ if (cursor().par_->idxRight(cursor().idx_, cursor().pos_)) {
return true;
- if (!pop())
- return false;
- array().next(cursor().pos_);
- return true;
+ }
+ if (pop()) {
+ plainRight();
+ return true;
+ }
+ return false;
}
void MathCursor::first()
{
Cursor_.clear();
- push(formula_->par(), true);
+ push(outerPar(), true);
}
void MathCursor::last()
{
Cursor_.clear();
- push(formula_->par(), false);
+ push(outerPar(), false);
}
lastcode_ = LM_TC_MIN;
first();
- cursor().par_ = formula()->par();
+ cursor().par_ = outerPar();
while (1) {
cursor().idx_ = -1;
clearLastCode();
if (!cursor().par_->idxEnd(cursor().idx_, cursor().pos_)) {
pop();
- array().next(cursor().pos_);
+ ++cursor().pos_;
}
dump("end 2");
}
}
array().insert(cursor().pos_, c, t);
- array().next(cursor().pos_);
+ plainRight();
}
}
array().insert(cursor().pos_, p);
- array().next(cursor().pos_);
+ plainRight();
}
}
// delete empty cells if necessary
- if (cursor().pos_ == 0 && array().size() == 0) {
+ if (cursor().pos_ == 0 && array().empty()) {
bool popit;
bool removeit;
cursor().par_->idxDelete(cursor().idx_, popit, removeit);
bool MathCursor::toggleLimits()
{
- if (!prevIsInset())
+ MathScriptInset * p = prevScriptInset();
+ if (!p)
return false;
- MathInset * p = prevInset();
int old = p->limits();
p->limits(old < 0 ? 1 : -1);
return old != p->limits();
//lyxerr << "interpret: '" << s << "'\n";
//lyxerr << "in: " << in_word_set(s) << " \n";
- if (s.size() && (s[0] == '^' || s[0] == '_')) {
+ if (s.empty())
+ return;
+
+ if (s[0] == '^' || s[0] == '_') {
bool const up = (s[0] == '^');
selCut();
MathScriptInset * p = prevScriptInset();
p = pp;
}
else
- p = new MathFuncInset(s, LM_OT_UNDEF);
+ p = new MathFuncInset(s);
} else {
switch (l->token) {
- case LM_TK_BIGSYM:
- p = new MathBigopInset(s, l->id);
+ case LM_TK_BIGSYM:
+ p = new MathBigopInset(l);
+ break;
+
+ case LM_TK_FUNCLIM:
+ p = new MathFuncLimInset(l);
break;
-
- case LM_TK_SYM: {
- MathTextCodes code = static_cast<MathTextCodes>(l->id);
- if (code < 255)
- insert(l->id, l->bin != LMB_NONE ? LM_TC_BOPS : LM_TC_SYMB);
- else
- p = new MathFuncInset(l->name);
+
+ case LM_TK_SYM:
+ p = new MathSymbolInset(l);
break;
- }
case LM_TK_STACK:
p = new MathFracInset("stackrel");
break;
case LM_TK_DECORATION:
- p = new MathDecorationInset(l->name, l->id);
- break;
-
- case LM_TK_FUNCLIM:
- p = new MathFuncInset(l->name, LM_OT_FUNCLIM);
+ p = new MathDecorationInset(l);
break;
case LM_TK_SPACE:
break;
case LM_TK_DOTS:
- p = new MathDotsInset(l->name, l->id);
+ p = new MathDotsInset(l);
break;
case LM_TK_MACRO:
}
if (p) {
- bool oldsel = selection_;
- if (oldsel)
- selCut();
+ selCut();
insert(p);
if (p->nargs()) {
plainLeft();
- right(); // do not push for e.g. MathBigopInset
- if (oldsel)
- selPaste();
+ right(); // do not push for e.g. MathSymbolInset
+ selPaste();
}
p->metrics(p->size());
}
if (!imacro_) {
imacro_ = new MathFuncInset("");
array().insert(cursor().pos_, imacro_);
- array().next(cursor().pos_);
+ ++cursor().pos_;
//insert(imacro_);
} else
lyxerr << "Math Warning: Already in macro mode" << endl;
theSelection.grab(*this);
theSelection.erase(*this);
selClear();
+ } else {
+ theSelection.clear();
}
}
void MathCursor::selHandle(bool sel)
{
- if (sel && !selection_)
- selStart();
- if (!sel && selection_)
- selClear();
+ if (sel == selection_)
+ return;
+
+ theSelection.clear();
+ Anchor_ = Cursor_;
+ selection_ = sel;
}
if (selection_)
return;
+ theSelection.clear();
Anchor_ = Cursor_;
selection_ = true;
}
void MathCursor::selClear()
{
+ seldump("selClear");
selection_ = false;
}
getSelection(i1, i2);
if (i1.idx_ == i2.idx_) {
MathArray & ar = i1.cell();
- for (int pos = i1.pos_; pos != i2.pos_; ar.next(pos))
- if (!ar.isInset(pos) && isalnum(ar.getChar(pos))) {
+ for (int pos = i1.pos_; pos != i2.pos_; ++pos)
+ if (isalnum(ar.getChar(pos))) {
MathTextCodes c = ar.getCode(pos) == t ? LM_TC_VAR : t;
ar.setCode(pos, c);
}
}
-void MathCursor::handleAccent(string const & name, int code)
+void MathCursor::handleAccent(string const & name)
{
- MathDecorationInset * p = new MathDecorationInset(name, code);
+ latexkeys const * l = in_word_set(name);
+ if (!l)
+ return;
+
+ MathDecorationInset * p = new MathDecorationInset(l);
if (selection_) {
selCut();
p->cell(0) = theSelection.glue();
}
-MathInset * MathCursor::enclosing(MathInsetTypes t, int & idx) const
+MathArrayInset * MathCursor::enclosingArray(int & idx) const
{
for (int i = Cursor_.size() - 1; i >= 0; --i) {
- //lyxerr << "checking level " << i << "\n";
- if (Cursor_[i].par_->getType() == t) {
+ if (Cursor_[i].par_->isArray()) {
idx = Cursor_[i].idx_;
- return Cursor_[i].par_;
+ return static_cast<MathArrayInset *>(Cursor_[i].par_);
}
}
return 0;
#endif
MathCursor * it = const_cast<MathCursor *>(this);
- if (cursor().idx_ < 0 || cursor().idx_ > cursor().par_->nargs())
+ if (cursor().idx_ < 0 || cursor().idx_ > cursor().par_->nargs() - 1)
lyxerr << "this should not really happen - 1\n";
it->cursor().idx_ = max(cursor().idx_, 0);
- it->cursor().idx_ = min(cursor().idx_, cursor().par_->nargs());
+ it->cursor().idx_ = min(cursor().idx_, cursor().par_->nargs() - 1);
if (cursor().pos_ < 0 || cursor().pos_ > array().size())
lyxerr << "this should not really happen - 2\n";
MathInset * MathCursor::prevInset() const
{
normalize();
- int c = cursor().pos_;
- if (!array().prev(c))
+ int pos = cursor().pos_;
+ if (!pos)
return 0;
- return array().nextInset(c);
+ return array().nextInset(pos - 1);
}
MathScriptInset * MathCursor::prevScriptInset() const
{
normalize();
- MathInset * p = array().prevInset(cursor().pos_);
+ MathInset * p = prevInset();
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
}
MathSpaceInset * MathCursor::prevSpaceInset() const
{
normalize();
- MathInset * p = array().prevInset(cursor().pos_);
+ MathInset * p = prevInset();
return (p && p->isSpaceInset()) ? static_cast<MathSpaceInset *>(p) : 0;
}
}
-bool MathCursor::nextIsInset() const
-{
- return cursor().pos_ < array().size() && MathIsInset(nextCode());
-}
-
-
-bool MathCursor::prevIsInset() const
-{
- return cursor().pos_ > 0 && MathIsInset(prevCode());
-}
-
-
int MathCursor::xpos() const
{
normalize();
void MathCursor::breakLine()
{
- MathMatrixInset * p = static_cast<MathMatrixInset *>(formula()->par());
+ MathMatrixInset * p = outerPar();
if (p->getType() == LM_OT_SIMPLE || p->getType() == LM_OT_EQUATION) {
p->mutate(LM_OT_EQNARRAY);
p->addRow(0);
char MathCursor::valign() const
{
int idx;
- MathGridInset * p =
- static_cast<MathGridInset *>(enclosing(LM_OT_MATRIX, idx));
+ MathArrayInset * p = enclosingArray(idx);
return p ? p->valign() : 0;
}
char MathCursor::halign() const
{
int idx;
- MathGridInset * p =
- static_cast<MathGridInset *>(enclosing(LM_OT_MATRIX, idx));
+ MathArrayInset * p = enclosingArray(idx);
return p ? p->halign(idx % p->ncols()) : 0;
}
MathCursorPos normal = Anchor_[Cursor_.size() - 1];
if (Cursor_.size() < Anchor_.size() && !(normal < cursor())) {
// anchor is behind cursor -> move anchor behind the inset
- normal.cell().next(normal.pos_);
+ ++normal.pos_;
}
//lyxerr << "normalizing: from " << Anchor_[Anchor_.size() - 1] << " to "
// << normal << "\n";
{
return par_->idxRight(idx_, pos_);
}
+
+
+MathMatrixInset * MathCursor::outerPar() const
+{
+ return
+ static_cast<MathMatrixInset *>(const_cast<MathInset *>(formula_->par()));
+}