#include <config.h>
+#include "Cursor.h"
+
#include "Buffer.h"
#include "BufferView.h"
#include "CoordCache.h"
-#include "Cursor.h"
#include "CutAndPaste.h"
-#include "DispatchResult.h"
#include "FuncCode.h"
#include "FuncRequest.h"
+#include "Language.h"
#include "Layout.h"
#include "LyXAction.h"
#include "LyXRC.h"
#include "Paragraph.h"
-#include "ParIterator.h"
#include "Row.h"
#include "texstream.h"
#include "Text.h"
#include "support/debug.h"
#include "support/docstream.h"
-#include "support/ExceptionMessage.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "insets/InsetLayout.h"
#include "insets/InsetTabular.h"
-#include "insets/InsetText.h"
#include "mathed/InsetMath.h"
#include "mathed/InsetMathBrace.h"
#include "mathed/MathFactory.h"
#include "mathed/InsetMathMacro.h"
+#include "frontends/Application.h"
+
#include <sstream>
#include <limits>
#include <map>
CursorData::CursorData()
: DocIterator(), anchor_(), selection_(false), mark_(false),
- word_selection_(false), autocorrect_(false), current_font(inherit_font)
+ word_selection_(false), current_font(inherit_font)
{}
CursorData::CursorData(Buffer * buffer)
: DocIterator(buffer), anchor_(), selection_(false), mark_(false),
- word_selection_(false), autocorrect_(false), current_font(inherit_font)
+ word_selection_(false), current_font(inherit_font)
{}
CursorData::CursorData(DocIterator const & dit)
: DocIterator(dit), anchor_(), selection_(false), mark_(false),
- word_selection_(false), autocorrect_(false), current_font(inherit_font)
+ word_selection_(false), current_font(inherit_font)
{}
docstring parbreak(CursorData const * cur)
{
+ if (cur->inset().getLayout().parbreakIgnored())
+ return docstring();
odocstringstream os;
os << '\n';
// only add blank line if we're not in a ParbreakIsNewline situation
}
-docstring CursorData::selectionAsString(bool with_label) const
+docstring CursorData::selectionAsString(bool const with_label, bool const skipdelete) const
{
if (!selection())
return docstring();
if (inMathed())
return cap::grabSelection(*this);
- int const label = with_label
+ int label = with_label
? AS_STR_LABEL | AS_STR_INSETS : AS_STR_INSETS;
+ if (skipdelete)
+ label = with_label
+ ? AS_STR_LABEL | AS_STR_INSETS | AS_STR_SKIPDELETE
+ : AS_STR_INSETS | AS_STR_SKIPDELETE;
idx_type const startidx = selBegin().idx();
idx_type const endidx = selEnd().idx();
}
-int CursorData::countInsetsInSelection(InsetCode const & inset_code)
+int CursorData::countInsetsInSelection(InsetCode const & inset_code) const
{
if (!selection_)
return 0;
}
-bool CursorData::insetInSelection(InsetCode const & inset_code)
+bool CursorData::insetInSelection(InsetCode const & inset_code) const
{
if (!selection_)
return false;
}
+void CursorData::splitUndoGroup() const
+{
+ buffer()->undo().splitUndoGroup(*this);
+}
+
+
void CursorData::recordUndo(pit_type from, pit_type to) const
{
buffer()->undo().recordUndo(*this, from, to);
}
-void CursorData::recordUndoInset(Inset const * in) const
+void CursorData::recordUndoInset(Inset const * inset) const
{
- buffer()->undo().recordUndoInset(*this, in);
+ buffer()->undo().recordUndoInset(*this, inset);
}
}
-int CursorData::currentMode()
+int CursorData::currentMode() const
{
LASSERT(!empty(), return Inset::UNDECIDED_MODE);
for (int i = depth() - 1; i >= 0; --i) {
}
-void Cursor::push(Inset & p)
+void Cursor::push(Inset & inset)
{
- push_back(CursorSlice(p));
- p.setBuffer(*buffer());
+ push_back(CursorSlice(inset));
+ inset.setBuffer(*buffer());
}
-void Cursor::pushBackward(Inset & p)
+void Cursor::pushBackward(Inset & inset)
{
LASSERT(!empty(), return);
//lyxerr << "Entering inset " << t << " front" << endl;
- push(p);
- p.idxFirst(*this);
+ push(inset);
+ inset.idxFirst(*this);
}
}
-bool Cursor::selHandle(bool sel)
+bool Cursor::selHandle(bool selecting)
{
//lyxerr << "Cursor::selHandle" << endl;
if (mark())
- sel = true;
- if (sel == selection())
+ selecting = true;
+ if (selecting == selection())
return false;
- if (!sel)
+ if (!selecting)
cap::saveSelection(*this);
resetAnchor();
- selection(sel);
+ selection(selecting);
return true;
}
///////////////////////////////////////////////////////////////////
#include "mathed/InsetMathChar.h"
-#include "mathed/InsetMathGrid.h"
-#include "mathed/InsetMathScript.h"
#include "mathed/InsetMathUnknown.h"
-#include "mathed/MathFactory.h"
#include "mathed/MathStream.h"
#include "mathed/MathSupport.h"
// [|], 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();
}
InsetMathUnknown * Cursor::activeMacro()
{
- return inMacroMode() ? prevAtom().nucleus()->asUnknownInset() : 0;
+ return inMacroMode() ? prevAtom().nucleus()->asUnknownInset() : nullptr;
}
InsetMathUnknown const * Cursor::activeMacro() const
{
- return inMacroMode() ? prevAtom().nucleus()->asUnknownInset() : 0;
+ return inMacroMode() ? prevAtom().nucleus()->asUnknownInset() : nullptr;
}
<< " 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();
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;
}
if (updateNeeded)
forceBufferUpdate();
}
- return false;
+ return valid_destination;
}
// with and without selection are handled differently
}
+void Cursor::setLanguageFromInput()
+{
+ if (!lyxrc.respect_os_kbd_language
+ || !inTexted()
+ || paragraph().isPassThru())
+ return;
+ string const & code = theApp()->inputLanguageCode();
+ Language const * lang = languages.getFromCode(code, buffer()->getLanguages());
+ if (lang) {
+ current_font.setLanguage(lang);
+ real_current_font.setLanguage(lang);
+ } else
+ LYXERR0("setLanguageFromCode: unknown language code " << code);
+}
+
+
void Cursor::setCurrentFont()
{
CursorSlice const & cs = innerTextSlice();
current_font = par.getFontSettings(bufparams, cpos);
real_current_font = tm.displayFont(cpit, cpos);
+ // set language to input language
+ setLanguageFromInput();
+
// special case for paragraph end
if (cs.pos() == lastpos()
&& tm.isRTLBoundary(cpit, cs.pos())
real_current_font.setLanguage(lang);
real_current_font.fontInfo().setNumber(FONT_OFF);
}
+
+ // No language in pass thru situations
+ if (cs.paragraph().isPassThru()) {
+ current_font.setLanguage(latex_language);
+ real_current_font.setLanguage(latex_language);
+ }
}
void Cursor::checkBufferStructure()
{
+ if (buffer()->isInternal())
+ return;
+
Buffer const * master = buffer()->masterBuffer();
master->tocBackend().updateItem(*this);
if (master != buffer() && !master->hasGuiDelegate())
// In case the master has no gui associated with it,
// the TocItem is not updated (part of bug 5699).
buffer()->tocBackend().updateItem(*this);
-
- // If the last tracked change of the paragraph has just been
- // deleted, then we need to recompute the buffer flag
- // tracked_changes_present_.
- if (inTexted() && paragraph().isChangeUpdateRequired())
- disp_.forceChangesUpdate();
}