]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_cursor.C
small up/down tweaking
[lyx.git] / src / mathed / math_cursor.C
index 757462e861d8b7b2fed1fa34cf282c6a56e30d7b..44b0136ce6075e99e6c4f33a7c6a8e5c961fbd8c 100644 (file)
@@ -24,9 +24,7 @@
 
 #include "support/lstrings.h"
 #include "support/LAssert.h"
-#include "BufferView.h"
 #include "debug.h"
-#include "LColor.h"
 #include "frontends/Painter.h"
 #include "math_cursor.h"
 #include "formulabase.h"
 #include "math_charinset.h"
 #include "math_extern.h"
 #include "math_factory.h"
+#include "math_fontinset.h"
 #include "math_gridinset.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"
 #include "math_scriptinset.h"
 #include "math_spaceinset.h"
 #include "math_support.h"
@@ -64,11 +61,11 @@ using std::isalpha;
 
 
 // matheds own cut buffer
-MathGridInset theCutBuffer = MathGridInset(1, 1);
+string theCutBuffer;
 
 
 MathCursor::MathCursor(InsetFormulaBase * formula, bool front)
-       :       formula_(formula), autocorrect_(false), selection_(false)
+       :       formula_(formula), autocorrect_(false), selection_(false), targetx_(-1)
 {
        front ? first() : last();
        Anchor_ = Cursor_;
@@ -77,9 +74,9 @@ MathCursor::MathCursor(InsetFormulaBase * formula, bool front)
 
 MathCursor::~MathCursor()
 {
-  // ensure that 'notifyCursorLeave' is called
-  while (popLeft())
-    ;
+       // ensure that 'notifyCursorLeave' is called
+       while (popLeft())
+               ;
 }
 
 
@@ -111,10 +108,10 @@ bool MathCursor::popLeft()
        //cerr << "Leaving atom to the left\n";
        if (depth() <= 1) {
                if (depth() == 1)
-                       par()->notifyCursorLeaves();
+                       par()->notifyCursorLeaves(idx());
                return false;
        }
-       par()->notifyCursorLeaves();
+       par()->notifyCursorLeaves(idx());
        Cursor_.pop_back();
        return true;
 }
@@ -125,10 +122,10 @@ bool MathCursor::popRight()
        //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n";
        if (depth() <= 1) {
                if (depth() == 1)
-                       par()->notifyCursorLeaves();
+                       par()->notifyCursorLeaves(idx());
                return false;
        }
-       par()->notifyCursorLeaves();
+       par()->notifyCursorLeaves(idx());
        Cursor_.pop_back();
        posRight();
        return true;
@@ -139,14 +136,14 @@ bool MathCursor::popRight()
 #if FILEDEBUG
        void MathCursor::dump(char const * what) const
        {
-               lyxerr << "MC: " << what << "\n";
-               lyxerr << " Cursor: " << depth() << "\n";
+               lyxerr << "MC: " << what << endl;
+               lyxerr << " Cursor: " << depth() << endl;
                for (unsigned i = 0; i < depth(); ++i)
-                       lyxerr << "    i: " << i << " " << Cursor_[i] << "\n";
-               lyxerr << " Anchor: " << Anchor_.size() << "\n";
+                       lyxerr << "    i: " << i << ' ' << Cursor_[i] << endl;
+               lyxerr << " Anchor: " << Anchor_.size() << endl;
                for (unsigned i = 0; i < Anchor_.size(); ++i)
-                       lyxerr << "    i: " << i << " " << Anchor_[i] << "\n";
-               lyxerr  << " sel: " << selection_ << "\n";
+                       lyxerr << "    i: " << i << ' ' << Anchor_[i] << endl;
+               lyxerr  << " sel: " << selection_ << endl;
        }
 #else
        void MathCursor::dump(char const *) const {}
@@ -376,10 +373,20 @@ void MathCursor::insert(MathAtom const & t)
 }
 
 
+void MathCursor::niceInsert(string const & t)
+{
+       MathArray ar = asArray(t);
+       if (ar.size() == 1)
+               niceInsert(ar[0]);
+       else
+               insert(ar);
+}
+
+
 void MathCursor::niceInsert(MathAtom const & t)
 {
        macroModeClose();
-       MathGridInset safe = grabAndEraseSelection();
+       string safe = grabAndEraseSelection();
        plainInsert(t);
        // enter the new inset and move the contents of the selection if possible
        if (t->isActive()) {
@@ -400,28 +407,26 @@ void MathCursor::insert(MathArray const & ar)
 }
 
 
-void MathCursor::paste(MathGridInset const & data)
+void MathCursor::paste(string const & data)
 {
-       ostringstream os;
-  WriteStream wi(os, false, false);
-  data.write(wi);
-       dispatch(FuncRequest(LFUN_PASTE, os.str()));
+       dispatch(FuncRequest(LFUN_PASTE, data));
 }
 
 
 void MathCursor::backspace()
 {
        autocorrect_ = false;
-       if (pos() == 0) {
-               pullArg();
-               return;
-       }
 
        if (selection_) {
                selDel();
                return;
        }
 
+       if (pos() == 0) {
+               pullArg();
+               return;
+       }
+
        if (inMacroMode()) {
                MathUnknownInset * p = activeMacro();
                if (p->name().size() > 1) {
@@ -534,7 +539,7 @@ void MathCursor::selCopy()
                theCutBuffer = grabSelection();
                selection_ = false;
        } else {
-               theCutBuffer = MathGridInset(1, 1);
+               theCutBuffer.erase();
        }
 }
 
@@ -595,14 +600,6 @@ void MathCursor::selClearOrDel()
 }
 
 
-void MathCursor::selGet(MathArray & ar)
-{
-       dump("selGet");
-       if (selection_)
-               ar = grabSelection().glue();
-}
-
-
 void MathCursor::drawSelection(MathPainterInfo & pi) const
 {
        if (!selection_)
@@ -617,7 +614,7 @@ void MathCursor::drawSelection(MathPainterInfo & pi) const
 void MathCursor::handleNest(MathAtom const & a)
 {
        MathAtom at = a;
-       at.nucleus()->cell(0) = grabAndEraseSelection().glue();
+       at.nucleus()->cell(0) = asArray(grabAndEraseSelection());
        insert(at);
        pushRight(prevAtom());
 }
@@ -669,6 +666,18 @@ MathCursor::pos_type MathCursor::pos() const
 }
 
 
+void MathCursor::adjust(pos_type from, difference_type diff)
+{
+       if (cursor().pos_ > from)
+               cursor().pos_ += diff;
+       if (Anchor_.back().pos_ > from)
+               Anchor_.back().pos_ += diff;
+       // just to be on the safe side
+       // theoretically unecessary
+       normalize();
+}
+
+
 MathCursor::pos_type & MathCursor::pos()
 {
        return cursor().pos_;
@@ -769,36 +778,22 @@ void MathCursor::normalize()
 {
        if (idx() >= par()->nargs()) {
                lyxerr << "this should not really happen - 1: "
-                      << idx() << " " << par()->nargs() << " in: " << par() << "\n";
+                      << idx() << ' ' << par()->nargs()
+                      << " in: " << par() << endl;
                dump("error 2");
        }
        idx() = min(idx(), par()->nargs() - 1);
 
        if (pos() > size()) {
                lyxerr << "this should not really happen - 2: "
-                       << pos() << " " << size() <<  " in idx: " << idx()
-                       << " in atom: '";
+                       << pos() << ' ' << size() <<  " in idx: " << idx()
+                      << " in atom: '";
                WriteStream wi(lyxerr, false, true);
                par()->write(wi);
-               lyxerr << "\n";
+               lyxerr << endl;
                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()[i].nucleus()->asScriptInset();
-                       if (p) {
-                               p->removeEmptyScripts();
-                               if (!p->hasUp() && !p->hasDown() && p->nuc().size() == 1)
-                                       array()[i] = p->nuc()[0];
-                       }
-               }
-       }
-
-       // fix again position
-       pos() = min(pos(), size());
 }
 
 
@@ -1096,7 +1091,7 @@ bool MathCursor::script(bool up)
        }
 
        macroModeClose();
-       MathGridInset safe = grabAndEraseSelection();
+       string safe = grabAndEraseSelection();
        if (inNucleus()) {
                // we are in a nucleus of a script inset, move to _our_ script
                par()->asScriptInset()->ensure(up);
@@ -1206,7 +1201,7 @@ bool MathCursor::interpret(char c)
        }
 
        if (c == '\n') {
-               if (currentMode() == MathInset::TEXT_MODE) 
+               if (currentMode() == MathInset::TEXT_MODE)
                        insert(c);
                return true;
        }
@@ -1251,25 +1246,6 @@ bool MathCursor::interpret(char c)
                return true;
        }
 
-/*
-       if (isalpha(c) && lastcode_ == LM_TC_GREEK) {
-               insert(c, LM_TC_VAR);
-               return true;
-       }
-
-       if (isalpha(c) && lastcode_ == LM_TC_GREEK1) {
-               insert(c, LM_TC_VAR);
-               lastcode_ = LM_TC_VAR;
-               return true;
-       }
-
-       if (c == '\\') {
-               insert(c, LM_TC_TEX);
-               //bv->owner()->message(_("TeX mode"));
-               return true;
-       }
-*/
-
        // try auto-correction
        //if (autocorrect_ && hasPrevAtom() && math_autocorrect(prevAtom(), c))
        //      return true;
@@ -1312,10 +1288,9 @@ string MathCursor::info() const
                os << "  ";
        }
        if (hasPrevAtom())
-               if (prevAtom()->asSymbolInset() || prevAtom()->asScriptInset())
-                       prevAtom()->infoize(os);
+               prevAtom()->infoize2(os);
        os << "                    ";
-       return os.str().c_str(); // .c_str() needed for lyxstring
+       return STRCONV(os.str());
 }
 
 
@@ -1347,29 +1322,34 @@ void region(MathCursorPos const & i1, MathCursorPos const & i2,
 }
 
 
-MathGridInset MathCursor::grabSelection() const
+string MathCursor::grabSelection() const
 {
        if (!selection_)
-               return MathGridInset();
+               return string();
+
        MathCursorPos i1;
        MathCursorPos i2;
        getSelection(i1, i2);
-       // shouldn't we assert on i1.par_ == i2.par_?
+
        if (i1.idx_ == i2.idx_) {
-               MathGridInset data(1, 1);
                MathArray::const_iterator it = i1.cell().begin();
-               data.cell(0) = MathArray(it + i1.pos_, it + i2.pos_);
-               return data;
+               return asString(MathArray(it + i1.pos_, it + i2.pos_));
        }
+
        row_type r1, r2;
        col_type c1, c2;
        region(i1, i2, r1, r2, c1, c2);
-       MathGridInset data(c2 - c1 + 1, r2 - r1 + 1);
-       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);
+
+       string data;
+       for (row_type row = r1; row <= r2; ++row) {
+               if (row > r1)
+                       data += "\\\\";
+               for (col_type col = c1; col <= c2; ++col) {
+                       if (col > c1)
+                               data += '&';
+                       data += asString(i1.par_->cell(i1.par_->index(row, col)));
                }
+       }
        return data;
 }
 
@@ -1394,11 +1374,11 @@ void MathCursor::eraseSelection()
 }
 
 
-MathGridInset MathCursor::grabAndEraseSelection()
+string MathCursor::grabAndEraseSelection()
 {
        if (!selection_)
-               return MathGridInset();
-       MathGridInset res = grabSelection();
+               return string();
+       string res = grabSelection();
        eraseSelection();
        selection_ = false;
        return res;
@@ -1451,12 +1431,47 @@ MathInset::mode_type MathCursor::currentMode() const
 }
 
 
-void releaseMathCursor(BufferView * bv)
+void MathCursor::handleFont(string const & font)
 {
-       if (!mathcursor)
-               return;
-       mathcursor->formula()->hideInsetCursor(bv);
-       delete mathcursor;
-       mathcursor = 0;
+       string safe;
+       if (selection()) {
+               macroModeClose();
+               safe = grabAndEraseSelection();
+       }
+
+       if (array().size()) {
+               // something left in the cell
+               if (pos() == 0) {
+                       // cursor in first position
+                       popLeft();
+               } else if (pos() == array().size()) {
+                       // cursor in last position
+                       popRight();
+               } else {
+                       // cursor in between. split cell
+                       MathArray::iterator bt = array().begin();
+                       MathAtom at = createMathInset(font);
+                       at.nucleus()->cell(0) = MathArray(bt, bt + pos());
+                       cursor().cell().erase(bt, bt + pos());
+                       popLeft();
+                       plainInsert(at);
+               }
+       } else {
+               // nothing left in the cell
+               pullArg();
+               plainErase();
+       }
+       insert(safe);
 }
 
+
+void releaseMathCursor(BufferView * bv)
+{
+       if (mathcursor) {
+               InsetFormulaBase * f =  mathcursor->formula();
+               f->hideInsetCursor(bv);
+               delete mathcursor;
+               mathcursor = 0;
+               f->insetUnlock(bv);
+       }
+}