]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
Disable CheckTeX while buffer is processed
[lyx.git] / src / Cursor.cpp
index 05389d9845b755c32f215ff010f9f42dd9e2ea0c..2e8060509de0dbfd40af8033640bfc971463314e 100644 (file)
@@ -21,7 +21,6 @@
 #include "Cursor.h"
 #include "CutAndPaste.h"
 #include "DispatchResult.h"
-#include "Encoding.h"
 #include "Font.h"
 #include "FuncCode.h"
 #include "FuncRequest.h"
@@ -53,7 +52,7 @@
 #include "mathed/MacroTable.h"
 #include "mathed/MathData.h"
 #include "mathed/MathFactory.h"
-#include "mathed/MathMacro.h"
+#include "mathed/InsetMathMacro.h"
 
 #include <sstream>
 #include <limits>
@@ -115,7 +114,7 @@ DocIterator bruteFind(Cursor const & c, int x, int y)
 }
 
 
-} // namespace anon
+} // namespace
 
 
 CursorData::CursorData()
@@ -758,7 +757,7 @@ bool findNonVirtual(Row const & row, Row::const_iterator & cit, bool onleft)
        return cit != row.end() && !cit->isVirtual();
 }
 
-}
+} // namespace
 
 void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const
 {
@@ -1057,7 +1056,7 @@ void Cursor::updateTextTargetOffset()
 }
 
 
-void Cursor::info(odocstream & os) const
+void Cursor::info(odocstream & os, bool devel_mode) const
 {
        for (int i = 1, n = depth(); i < n; ++i) {
                operator[](i).inset().infoize(os);
@@ -1069,6 +1068,14 @@ void Cursor::info(odocstream & os) const
                if (inset)
                        prevInset()->infoize2(os);
        }
+       if (devel_mode) {
+               InsetMath * math = inset().asInsetMath();
+               if (math)
+                       os << _(", Inset: ") << math->id();
+               os << _(", Cell: ") << idx();
+               os << _(", Position: ") << pos();
+       }
+
 }
 
 
@@ -1431,12 +1438,12 @@ bool Cursor::macroModeClose()
        if (in && in->interpretString(*this, s))
                return true;
        bool const user_macro = buffer()->getMacro(name, *this, false);
-       MathAtom atom = user_macro ? MathAtom(new MathMacro(buffer(), name))
+       MathAtom atom = user_macro ? MathAtom(new InsetMathMacro(buffer(), name))
                                   : createInsetMath(name, buffer());
 
        // try to put argument into macro, if we just inserted a macro
        bool macroArg = false;
-       MathMacro * atomAsMacro = atom.nucleus()->asMacro();
+       InsetMathMacro * atomAsMacro = atom.nucleus()->asMacro();
        if (atomAsMacro) {
                // macros here are still unfolded (in init mode in fact). So
                // we have to resolve the macro here manually and check its arity
@@ -1444,10 +1451,10 @@ bool Cursor::macroModeClose()
                MacroData const * data = buffer()->getMacro(atomAsMacro->name());
                if (!selection.empty() && data && data->numargs() - data->optionals() > 0) {
                        macroArg = true;
-                       atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT, 1);
+                       atomAsMacro->setDisplayMode(InsetMathMacro::DISPLAY_INTERACTIVE_INIT, 1);
                } else
                        // non-greedy case. Do not touch the arguments behind
-                       atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT, 0);
+                       atomAsMacro->setDisplayMode(InsetMathMacro::DISPLAY_INTERACTIVE_INIT, 0);
        }
 
        // insert remembered selection into first argument of a non-macro
@@ -1456,9 +1463,10 @@ bool Cursor::macroModeClose()
 
        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 keep_mathmode = user_macro
+               || (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
@@ -1738,11 +1746,23 @@ bool Cursor::mathForward(bool word)
        LASSERT(inMathed(), return false);
        if (pos() < lastpos()) {
                if (word) {
-                       // word: skip a group of insets with same math class
+                       // word: skip a group of insets of the form X*(B*|R*|P*) (greedy
+                       // match) where X is any math class, B is mathbin, R is mathrel, and
+                       // P is mathpunct. Make sure that the following remains true:
+                       //   mathForward(true); mathBackward(true); mathForward(true)
+                       // is the same as mathForward(true) and
+                       //   mathBackward(true); mathForward(true); mathBackward(true)
+                       // is the same as mathBackward(true).
                        MathClass mc = nextMath().mathClass();
                        do
                                posForward();
                        while (pos() < lastpos() && mc == nextMath().mathClass());
+                       if (pos() < lastpos() &&
+                           ((mc = nextMath().mathClass()) == MC_BIN ||
+                            mc == MC_REL || mc == MC_PUNCT))
+                               do
+                                       posForward();
+                               while (pos() < lastpos() && mc == nextMath().mathClass());
                } else if (openable(nextAtom())) {
                        // single step: try to enter the next inset
                        pushBackward(nextMath());
@@ -1767,11 +1787,17 @@ bool Cursor::mathBackward(bool word)
        LASSERT(inMathed(), return false);
        if (pos() > 0) {
                if (word) {
-                       // word: skip a group of insets with same math class
+                       // word: skip a group of insets. See the comment in mathForward.
                        MathClass mc = prevMath().mathClass();
                        do
                                posBackward();
                        while (pos() > 0 && mc == prevMath().mathClass());
+                       if (pos() > 0 && (mc == MC_BIN || mc == MC_REL || mc == MC_PUNCT)) {
+                               mc = prevMath().mathClass();
+                               do
+                                       posBackward();
+                               while (pos() > 0 && mc == prevMath().mathClass());
+                       }
                } else if (openable(prevAtom())) {
                        // single step: try to enter the preceding inset
                        posBackward();
@@ -1906,10 +1932,13 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                int yo = bv().getPos(*this).y_;
                Cursor old = *this;
                // To next/previous row
+               // FIXME: the y position is often guessed wrongly across styles and
+               // insets, which leads to weird behaviour.
                if (up)
                        tm.editXY(*this, xo, yo - textRow().ascent() - 1);
                else
                        tm.editXY(*this, xo, yo + textRow().descent() + 1);
+               x_target_ = old.x_target_;
                clearSelection();
 
                // This happens when you move out of an inset.
@@ -1958,6 +1987,8 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                bool bound = false;
                top().pos() = tm.getPosNearX(real_next_row, xo, bound);
                boundary(bound);
+               // When selection==false, this is done by TextMetrics::editXY
+               setCurrentFont();
 
                updateNeeded |= bv().checkDepm(*this, old);
        }
@@ -2033,7 +2064,7 @@ docstring parbreak(Cursor const * cur)
        return os.str();
 }
 
-}
+} // namespace
 
 
 docstring Cursor::selectionAsString(bool with_label) const
@@ -2085,23 +2116,16 @@ docstring Cursor::selectionAsString(bool with_label) const
 }
 
 
-docstring Cursor::currentState() const
+docstring Cursor::currentState(bool devel_mode) const
 {
        if (inMathed()) {
                odocstringstream os;
-               info(os);
-#ifdef DEVEL_VERSION
-               InsetMath * math = inset().asInsetMath();
-               if (math)
-                       os << _(", Inset: ") << math->id();
-               os << _(", Cell: ") << idx();
-               os << _(", Position: ") << pos();
-#endif
+               info(os, devel_mode);
                return os.str();
        }
 
        if (inTexted())
-               return text()->currentState(*this);
+               return text()->currentState(*this, devel_mode);
 
        return docstring();
 }
@@ -2113,22 +2137,6 @@ docstring Cursor::getPossibleLabel() const
 }
 
 
-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(bp, sl.pos(),
-                                                 text.outerFont(sl.pit()));
-       return font.language()->encoding();
-}
-
-
 void Cursor::undispatched() const
 {
        disp_.dispatched(false);
@@ -2425,8 +2433,8 @@ bool Cursor::confirmDeletion(bool const before) const
                        return inset->confirmDeletion();
        } else {
                DocIterator dit = selectionBegin();
-               DocIterator const sel_end = selectionEnd();
-               for (; dit < sel_end; dit.posForward())
+               CursorSlice const end = selectionEnd().top();
+               for (; dit.top() < end; dit.top().forwardPos())
                        if (Inset const * inset = dit.nextInset())
                                if (inset->confirmDeletion())
                                        return true;
@@ -2435,4 +2443,22 @@ bool Cursor::confirmDeletion(bool const before) const
 }
 
 
+void Cursor::moveToClosestEdge(int const x, bool const edit)
+{
+       if (Inset const * inset = nextInset()) {
+               // stay in front of insets for which we want to open the dialog
+               // (e.g. InsetMathSpace).
+               if (edit && (inset->hasSettings() || !inset->contextMenuName().empty()))
+                       return;
+               CoordCache::Insets const & insetCache = bv().coordCache().getInsets();
+               if (!insetCache.has(inset))
+                       return;
+               int const wid = insetCache.dim(inset).wid;
+               Point p = insetCache.xy(inset);
+               if (x > p.x_ + (wid + 1) / 2)
+                       posForward();
+       }
+}
+
+
 } // namespace lyx