#include "Cursor.h"
#include "CutAndPaste.h"
#include "DispatchResult.h"
-#include "Encoding.h"
#include "Font.h"
#include "FuncCode.h"
#include "FuncRequest.h"
#include "mathed/MacroTable.h"
#include "mathed/MathData.h"
#include "mathed/MathFactory.h"
-#include "mathed/MathMacro.h"
+#include "mathed/InsetMathMacro.h"
#include <sstream>
#include <limits>
}
-} // namespace anon
+} // namespace
CursorData::CursorData()
return cit != row.end() && !cit->isVirtual();
}
-}
+} // namespace
void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const
{
}
-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);
if (inset)
prevInset()->infoize2(os);
}
+ if (devel_mode) {
+ InsetMath * math = inset().asInsetMath();
+ if (math)
+ os << _(", Inset: ") << math->id();
+ os << _(", Cell: ") << idx();
+ os << _(", Position: ") << pos();
+ }
+
}
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
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
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
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());
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();
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.
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);
}
return os.str();
}
-}
+} // namespace
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();
}
}
-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);
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;
}
+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