#include "author.h"
#include "buffer.h"
+#include "buffer_funcs.h"
#include "bufferparams.h"
#include "BufferView.h"
#include "cursor.h"
void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
- string const & token, LyXFont & font)
+ string const & token, LyXFont & font, Change & change)
{
- static Change change;
-
BufferParams const & bp = buf.params();
if (token[0] != '\\') {
string::const_iterator cit = token.begin();
- for (; cit != token.end(); ++cit) {
+ for (; cit != token.end(); ++cit)
par.insertChar(par.size(), (*cit), font, change);
- }
} else if (token == "\\begin_layout") {
lex.eatLine();
string layoutname = lex.getString();
if (!hasLayout) {
buf.error(ErrorItem(_("Unknown layout"),
- bformat(_("Layout '%1$s' does not exists in textclass '%2$s'\nTrying to use the default instead.\n"),
+ bformat(_("Layout '%1$s' does not exist in textclass '%2$s'\nTrying to use the default instead.\n"),
layoutname, tclass.name()), par.id(), 0, par.size()));
layoutname = tclass.defaultLayoutName();
}
par.params().read(lex);
} else if (token == "\\end_layout") {
- lyxerr << "Solitary \\end_layout in line " << lex.getLineNo() << "\n"
+ lyxerr << BOOST_CURRENT_FUNCTION
+ << ": Solitary \\end_layout in line "
+ << lex.getLineNo() << "\n"
<< "Missing \\begin_layout?.\n";
} else if (token == "\\end_inset") {
- lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n"
+ lyxerr << BOOST_CURRENT_FUNCTION
+ << ": Solitary \\end_inset in line "
+ << lex.getLineNo() << "\n"
<< "Missing \\begin_inset?.\n";
} else if (token == "\\begin_inset") {
InsetBase * inset = readInset(lex, buf);
lex.nextToken();
string token = lex.getString();
LyXFont font;
+ Change change;
while (lex.isOK()) {
- readParToken(buf, par, lex, token, font);
+ readParToken(buf, par, lex, token, font, change);
lex.nextToken();
token = lex.getString();
break;
}
}
+ // Initialize begin_of_body_ on load; redoParagraph maintains
+ par.setBeginOfBody();
}
} // namespace anon
-BufferView * LyXText::bv()
-{
- BOOST_ASSERT(bv_owner != 0);
- return bv_owner;
-}
-
BufferView * LyXText::bv() const
{
int LyXText::singleWidth(Paragraph const & par,
pos_type pos, char c, LyXFont const & font) const
{
- BOOST_ASSERT(pos < par.size());
-
// The most common case is handled first (Asger)
if (IsPrintable(c)) {
- if (font.language()->RightToLeft()) {
+ Language const * language = font.language();
+ if (language->RightToLeft()) {
if ((lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
lyxrc.font_norm_type == LyXRC::ISO_10646_1)
- && font.language()->lang() == "arabic") {
+ && language->lang() == "arabic") {
if (Encodings::IsComposeChar_arabic(c))
return 0;
c = par.transformChar(c, pos);
- } else if (font.language()->lang() == "hebrew" &&
+ } else if (language->lang() == "hebrew" &&
Encodings::IsComposeChar_hebrew(c))
return 0;
}
if (c == Paragraph::META_INSET)
return par.getInset(pos)->width();
- if (IsSeparatorChar(c))
- c = ' ';
return font_metrics::width(c, font);
}
&& !isFirstInSequence(pit, pars_)))
&& align == LYX_ALIGN_BLOCK
&& !par.params().noindent()
- // in charstyles, tabulars and ert paragraphs are never indented!
- && (par.ownerCode() != InsetBase::TEXT_CODE
- && par.ownerCode() != InsetBase::ERT_CODE
- && par.ownerCode() != InsetBase::CHARSTYLE_CODE)
+ // in some insets, paragraphs are never indented
+ && !(par.inInset() && par.inInset()->neverIndent())
+ // display style insets are always centered, omit indentation
+ && !(!par.empty()
+ && par.isInset(pos)
+ && par.getInset(pos)->display())
&& (par.layout() != tclass.defaultLayout()
|| bv()->buffer()->params().paragraph_separation ==
BufferParams::PARSEP_INDENT))
pos_type i = pos;
for ( ; i < end; ++i, ++fi) {
char const c = par.getChar(i);
+ int thiswidth = singleWidth(par, i, c, *fi);
- {
- int thiswidth = singleWidth(par, i, c, *fi);
-
- // add the auto-hfill from label end to the body
- if (body_pos && i == body_pos) {
- int add = font_metrics::width(layout->labelsep, getLabelFont(par));
- if (par.isLineSeparator(i - 1))
- add -= singleWidth(par, i - 1);
-
- add = std::max(add, labelEnd(pit) - x);
- thiswidth += add;
- }
+ // add the auto-hfill from label end to the body
+ if (body_pos && i == body_pos) {
+ int add = font_metrics::width(layout->labelsep, getLabelFont(par));
+ if (par.isLineSeparator(i - 1))
+ add -= singleWidth(par, i - 1);
- x += thiswidth;
- chunkwidth += thiswidth;
+ add = std::max(add, labelEnd(pit) - x);
+ thiswidth += add;
}
+ x += thiswidth;
+ chunkwidth += thiswidth;
+
// break before a character that will fall off
// the right of the row
if (x >= width) {
pos_type const end = row.endpos();
Paragraph const & par = pars_[pit];
- string labelsep = par.layout()->labelsep;
+ string const & labelsep = par.layout()->labelsep;
int w = leftMargin(pit, row.pos());
pos_type const body_pos = par.beginOfBody();
maxasc += bufparams.getDefSkip().inPixels(*bv());
}
- if (pars_[pit].params().startOfAppendix())
+ if (par.params().startOfAppendix())
maxasc += int(3 * dh);
// This is special code for the chapter, since the label of this
// layout is printed in an extra row
- if (layout->counter == "chapter" && bufparams.secnumdepth >= 0) {
+ if (layout->counter == "chapter"
+ && !par.params().labelString().empty()) {
labeladdon = int(font_metrics::maxHeight(labelfont)
* layout->spacing.getValue()
* spacing(par));
if (bv_owner->text() == this) {
if (pit == 0 && row.pos() == 0)
maxasc += 20;
- if (pit == pars_.size() - 1 && row.endpos() == par.size())
+ if (pit + 1 == pars_.size() && row.endpos() == par.size())
maxdesc += 20;
}
}
-void LyXText::breakParagraph(LCursor & cur, char keep_layout)
+void LyXText::breakParagraph(LCursor & cur, bool keep_layout)
{
BOOST_ASSERT(this == cur.text());
// allow only if at start or end, or all previous is new text
if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
cpar.erase(cur.pos());
- // break the paragraph
+ // How should the layout for the new paragraph be?
+ int preserve_layout = 0;
if (keep_layout)
- keep_layout = 2;
+ preserve_layout = 2;
else
- keep_layout = layout->isEnvironment();
+ preserve_layout = layout->isEnvironment();
+
+ // We need to remember this before we break the paragraph, because
+ // that invalidates the layout variable
+ bool sensitive = layout->labeltype == LABEL_SENSITIVE;
- // we need to set this before we insert the paragraph. IMO the
- // breakParagraph call should return a bool if it inserts the
- // paragraph before or behind and we should react on that one
- // but we can fix this in 1.3.0 (Jug 20020509)
+ // we need to set this before we insert the paragraph.
bool const isempty = cpar.allowEmpty() && cpar.empty();
+
::breakParagraph(cur.buffer().params(), paragraphs(), cpit,
- cur.pos(), keep_layout);
+ cur.pos(), preserve_layout);
+
+ // After this, neither paragraph contains any rows!
cpit = cur.pit();
pit_type next_par = cpit + 1;
// well this is the caption hack since one caption is really enough
- if (layout->labeltype == LABEL_SENSITIVE) {
+ if (sensitive) {
if (cur.pos() == 0)
// set to standard-layout
pars_[cpit].applyLayout(tclass.defaultLayout());
pars_[next_par].applyLayout(tclass.defaultLayout());
}
- // if the cursor is at the beginning of a row without prior newline,
- // move one row up!
- // This touches only the screen-update. Otherwise we would may have
- // an empty row on the screen
- if (cur.pos() != 0 && cur.textRow().pos() == cur.pos()
- && !pars_[cpit].isNewline(cur.pos() - 1))
- {
- cursorLeft(cur);
- }
-
while (!pars_[next_par].empty() && pars_[next_par].isNewline(0))
pars_[next_par].erase(0);
- updateCounters();
+ updateCounters(cur.buffer());
// This check is necessary. Otherwise the new empty paragraph will
// be deleted automatically. And it is more friendly for the user!
cur.message(_("You cannot insert a space at the "
"beginning of a paragraph. Please read the Tutorial."));
sent_space_message = true;
- return;
}
+ return;
}
BOOST_ASSERT(cur.pos() > 0);
- if (par.isLineSeparator(cur.pos() - 1)
- || par.isNewline(cur.pos() - 1)) {
+ if ((par.isLineSeparator(cur.pos() - 1)
+ || par.isNewline(cur.pos() - 1))
+ && par.lookupChange(cur.pos() - 1) != Change::DELETED) {
static bool sent_space_message = false;
if (!sent_space_message) {
cur.message(_("You cannot type two spaces this way. "
current_font = rawtmpfont;
real_current_font = realtmpfont;
- setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+ //setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+ setCursor(cur, cur.pit(), cur.pos() + 1, false, true);
charInserted();
}
// the cursor set functions have a special mechanism. When they
// realize, that you left an empty paragraph, they will delete it.
-void LyXText::cursorRightOneWord(LCursor & cur)
+bool LyXText::cursorRightOneWord(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
- if (cur.pos() == cur.lastpos() && cur.pit() != cur.lastpit()) {
- ++cur.pit();
- cur.pos() = 0;
+
+ LCursor old = cur;
+
+ if (old.pos() == old.lastpos() && old.pit() != old.lastpit()) {
+ ++old.pit();
+ old.pos() = 0;
} else {
// Skip through initial nonword stuff.
// Treat floats and insets as words.
- while (cur.pos() != cur.lastpos() && !cur.paragraph().isLetter(cur.pos()))
- ++cur.pos();
+ while (old.pos() != old.lastpos() && !old.paragraph().isLetter(old.pos()))
+ ++old.pos();
// Advance through word.
- while (cur.pos() != cur.lastpos() && cur.paragraph().isLetter(cur.pos()))
- ++cur.pos();
+ while (old.pos() != old.lastpos() && old.paragraph().isLetter(old.pos()))
+ ++old.pos();
}
- setCursor(cur, cur.pit(), cur.pos());
+ return setCursor(cur, old.pit(), old.pos());
}
-void LyXText::cursorLeftOneWord(LCursor & cur)
+bool LyXText::cursorLeftOneWord(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
- if (cur.pos() == 0 && cur.pit() != 0) {
- --cur.pit();
- cur.pos() = cur.lastpos();
+
+ LCursor old = cur;
+
+ if (old.pos() == 0 && old.pit() != 0) {
+ --old.pit();
+ old.pos() = old.lastpos();
} else {
// Skip through initial nonword stuff.
// Treat floats and insets as words.
- while (cur.pos() != 0 && !cur.paragraph().isLetter(cur.pos() - 1))
- --cur.pos();
+ while (old.pos() != 0 && !old.paragraph().isLetter(old.pos() - 1))
+ --old.pos();
// Advance through word.
- while (cur.pos() != 0 && cur.paragraph().isLetter(cur.pos() - 1))
- --cur.pos();
+ while (old.pos() != 0 && old.paragraph().isLetter(old.pos() - 1))
+ --old.pos();
}
- setCursor(cur, cur.pit(), cur.pos());
+ return setCursor(cur, old.pit(), old.pos());
}
void LyXText::Delete(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
+
if (cur.pos() != cur.lastpos()) {
recordUndo(cur, Undo::DELETE, cur.pit());
setCursorIntern(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
backspace(cur);
+ } else if (cur.pit() != cur.lastpit()) {
+ LCursor scur = cur;
+
+ setCursorIntern(cur, cur.pit()+1, 0, false, false);
+ if (pars_[cur.pit()].layout() == pars_[scur.pit()].layout()) {
+ recordUndo(scur, Undo::DELETE, scur.pit());
+ backspace(cur);
+ } else {
+ setCursorIntern(scur, scur.pit(), scur.pos(), false, scur.boundary());
+ }
}
- // should we do anything in an else branch?
}
// handle the actual deletion of the paragraph.
if (cur.pit() != 0) {
+ // For KeepEmpty layouts we need to get
+ // rid of the keepEmpty setting first.
+ // And the only way to do this is to
+ // reset the layout to something
+ // else: f.ex. the default layout.
+ if (par.allowEmpty()) {
+ Buffer & buf = cur.buffer();
+ BufferParams const & bparams = buf.params();
+ par.layout(bparams.getLyXTextClass().defaultLayout());
+ }
+
cursorLeft(cur);
return;
}
// layout. I think it is a real bug of all other
// word processors to allow it. It confuses the user.
// Correction: Pasting is always allowed with standard-layout
+ // Correction (Jug 20050717): Remove check about alignment!
Buffer & buf = cur.buffer();
BufferParams const & bufparams = buf.params();
LyXTextClass const & tclass = bufparams.getLyXTextClass();
if (cpit != tmppit
&& (pars_[cpit].layout() == pars_[tmppit].layout()
- || pars_[tmppit].layout() == tclass.defaultLayout())
- && pars_[cpit].getAlign() == pars_[tmppit].getAlign()) {
+ || pars_[tmppit].layout() == tclass.defaultLayout()))
+ {
mergeParagraph(bufparams, pars_, cpit);
if (cur.pos() != 0 && pars_[cpit].isSeparator(cur.pos() - 1))
--cur.pos();
// the counters may have changed
- updateCounters();
+ updateCounters(cur.buffer());
setCursor(cur, cur.pit(), cur.pos(), false);
}
} else {
}
-Paragraph & LyXText::getPar(pit_type par) const
-{
- //lyxerr << "getPar: " << par << " from " << paragraphs().size() << endl;
- BOOST_ASSERT(par >= 0);
- BOOST_ASSERT(par < int(paragraphs().size()));
- return paragraphs()[par];
-}
-
-
Row const & LyXText::firstRow() const
{
return *paragraphs().front().rows().begin();
}
-void LyXText::redoParagraph(pit_type const pit)
+bool LyXText::redoParagraph(pit_type const pit)
{
// remove rows of paragraph, keep track of height changes
Paragraph & par = pars_[pit];
+ // Add bibitem insets if necessary
+ if (par.layout()->labeltype == LABEL_BIBLIO) {
+ bool hasbibitem(false);
+ if (!par.insetlist.empty()
+ // Insist on it being in pos 0
+ && par.getChar(0) == Paragraph::META_INSET) {
+ InsetBase * inset = par.insetlist.begin()->inset;
+ if (inset->lyxCode() == InsetBase::BIBITEM_CODE)
+ hasbibitem = true;
+ }
+ if (!hasbibitem) {
+ InsetBibitem * inset(new
+ InsetBibitem(InsetCommandParams("bibitem")));
+ par.insertInset(0, static_cast<InsetBase *>(inset));
+ bv()->cursor().posRight();
+ }
+ }
+
// redo insets
InsetList::iterator ii = par.insetlist.begin();
InsetList::iterator iend = par.insetlist.end();
dim.asc += par.rows()[0].ascent();
dim.des -= par.rows()[0].ascent();
- par.dim_ = dim;
+
+ bool const same = dim == par.dim();
+
+ par.dim() = dim;
//lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
+
+ return !same;
}
maxwidth_ = mi.base.textwidth;
//lyxerr << "LyXText::metrics: width: " << mi.base.textwidth
// << " maxWidth: " << maxwidth_ << "\nfont: " << mi.base.font << endl;
+ // save the caller's font locally:
+ font_ = mi.base.font;
unsigned int h = 0;
unsigned int w = 0;
}
-/*
+#if 0
// only used for inset right now. should also be used for main text
void LyXText::drawSelection(PainterInfo & pi, int x , int) const
{
Paragraph const & par1 = pars_[beg.pit()];
Paragraph const & par2 = pars_[end.pit()];
- Row const & row1 = par1.getRow(beg.pos());
- Row const & row2 = par2.getRow(end.pos());
+ Row const & row1 = par1.getRow(beg.pos(), beg.boundary());
+ Row const & row2 = par2.getRow(end.pos(), end.boundary());
int y1,x1,x2;
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_ABOVE) {
x2 = 0;
} else {
y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
- int const startx = cursorX(beg.top());
+ int const startx = cursorX(beg.top(), begin.boundary());
x1 = isRTL(par1) ? startx : 0;
x2 = isRTL(par1) ? 0 + dim_.wid : startx;
}
X2 = 0;
} else {
y2 = bv_funcs::getPos(end).y_ + row2.descent();
- int const endx = cursorX(end.top());
+ int const endx = cursorX(end.top(), end.boundary());
X1 = isRTL(par2) ? 0 : endx;
X2 = isRTL(par2) ? endx : 0 + dim_.wid;
}
pi.pain.fillRectangle(x + X1, y2 - row2.height(),
X2 - X1, row2.height(), LColor::background);
}
-*/
+#else
void LyXText::drawSelection(PainterInfo & pi, int x, int) const
{
if (!ptr_cmp(cur.text(), this))
return;
- lyxerr << "draw selection at " << x << endl;
+ lyxerr[Debug::DEBUG]
+ << BOOST_CURRENT_FUNCTION
+ << "draw selection at " << x
+ << endl;
// is there a better way of getting these two iterators?
DocIterator beg = cur;
x1 = 0;
x2 = dim_.wid;
} else {
- Row const & row1 = par1.getRow(beg.pos());
- y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
+ Row const & row1 = par1.getRow(beg.pos(), beg.boundary());
+ y1 = bv_funcs::getPos(beg, beg.boundary()).y_ - row1.ascent();
y2 = y1 + row1.height();
- int const startx = cursorX(beg.top());
+ int const startx = cursorX(beg.top(), beg.boundary());
x1 = !isRTL(par1) ? startx : 0;
x2 = !isRTL(par1) ? 0 + dim_.wid : startx;
}
X1 = 0;
X2 = dim_.wid;
} else {
- Row const & row2 = par2.getRow(end.pos());
- Y1 = bv_funcs::getPos(end).y_ - row2.ascent();
+ Row const & row2 = par2.getRow(end.pos(), end.boundary());
+ Y1 = bv_funcs::getPos(end, end.boundary()).y_ - row2.ascent();
Y2 = Y1 + row2.height();
- int const endx = cursorX(end.top());
+ int const endx = cursorX(end.top(), end.boundary());
X1 = !isRTL(par2) ? 0 : endx;
X2 = !isRTL(par2) ? endx : 0 + dim_.wid;
}
- if (!above && !below && &par1.getRow(beg.pos())
- == &par2.getRow(end.pos()))
+ if (!above && !below && &par1.getRow(beg.pos(), beg.boundary())
+ == &par2.getRow(end.pos(), end.boundary()))
{
// paint only one rectangle
- pi.pain.fillRectangle(x + x1, y1, X2 - x1, y2 - y1,
- LColor::selection);
+ int const b( !isRTL(par1) ? x + x1 : x + X1 );
+ int const w( !isRTL(par1) ? X2 - x1 : x2 - X1 );
+ pi.pain.fillRectangle(b, y1, w, y2 - y1, LColor::selection);
return;
}
+ lyxerr[Debug::DEBUG] << " y1: " << y1 << " y2: " << y2
+ << "X1:" << X1 << " x2: " << X2 << " wid: " << dim_.wid
+ << endl;
+
// paint upper rectangle
pi.pain.fillRectangle(x + x1, y1, x2 - x1, y2 - y1,
LColor::selection);
pi.pain.fillRectangle(x, y2, dim_.wid,
Y1 - y2, LColor::selection);
}
+#endif
bool LyXText::isLastRow(pit_type pit, Row const & row) const
{
bool LyXText::read(Buffer const & buf, LyXLex & lex)
{
- static Change current_change;
-
Paragraph::depth_type depth = 0;
while (lex.isOK()) {
}
-int LyXText::cursorX(CursorSlice const & cur) const
+int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
{
- pit_type const pit = cur.pit();
+ pit_type const pit = sl.pit();
Paragraph const & par = pars_[pit];
if (par.rows().empty())
return 0;
- Row const & row = par.getRow(cur.pos());
+ pos_type ppos = sl.pos();
+ // Correct position in front of big insets
+ bool const boundary_correction = ppos != 0 && boundary;
+ if (boundary_correction)
+ --ppos;
+
+ Row const & row = par.getRow(sl.pos(), boundary);
- pos_type pos = cur.pos();
pos_type cursor_vpos = 0;
RowMetrics const m = computeRowMetrics(pit, row);
if (end <= row_pos)
cursor_vpos = row_pos;
- else if (pos >= end)
+ else if (ppos >= end)
cursor_vpos = isRTL(par) ? row_pos : end;
- else if (pos > row_pos && pos >= end)
+ else if (ppos > row_pos && ppos >= end)
// Place cursor after char at (logical) position pos - 1
- cursor_vpos = (bidi.level(pos - 1) % 2 == 0)
- ? bidi.log2vis(pos - 1) + 1 : bidi.log2vis(pos - 1);
+ cursor_vpos = (bidi.level(ppos - 1) % 2 == 0)
+ ? bidi.log2vis(ppos - 1) + 1 : bidi.log2vis(ppos - 1);
else
- // Place cursor before char at (logical) position pos
- cursor_vpos = (bidi.level(pos) % 2 == 0)
- ? bidi.log2vis(pos) : bidi.log2vis(pos) + 1;
+ // Place cursor before char at (logical) position ppos
+ cursor_vpos = (bidi.level(ppos) % 2 == 0)
+ ? bidi.log2vis(ppos) : bidi.log2vis(ppos) + 1;
pos_type body_pos = par.beginOfBody();
if (body_pos > 0 &&
(body_pos > end || !par.isLineSeparator(body_pos - 1)))
body_pos = 0;
+ // Use font span to speed things up, see below
+ FontSpan font_span;
+ LyXFont font;
+
for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
pos_type pos = bidi.vis2log(vpos);
if (body_pos > 0 && pos == body_pos - 1) {
x -= singleWidth(par, body_pos - 1);
}
- if (hfillExpansion(par, row, pos)) {
- x += singleWidth(par, pos);
- if (pos >= body_pos)
- x += m.hfill;
- else
- x += m.label_hfill;
- } else if (par.isSeparator(pos)) {
- x += singleWidth(par, pos);
- if (pos >= body_pos)
- x += m.separator;
- } else
- x += singleWidth(par, pos);
+ // Use font span to speed things up, see above
+ if (pos < font_span.first || pos > font_span.last) {
+ font_span = par.fontSpan(pos);
+ font = getFont(par, pos);
+ }
+
+ x += singleWidth(par, pos, par.getChar(pos), font);
+
+ if (hfillExpansion(par, row, pos))
+ x += (pos >= body_pos) ? m.hfill : m.label_hfill;
+ else if (par.isSeparator(pos) && pos >= body_pos)
+ x += m.separator;
}
+
+ // see correction above
+ if (boundary_correction)
+ if (getFont(par, ppos).isRightToLeft())
+ x -= singleWidth(par, ppos);
+ else
+ x += singleWidth(par, ppos);
+
return int(x);
}
-int LyXText::cursorY(CursorSlice const & cur) const
+int LyXText::cursorY(CursorSlice const & sl, bool boundary) const
{
- Paragraph const & par = getPar(cur.pit());
+ //lyxerr << "LyXText::cursorY: boundary: " << boundary << std::endl;
+ Paragraph const & par = getPar(sl.pit());
int h = 0;
h -= pars_[0].rows()[0].ascent();
- for (pit_type pit = 0; pit < cur.pit(); ++pit)
+ for (pit_type pit = 0; pit < sl.pit(); ++pit)
h += pars_[pit].height();
- for (size_t rit = 0, rend = par.pos2row(cur.pos()); rit != rend; ++rit)
+ int pos = sl.pos();
+ if (pos && boundary)
+ --pos;
+ size_t const rend = par.pos2row(pos);
+ for (size_t rit = 0; rit != rend; ++rit)
h += par.rows()[rit].height();
- h += par.rows()[par.pos2row(cur.pos())].ascent();
+ h += par.rows()[rend].ascent();
return h;
}
os << _(", Paragraph: ") << cur.pit();
os << _(", Id: ") << par.id();
os << _(", Position: ") << cur.pos();
+ os << _(", Boundary: ") << cur.boundary();
// Row & row = cur.textRow();
// os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos());
#endif
pos_type LyXText::x2pos(pit_type pit, int row, int x) const
{
+ BOOST_ASSERT(row < int(pars_[pit].rows().size()));
bool bound = false;
Row const & r = pars_[pit].rows()[row];
return r.pos() + getColumnNearX(pit, r, x, bound);
{
pit_type pit = getPitNearY(y);
int yy = theCoords.get(this, pit).y_ - pars_[pit].ascent();
- lyxerr << "setCursorFromCoordinates: x: " << x << " y: " << y
- << " pit: " << pit << " yy: " << yy << endl;
+ lyxerr[Debug::DEBUG]
+ << BOOST_CURRENT_FUNCTION
+ << ": x: " << x
+ << " y: " << y
+ << " pit: " << pit
+ << " yy: " << yy << endl;
Paragraph const & par = pars_[pit];
int r = 0;
Row const & row = par.rows()[r];
- lyxerr << "setCursorFromCoordinates: row " << r
- << " from pos: " << row.pos() << endl;
+ lyxerr[Debug::DEBUG]
+ << BOOST_CURRENT_FUNCTION
+ << ": row " << r
+ << " from pos: " << row.pos()
+ << endl;
bool bound = false;
int xx = x;
pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
+
+ lyxerr[Debug::DEBUG]
+ << BOOST_CURRENT_FUNCTION
+ << ": setting cursor pit: " << pit
+ << " pos: " << pos
+ << endl;
+
setCursor(cur, pit, pos, true, bound);
}