#include "support/gettext.h"
#include "support/lassert.h"
+#include "insets/InsetLayout.h"
#include "insets/InsetTabular.h"
#include "mathed/InsetMath.h"
if (di.depth() > depth()) {
di.resize(depth());
++di.pos();
+ di.boundary(true);
}
return di;
}
Cursor::Cursor(BufferView & bv)
: CursorData(&bv.buffer()), bv_(&bv),
x_target_(-1), textTargetOffset_(0),
+ x_clickpos_(-1), y_clickpos_(-1),
beforeDispatchPosX_(0), beforeDispatchPosY_(0)
{}
beginUndoGroup();
+ Inset * nextins = nextInset();
// Is this a function that acts on inset at point?
- if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint)
- && nextInset()) {
+ if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint) && nextins) {
disp_.dispatched(true);
disp_.screenUpdate(Update::FitCursor | Update::Force);
FuncRequest tmpcmd = cmd;
- LYXERR(Debug::DEBUG, "Cursor::dispatch: (AtPoint) cmd: "
+ LYXERR(Debug::ACTION, "Cursor::dispatch: (AtPoint) cmd: "
<< cmd0 << endl << *this);
- nextInset()->dispatch(*this, tmpcmd);
+ nextins->dispatch(*this, tmpcmd);
if (disp_.dispatched()) {
endUndoGroup();
return;
// store some values to be used inside of the handlers
beforeDispatchCursor_ = *this;
for (; depth(); pop(), boundary(false)) {
- LYXERR(Debug::DEBUG, "Cursor::dispatch: cmd: "
+ LYXERR(Debug::ACTION, "Cursor::dispatch: cmd: "
<< cmd0 << endl << *this);
// In any of these cases, the cursor is invalid, and we should
// it completely to get a 'bomb early' behaviour in case this
// object will be used again.
if (!disp_.dispatched()) {
- LYXERR(Debug::DEBUG, "RESTORING OLD CURSOR!");
+ LYXERR(Debug::ACTION, "RESTORING OLD CURSOR!");
// We might have invalidated the cursor when removing an empty
// paragraph while the cursor could not be moved out the inset
// while we initially thought we could. This might happen when
void Cursor::push(Inset & inset)
{
push_back(CursorSlice(inset));
- inset.setBuffer(*buffer());
+ // See bug #13050
+ // inset.setBuffer(*buffer());
}
}
+void Cursor::setClickPos(int x, int y)
+{
+ x_clickpos_ = x;
+ y_clickpos_ = y;
+}
+
+
bool Cursor::selHandle(bool selecting)
{
//lyxerr << "Cursor::selHandle" << endl;
LASSERT(!empty(), return);
if (inMathed()) {
cap::selClearOrDel(*this);
- insert(new InsetMathChar(c));
+ insert(new InsetMathChar(buffer(), c));
} else {
text()->insertChar(*this, c);
}
docstring const name = t->asMacro()->name();
MacroData const * data = buffer()->getMacro(name);
if (data && data->numargs() - data->optionals() > 0) {
- plainInsert(MathAtom(new InsetMathBrace(ar)));
+ plainInsert(MathAtom(new InsetMathBrace(buffer(), ar)));
posBackward();
}
}
// [|], can not delete from inside
return false;
} else {
- if (inMathed())
- pullArg();
- else
+ if (inMathed()) {
+ switch (inset().asInsetMath()->getType()) {
+ case hullEqnArray:
+ case hullAlign:
+ case hullFlAlign: {
+ FuncRequest cmd(LFUN_CHAR_BACKWARD);
+ this->dispatch(cmd);
+ break;
+ }
+ default:
+ pullArg();
+ break;
+ }
+ } else
popBackward();
return true;
}
{
idx_type const idx = a.nucleus()->asNestInset()->firstIdx();
//lyxerr << "Cursor::handleNest: " << idx << endl;
+ InsetMath const * im = selectionBegin().inset().asInsetMath();
+ Parse::flags const f = im && im->currentMode() != InsetMath::MATH_MODE
+ ? Parse::TEXTMODE : Parse::NORMAL;
MathAtom t = a;
- asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx));
+ asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx), f);
insert(t);
editInsertedInset();
}
bool keep_mathmode = user_macro
|| (it != words.end() && (it->second.inset == "font"
|| it->second.inset == "oldfont"
+ || it->second.inset == "textsize"
|| it->second.inset == "mbox"));
bool ert_macro = !user_macro && it == words.end() && atomAsMacro;
// finally put the macro argument behind, if needed
if (macroArg) {
if (selection.size() > 1 || selection[0]->asScriptInset())
- plainInsert(MathAtom(new InsetMathBrace(selection)));
+ plainInsert(MathAtom(new InsetMathBrace(buffer(), selection)));
else
insert(selection);
}
plainErase();
cell().insert(pos(), ar);
resetAnchor();
- } else {
- //formula()->mutateToText();
}
}
<< " in atom: '";
odocstringstream os;
otexrowstream ots(os);
- WriteStream wi(ots, false, true, WriteStream::wsDefault);
+ TeXMathStream wi(ots, false, true, TeXMathStream::wsDefault);
inset().asInsetMath()->write(wi);
lyxerr << to_utf8(os.str()) << endl;
pos() = lastpos();
// try to find best position within this inset
if (!selection())
setCursor(bruteFind(*this, xo, yo));
+ // FIXME : this is actually only needed for InsetMathMacro (bug #12952).
+ screenUpdateFlags(Update::SinglePar);
return true;
}
posForward();
while (pos() < lastpos() && mc == nextMath().mathClass());
} else if (openable(nextAtom())) {
+ InsetMathScript const * n = nextMath().asScriptInset();
+ bool to_brace_deco = n && !n->nuc().empty()
+ && n->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+ && n->nuc().back()->mathClass() == MC_OP;
// single step: try to enter the next inset
pushBackward(nextMath());
inset().idxFirst(*this);
+ // Make sure the cursor moves directly to an
+ // \overbrace or \underbrace inset (bug 2264)
+ if (to_brace_deco) {
+ pushBackward(nextMath());
+ inset().idxFirst(*this);
+ }
} else
posForward();
return true;
}
if (inset().idxForward(*this))
return true;
+ InsetMath const * m = inset().asInsetMath();
+ bool from_brace_deco = m
+ && m->lyxCode() == MATH_DECORATION_CODE
+ && m->mathClass() == MC_OP;
// try to pop forwards --- but don't pop out of math! leave that to
// the FINISH lfuns
int s = depth() - 2;
- if (s >= 0 && operator[](s).inset().asInsetMath())
- return popForward();
+ if (s >= 0 && operator[](s).inset().asInsetMath() && popForward()) {
+ // Make sure the cursor moves directly to an
+ // \overbrace or \underbrace inset (bug 2264)
+ bool to_script = inset().asInsetMath()
+ && inset().asInsetMath()->asScriptInset();
+ return from_brace_deco && to_script ? mathForward(word) : true;
+ }
return false;
}
while (pos() > 0 && mc == prevMath().mathClass());
}
} else if (openable(prevAtom())) {
+ InsetMathScript const * p = prevMath().asScriptInset();
+ bool to_brace_deco = p && !p->nuc().empty()
+ && p->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+ && p->nuc().back()->mathClass() == MC_OP;
// single step: try to enter the preceding inset
posBackward();
push(nextMath());
inset().idxLast(*this);
+ // Make sure the cursor moves directly to an
+ // \overbrace or \underbrace inset (bug 2264)
+ if (to_brace_deco) {
+ posBackward();
+ push(nextMath());
+ inset().idxLast(*this);
+ }
} else
posBackward();
return true;
}
if (inset().idxBackward(*this))
return true;
+ InsetMath const * m = inset().asInsetMath();
+ bool from_brace_deco = m
+ && m->lyxCode() == MATH_DECORATION_CODE
+ && m->mathClass() == MC_OP;
// try to pop backwards --- but don't pop out of math! leave that to
// the FINISH lfuns
int s = depth() - 2;
- if (s >= 0 && operator[](s).inset().asInsetMath())
- return popBackward();
+ if (s >= 0 && operator[](s).inset().asInsetMath() && popBackward()) {
+ // Make sure the cursor moves directly to an
+ // \overbrace or \underbrace inset (bug 2264)
+ bool to_script = inset().asInsetMath()
+ && inset().asInsetMath()->asScriptInset();
+ return from_brace_deco && to_script ? mathBackward(word) : true;
+ }
return false;
}
-bool Cursor::upDownInText(bool up, bool & updateNeeded)
+bool Cursor::upDownInText(bool up)
{
LASSERT(text(), return false);
getPos(xo, yo);
xo = beforeDispatchPosX_;
+ // Is a full repaint necessary?
+ bool updateNeeded = false;
+
// update the targetX - this is here before the "return false"
// to set a new target which can be used by InsetTexts above
// if we cannot move up/down inside this inset anymore
dummy.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0;
dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0;
- updateNeeded |= bv().checkDepm(dummy, *this);
- updateTextTargetOffset();
- if (updateNeeded)
+ if (bv().checkDepm(dummy, *this)) {
+ updateNeeded = true;
forceBufferUpdate();
+ }
+ updateTextTargetOffset();
}
- return false;
+ return updateNeeded;
}
// with and without selection are handled differently
++dummy.pos();
if (bv().checkDepm(dummy, old)) {
updateNeeded = true;
+ forceBufferUpdate();
// Make sure that cur gets back whatever happened to dummy (Lgb)
operator=(dummy);
}
// When selection==false, this is done by TextMetrics::editXY
setCurrentFont();
- updateNeeded |= bv().checkDepm(*this, old);
+ if (bv().checkDepm(*this, old)) {
+ updateNeeded = true;
+ forceBufferUpdate();
+ }
}
- if (updateNeeded)
- forceBufferUpdate();
updateTextTargetOffset();
- return true;
+ return updateNeeded;
}
void Cursor::setLanguageFromInput()
{
- if (!lyxrc.respect_os_kbd_language)
+ if (!lyxrc.respect_os_kbd_language
+ || !inTexted()
+ || paragraph().isPassThru())
return;
string const & code = theApp()->inputLanguageCode();
Language const * lang = languages.getFromCode(code, buffer()->getLanguages());
void Cursor::checkBufferStructure()
{
+ if (buffer()->isInternal())
+ return;
+
Buffer const * master = buffer()->masterBuffer();
master->tocBackend().updateItem(*this);
if (master != buffer() && !master->hasGuiDelegate())