]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
Remove hardcoded values
[lyx.git] / src / Cursor.cpp
index 6733aaedfad58d3beb14d92a43a121a7498d8a82..e2d1f893ae120d986073905fe3ef217c38b02192 100644 (file)
@@ -15,6 +15,7 @@
 #include <config.h>
 
 #include "Buffer.h"
+#include "BufferParams.h"
 #include "BufferView.h"
 #include "CoordCache.h"
 #include "Cursor.h"
@@ -31,6 +32,7 @@
 #include "Paragraph.h"
 #include "ParIterator.h"
 #include "Row.h"
+#include "texstream.h"
 #include "Text.h"
 #include "TextMetrics.h"
 #include "TocBackend.h"
 
 #include "mathed/InsetMath.h"
 #include "mathed/InsetMathBrace.h"
+#include "mathed/InsetMathEnsureMath.h"
 #include "mathed/InsetMathScript.h"
 #include "mathed/MacroTable.h"
 #include "mathed/MathData.h"
+#include "mathed/MathFactory.h"
 #include "mathed/MathMacro.h"
 
-#include "support/bind.h"
-
 #include <sstream>
 #include <limits>
 #include <map>
@@ -73,25 +75,25 @@ DocIterator bruteFind(Cursor const & c, int x, int y)
        DocIterator result;
 
        DocIterator it = c;
-       it.top().pos() = 0;
+       it.pos() = 0;
        DocIterator et = c;
-       et.top().pos() = et.top().asInsetMath()->cell(et.top().idx()).size();
+       et.pos() = et.lastpos();
        for (size_t i = 0;; ++i) {
                int xo;
                int yo;
                Inset const * inset = &it.inset();
-               CoordCache const & cache = c.bv().coordCache();
+               CoordCache::Insets const & insetCache = c.bv().coordCache().getInsets();
 
                // FIXME: in the case where the inset is not in the cache, this
                // means that no part of it is visible on screen. In this case
                // we don't do elaborate search and we just return the forwarded
                // DocIterator at its beginning.
-               if (!cache.getInsets().has(inset)) {
+               if (!insetCache.has(inset)) {
                        it.top().pos() = 0;
                        return it;
                }
 
-               Point const o = cache.getInsets().xy(inset);
+               Point const o = insetCache.xy(inset);
                inset->cursorPos(c.bv(), it.top(), c.boundary(), xo, yo);
                // Convert to absolute
                xo += o.x_;
@@ -193,13 +195,37 @@ void Cursor::reset()
 }
 
 
-// this (intentionally) does neither touch anchor nor selection status
 void Cursor::setCursor(DocIterator const & cur)
 {
        DocIterator::operator=(cur);
 }
 
 
+void Cursor::setCursorSelectionTo(DocIterator dit)
+{
+       size_t i = 0;
+       // normalise dit
+       while (i < dit.depth() && i < anchor_.depth() && dit[i] == anchor_[i])
+               ++i;
+       if (i != dit.depth()) {
+               // otherwise the cursor is already normal
+               if (i == anchor_.depth())
+                       // dit is a proper extension of the anchor_
+                       dit.cutOff(i - 1);
+               else if (i + 1 < dit.depth()) {
+                       // one has dit[i] != anchor_[i] but either dit[i-1] == anchor_[i-1]
+                       // or i == 0. Remove excess.
+                       dit.cutOff(i);
+                       if (dit[i] > anchor_[i])
+                               // place dit after the inset it was in
+                               ++dit.pos();
+               }
+       }
+       setCursor(dit);
+       setSelection();
+}
+
+
 void Cursor::setCursorToAnchor()
 {
        if (selection()) {
@@ -997,18 +1023,18 @@ DocIterator Cursor::selectionEnd() const
 
 void Cursor::setSelection()
 {
-       setSelection(true);
+       selection(true);
        if (idx() == normalAnchor().idx() &&
            pit() == normalAnchor().pit() &&
            pos() == normalAnchor().pos())
-               setSelection(false);
+               selection(false);
 }
 
 
 void Cursor::setSelection(DocIterator const & where, int n)
 {
        setCursor(where);
-       setSelection(true);
+       selection(true);
        anchor_ = where;
        pos() += n;
 }
@@ -1016,7 +1042,7 @@ void Cursor::setSelection(DocIterator const & where, int n)
 
 void Cursor::clearSelection()
 {
-       setSelection(false);
+       selection(false);
        setWordSelection(false);
        setMark(false);
        resetAnchor();
@@ -1079,7 +1105,7 @@ bool Cursor::selHandle(bool sel)
                cap::saveSelection(*this);
 
        resetAnchor();
-       setSelection(sel);
+       selection(sel);
        return true;
 }
 } // namespace lyx
@@ -1184,9 +1210,8 @@ void Cursor::plainInsert(MathAtom const & t)
 
 void Cursor::insert(docstring const & str)
 {
-       for_each(str.begin(), str.end(),
-                bind(static_cast<void(Cursor::*)(char_type)>
-                            (&Cursor::insert), this, _1));
+       for (char_type c : str)
+               insert(c);
 }
 
 
@@ -1319,7 +1344,7 @@ bool Cursor::backspace()
                // let's require two backspaces for 'big stuff' and
                // highlight on the first
                resetAnchor();
-               setSelection(true);
+               selection(true);
                --pos();
        } else {
                --pos();
@@ -1366,7 +1391,7 @@ bool Cursor::erase()
        // 'clever' UI hack: only erase large items if previously slected
        if (pos() != lastpos() && nextAtom()->nargs() > 0) {
                resetAnchor();
-               setSelection(true);
+               selection(true);
                ++pos();
        } else {
                plainErase();
@@ -1426,8 +1451,9 @@ bool Cursor::macroModeClose()
        InsetMathNest * const in = inset().asInsetMath()->asNestInset();
        if (in && in->interpretString(*this, s))
                return true;
-       MathAtom atom = buffer()->getMacro(name, *this, false) ?
-               MathAtom(new MathMacro(buffer(), name)) : createInsetMath(name, buffer());
+       bool const user_macro = buffer()->getMacro(name, *this, false);
+       MathAtom atom = user_macro ? MathAtom(new MathMacro(buffer(), name))
+                                  : createInsetMath(name, buffer());
 
        // try to put argument into macro, if we just inserted a macro
        bool macroArg = false;
@@ -1449,7 +1475,29 @@ bool Cursor::macroModeClose()
        else if (atom.nucleus()->nargs() > 0)
                atom.nucleus()->cell(0).append(selection);
 
-       plainInsert(atom);
+       MathWordList const & words = mathedWordList();
+       MathWordList::const_iterator it = words.find(name);
+       bool keep_mathmode = it != words.end() && (it->second.inset == "font"
+                                               || it->second.inset == "oldfont"
+                                               || it->second.inset == "mbox");
+       bool ert_macro = !user_macro && it == words.end() && atomAsMacro;
+
+       if (in && in->currentMode() == Inset::TEXT_MODE
+           && atom.nucleus()->currentMode() == Inset::MATH_MODE
+           && name != from_ascii("ensuremath") && !ert_macro) {
+               MathAtom at(new InsetMathEnsureMath(buffer()));
+               at.nucleus()->cell(0).push_back(atom);
+               niceInsert(at);
+               posForward();
+       } else if (in && in->currentMode() == Inset::MATH_MODE
+                  && atom.nucleus()->currentMode() == Inset::TEXT_MODE
+                  && !keep_mathmode) {
+               MathAtom at = createInsetMath("text", buffer());
+               at.nucleus()->cell(0).push_back(atom);
+               niceInsert(at);
+               posForward();
+       } else
+               plainInsert(atom);
 
        // finally put the macro argument behind, if needed
        if (macroArg) {
@@ -1569,8 +1617,7 @@ void Cursor::normalize()
                        << pos() << ' ' << lastpos() <<  " in idx: " << idx()
                       << " in atom: '";
                odocstringstream os;
-               TexRow texrow(false);
-               otexrowstream ots(os,texrow);
+               otexrowstream ots(os);
                WriteStream wi(ots, false, true, WriteStream::wsDefault);
                inset().asInsetMath()->write(wi);
                lyxerr << to_utf8(os.str()) << endl;
@@ -2020,10 +2067,14 @@ Encoding const * Cursor::getEncoding() const
 {
        if (empty())
                return 0;
+       BufferParams const & bp = bv().buffer().params();
+       if (bp.useNonTeXFonts)
+               return encodings.fromLyXName("utf8-plain");
+
        CursorSlice const & sl = innerTextSlice();
        Text const & text = *sl.text();
-       Font font = text.getPar(sl.pit()).getFont(
-               bv().buffer().params(), sl.pos(), text.outerFont(sl.pit()));
+       Font font = text.getPar(sl.pit()).getFont(bp, sl.pos(),
+                                                 text.outerFont(sl.pit()));
        return font.language()->encoding();
 }
 
@@ -2075,6 +2126,7 @@ Font Cursor::getFont() const
        // The logic here should more or less match to the
        // Cursor::setCurrentFont logic, i.e. the cursor height should
        // give a hint what will happen if a character is entered.
+       // FIXME: this is not the case, what about removing this method ? (see #10478).
 
        // HACK. far from being perfect...