#include "lyxtext.h"
#include "LString.h"
+#include "Lsstream.h"
#include "paragraph.h"
+#include "funcrequest.h"
#include "frontends/LyXView.h"
#include "undo_funcs.h"
#include "buffer.h"
#include "bufferparams.h"
+#include "errorlist.h"
#include "gettext.h"
#include "BufferView.h"
#include "CutAndPaste.h"
#include "ParagraphParameters.h"
#include "counters.h"
#include "lyxrow_funcs.h"
+#include "paragraph_funcs.h"
#include "insets/insetbibitem.h"
+#include "insets/insetenv.h"
#include "insets/insetfloat.h"
+#include "insets/insetwrap.h"
#include "support/LAssert.h"
#include "support/textutils.h"
#include "support/lstrings.h"
-#include "support/BoostFormat.h"
+#include <boost/tuple/tuple.hpp>
using std::vector;
using std::copy;
rowlist_.clear();
need_break_row = rows().end();
width = height = 0;
- copylayouttype.erase();
top_y(0);
clearPaint();
} else if (!rowlist_.empty())
return;
- ParagraphList::iterator par = ownerParagraphs().begin();
+ ParagraphList::iterator pit = ownerParagraphs().begin();
ParagraphList::iterator end = ownerParagraphs().end();
- current_font = getFont(bview->buffer(), &*par, 0);
+ current_font = getFont(bview->buffer(), pit, 0);
- for (; par != end; ++par) {
- insertParagraph(&*par, rowlist_.end());
+ for (; pit != end; ++pit) {
+ insertParagraph(pit, rowlist_.end());
}
- setCursorIntern(&*rowlist_.begin()->par(), 0);
+ setCursorIntern(rowlist_.begin()->par(), 0);
selection.cursor = cursor;
updateCounters();
}
-namespace {
-
-LyXFont const realizeFont(LyXFont const & font,
- Buffer const * buf,
- Paragraph * par)
-{
- LyXTextClass const & tclass = buf->params.getLyXTextClass();
- LyXFont tmpfont(font);
- Paragraph::depth_type par_depth = par->getDepth();
-
- // Resolve against environment font information
- while (par && par_depth && !tmpfont.resolved()) {
- par = par->outerHook();
- if (par) {
- tmpfont.realize(par->layout()->font);
- par_depth = par->getDepth();
- }
- }
-
- tmpfont.realize(tclass.defaultfont());
-
- return tmpfont;
-}
-
-}
-
-
// Gets the fully instantiated font at a given position in a paragraph
// Basically the same routine as Paragraph::getFont() in paragraph.C.
// The difference is that this one is used for displaying, and thus we
// smaller. (Asger)
// If position is -1, we get the layout font of the paragraph.
// If position is -2, we get the font of the manual label of the paragraph.
-LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
+LyXFont const LyXText::getFont(Buffer const * buf, ParagraphList::iterator pit,
pos_type pos) const
{
lyx::Assert(pos >= 0);
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
// We specialize the 95% common case:
- if (!par->getDepth()) {
+ if (!pit->getDepth()) {
if (layout->labeltype == LABEL_MANUAL
- && pos < par->beginningOfBody()) {
+ && pos < pit->beginningOfBody()) {
// 1% goes here
- LyXFont f = par->getFontSettings(buf->params, pos);
- if (par->inInset())
- par->inInset()->getDrawFont(f);
+ LyXFont f = pit->getFontSettings(buf->params, pos);
+ if (pit->inInset())
+ pit->inInset()->getDrawFont(f);
return f.realize(layout->reslabelfont);
} else {
- LyXFont f = par->getFontSettings(buf->params, pos);
- if (par->inInset())
- par->inInset()->getDrawFont(f);
+ LyXFont f = pit->getFontSettings(buf->params, pos);
+ if (pit->inInset())
+ pit->inInset()->getDrawFont(f);
return f.realize(layout->resfont);
}
}
LyXFont layoutfont;
- if (pos < par->beginningOfBody()) {
+ if (pos < pit->beginningOfBody()) {
// 1% goes here
layoutfont = layout->labelfont;
} else {
layoutfont = layout->font;
}
- LyXFont tmpfont = par->getFontSettings(buf->params, pos);
+ LyXFont tmpfont = pit->getFontSettings(buf->params, pos);
tmpfont.realize(layoutfont);
- if (par->inInset())
- par->inInset()->getDrawFont(tmpfont);
+ if (pit->inInset())
+ pit->inInset()->getDrawFont(tmpfont);
+
+ // Realize with the fonts of lesser depth.
+ tmpfont.realize(outerFont(pit, ownerParagraphs()));
- return realizeFont(tmpfont, buf, par);
+ return realizeFont(tmpfont, buf->params);
}
-LyXFont const LyXText::getLayoutFont(Buffer const * buf, Paragraph * par) const
+LyXFont const LyXText::getLayoutFont(Buffer const * buf,
+ ParagraphList::iterator pit) const
{
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
- if (!par->getDepth()) {
+ if (!pit->getDepth()) {
return layout->resfont;
}
- return realizeFont(layout->font, buf, par);
+ LyXFont font(layout->font);
+ // Realize with the fonts of lesser depth.
+ font.realize(outerFont(pit, ownerParagraphs()));
+
+ return realizeFont(font, buf->params);
}
-LyXFont const LyXText::getLabelFont(Buffer const * buf, Paragraph * par) const
+LyXFont const LyXText::getLabelFont(Buffer const * buf,
+ ParagraphList::iterator pit) const
{
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
- if (!par->getDepth()) {
+ if (!pit->getDepth()) {
return layout->reslabelfont;
}
- return realizeFont(layout->labelfont, buf, par);
+ LyXFont font(layout->labelfont);
+ // Realize with the fonts of lesser depth.
+ font.realize(outerFont(pit, ownerParagraphs()));
+
+ return realizeFont(layout->labelfont, buf->params);
}
-void LyXText::setCharFont(Paragraph * par,
+void LyXText::setCharFont(ParagraphList::iterator pit,
pos_type pos, LyXFont const & fnt,
bool toggleall)
{
Buffer const * buf = bv()->buffer();
- LyXFont font = getFont(buf, par, pos);
+ LyXFont font = getFont(buf, pit, pos);
font.update(fnt, buf->params.language, toggleall);
// Let the insets convert their font
- if (par->isInset(pos)) {
- Inset * inset = par->getInset(pos);
+ if (pit->isInset(pos)) {
+ Inset * inset = pit->getInset(pos);
if (isEditableInset(inset)) {
UpdatableInset * uinset =
static_cast<UpdatableInset *>(inset);
}
// Plug thru to version below:
- setCharFont(buf, par, pos, font);
+ setCharFont(buf, pit, pos, font);
}
-void LyXText::setCharFont(Buffer const * buf, Paragraph * par,
+void LyXText::setCharFont(Buffer const * buf, ParagraphList::iterator pit,
pos_type pos, LyXFont const & fnt)
{
LyXFont font(fnt);
LyXTextClass const & tclass = buf->params.getLyXTextClass();
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
// Get concrete layout font to reduce against
LyXFont layoutfont;
- if (pos < par->beginningOfBody())
+ if (pos < pit->beginningOfBody())
layoutfont = layout->labelfont;
else
layoutfont = layout->font;
// Realize against environment font information
- if (par->getDepth()) {
- Paragraph * tp = par;
- while (!layoutfont.resolved() && tp && tp->getDepth()) {
- tp = tp->outerHook();
- if (tp)
+ if (pit->getDepth()) {
+ ParagraphList::iterator tp = pit;
+ while (!layoutfont.resolved() &&
+ tp != ownerParagraphs().end() &&
+ tp->getDepth()) {
+ tp = outerHook(tp, ownerParagraphs());
+ if (tp != ownerParagraphs().end())
layoutfont.realize(tp->layout()->font);
}
}
// Now, reduce font against full layout font
font.reduce(layoutfont);
- par->setFont(pos, font);
+ pit->setFont(pos, font);
}
if (anchor_row_ == rit) {
if (rit != rows().begin()) {
anchor_row_ = boost::prior(rit);
- anchor_row_offset_ += boost::prior(rit)->height();
+ anchor_row_offset_ += anchor_row_->height();
} else {
anchor_row_ = boost::next(rit);
anchor_row_offset_ -= rit->height();
}
-#warning FIXME Convert this to ParagraphList::iterator
-void LyXText::insertParagraph(Paragraph * par, RowList::iterator rowit)
+void LyXText::insertParagraph(ParagraphList::iterator pit,
+ RowList::iterator rowit)
{
// insert a new row, starting at position 0
- Row newrow(par, 0);
+ Row newrow(pit, 0);
RowList::iterator rit = rowlist_.insert(rowit, newrow);
// and now append the whole paragraph before the new row
Inset * LyXText::getInset() const
{
- if (cursor.pos() < cursor.par()->size()
- && cursor.par()->isInset(cursor.pos())) {
- return cursor.par()->getInset(cursor.pos());
+ ParagraphList::iterator pit = cursor.par();
+ pos_type const pos = cursor.pos();
+
+ if (pos < pit->size() && pit->isInset(pos)) {
+ return pit->getInset(pos);
}
return 0;
}
// No, try to see if we are inside a collapsable inset
if (inset_owner && inset_owner->owner()
&& inset_owner->owner()->isOpen()) {
- bv()->unlockInset(static_cast<UpdatableInset *>(inset_owner->owner()));
+ bv()->unlockInset(inset_owner->owner());
inset_owner->owner()->close(bv());
bv()->getLyXText()->cursorRight(bv());
}
Paragraph & par)
{
LyXLayout_ptr const & layout = par.layout();
+ pos_type const psize = par.size();
LyXFont layoutfont;
- for (pos_type pos = 0; pos < par.size(); ++pos) {
+ for (pos_type pos = 0; pos < psize; ++pos) {
if (pos < par.beginningOfBody())
layoutfont = layout->labelfont;
else
}
-Paragraph * LyXText::setLayout(LyXCursor & cur, LyXCursor & sstart_cur,
- LyXCursor & send_cur,
- string const & layout)
+ParagraphList::iterator
+LyXText::setLayout(LyXCursor & cur, LyXCursor & sstart_cur,
+ LyXCursor & send_cur,
+ string const & layout)
{
- Paragraph * endpar = send_cur.par()->next();
- Paragraph * undoendpar = endpar;
+ ParagraphList::iterator endpit = boost::next(send_cur.par());
+ ParagraphList::iterator undoendpit = endpit;
+ ParagraphList::iterator pars_end = ownerParagraphs().end();
- if (endpar && endpar->getDepth()) {
- while (endpar && endpar->getDepth()) {
- endpar = endpar->next();
- undoendpar = endpar;
+ if (endpit != pars_end && endpit->getDepth()) {
+ while (endpit != pars_end && endpit->getDepth()) {
+ ++endpit;
+ undoendpit = endpit;
}
- } else if (endpar) {
- endpar = endpar->next(); // because of parindents etc.
+ } else if (endpit != pars_end) {
+ // because of parindents etc.
+ ++endpit;
}
- setUndo(bv(), Undo::EDIT, sstart_cur.par(), undoendpar);
+ setUndo(bv(), Undo::EDIT, sstart_cur.par(), boost::prior(undoendpit));
// ok we have a selection. This is always between sstart_cur
// and sel_end cursor
cur = sstart_cur;
- Paragraph * par = sstart_cur.par();
- Paragraph * epar = send_cur.par()->next();
+ ParagraphList::iterator pit = sstart_cur.par();
+ ParagraphList::iterator epit = boost::next(send_cur.par());
LyXLayout_ptr const & lyxlayout =
bv()->buffer()->params.getLyXTextClass()[layout];
do {
- par->applyLayout(lyxlayout);
- makeFontEntriesLayoutSpecific(*bv()->buffer(), *par);
- Paragraph * fppar = par;
- fppar->params().spaceTop(lyxlayout->fill_top ?
+ pit->applyLayout(lyxlayout);
+ makeFontEntriesLayoutSpecific(*bv()->buffer(), *pit);
+ ParagraphList::iterator fppit = pit;
+ fppit->params().spaceTop(lyxlayout->fill_top ?
VSpace(VSpace::VFILL)
: VSpace(VSpace::NONE));
- fppar->params().spaceBottom(lyxlayout->fill_bottom ?
+ fppit->params().spaceBottom(lyxlayout->fill_bottom ?
VSpace(VSpace::VFILL)
: VSpace(VSpace::NONE));
if (lyxlayout->margintype == MARGIN_MANUAL)
- par->setLabelWidthString(lyxlayout->labelstring());
- cur.par(par);
- par = par->next();
- } while (par != epar);
+ pit->setLabelWidthString(lyxlayout->labelstring());
+ cur.par(pit);
+ ++pit;
+ } while (pit != epit);
- return endpar;
+ return endpit;
}
// set layout over selection and make a total rebreak of those paragraphs
void LyXText::setLayout(string const & layout)
{
- LyXCursor tmpcursor = cursor; /* store the current cursor */
+ LyXCursor tmpcursor = cursor; // store the current cursor
// if there is no selection just set the layout
- // of the current paragraph */
+ // of the current paragraph
if (!selection.set()) {
selection.start = cursor; // dummy selection
selection.end = cursor;
}
- Paragraph * endpar = setLayout(cursor, selection.start,
- selection.end, layout);
- redoParagraphs(selection.start, endpar);
+
+ // special handling of new environment insets
+ BufferParams const & params = bv()->buffer()->params;
+ LyXLayout_ptr const & lyxlayout = params.getLyXTextClass()[layout];
+ if (lyxlayout->is_environment) {
+ // move everything in a new environment inset
+ lyxerr << "setting layout " << layout << endl;
+ bv()->owner()->dispatch(FuncRequest(LFUN_HOME));
+ bv()->owner()->dispatch(FuncRequest(LFUN_ENDSEL));
+ bv()->owner()->dispatch(FuncRequest(LFUN_CUT));
+ Inset * inset = new InsetEnvironment(params, layout);
+ if (bv()->insertInset(inset)) {
+ //inset->edit(bv());
+ //bv()->owner()->dispatch(FuncRequest(LFUN_PASTE));
+ }
+ else
+ delete inset;
+ return;
+ }
+
+ ParagraphList::iterator endpit = setLayout(cursor, selection.start,
+ selection.end, layout);
+ redoParagraphs(selection.start, endpit);
// we have to reset the selection, because the
// geometry could have changed
- setCursor(selection.start.par(),
- selection.start.pos(), false);
+ setCursor(selection.start.par(), selection.start.pos(), false);
selection.cursor = cursor;
setCursor(selection.end.par(), selection.end.pos(), false);
updateCounters();
start = pit;
}
- ParagraphList::iterator pastend = end;
- ++pastend;
- setUndo(bv(), Undo::EDIT, &(*start), &(*pastend));
+ ParagraphList::iterator pastend = boost::next(end);
+
+ if (!test_only)
+ setUndo(bv(), Undo::EDIT, start, end);
bool changed = false;
int prev_after_depth = 0;
#warning parlist ... could be nicer ?
- if (start != ownerParagraphs().begin())
+ if (start != ownerParagraphs().begin()) {
prev_after_depth = boost::prior(start)->getMaxDepthAfter();
+ }
while (true) {
int const depth = pit->params().depth();
if (depth < prev_after_depth
&& pit->layout()->labeltype != LABEL_BIBLIO) {
changed = true;
- if (!test_only)
+ if (!test_only) {
pit->params().depth(depth + 1);
+ }
+
}
} else if (depth) {
changed = true;
prev_after_depth = pit->getMaxDepthAfter();
- if (pit == end)
+ if (pit == end) {
break;
+ }
++pit;
}
// Wow, redoParagraphs is stupid.
LyXCursor tmpcursor;
- setCursor(tmpcursor, &(*start), 0);
- redoParagraphs(tmpcursor, &(*pastend));
+ setCursor(tmpcursor, start, 0);
+
+ //redoParagraphs(tmpcursor, &(*pastend));
+ redoParagraphs(tmpcursor, pastend);
// We need to actually move the text->cursor. I don't
// understand why ...
setCursor(selection.end.par(), selection.end.pos());
}
+ // this handles the counter labels, and also fixes up
+ // depth values for follow-on (child) paragraphs
updateCounters();
+
setSelection();
setCursor(tmpcursor.par(), tmpcursor.pos());
// ok we have a selection. This is always between sel_start_cursor
// and sel_end cursor
- setUndo(bv(), Undo::EDIT,
- selection.start.par(), selection.end.par()->next());
+ setUndo(bv(), Undo::EDIT, selection.start.par(), selection.end.par());
freezeUndo();
cursor = selection.start;
while (cursor.par() != selection.end.par() ||
cursor.pos(cursor.pos() + 1);
} else {
cursor.pos(0);
- cursor.par(cursor.par()->next());
+ cursor.par(boost::next(cursor.par()));
}
}
unFreezeUndo();
- redoParagraphs(selection.start, selection.end.par()->next());
+ redoParagraphs(selection.start, boost::next(selection.end.par()));
// we have to reset the selection, because the
// geometry could have changed, but we keep
}
-// deletes and inserts again all paragaphs between the cursor
+// deletes and inserts again all paragraphs between the cursor
// and the specified par
// This function is needed after SetLayout and SetFont etc.
void LyXText::redoParagraphs(LyXCursor const & cur,
- Paragraph const * ep)
+ ParagraphList::iterator endpit)
{
RowList::iterator tmprit = cur.row();
- ParagraphList::iterator endpit(const_cast<Paragraph*>(ep));
int y = cur.y() - tmprit->baseline();
ParagraphList::iterator first_phys_pit;
+ RowList::iterator prevrit;
if (tmprit == rows().begin()) {
// A trick/hack for UNDO.
// This is needed because in an UNDO/REDO we could have
- // changed the ownerParagrah() so the paragraph inside
+ // changed the ownerParagraph() so the paragraph inside
// the row is NOT my really first par anymore.
// Got it Lars ;) (Jug 20011206)
first_phys_pit = ownerParagraphs().begin();
-#warning FIXME
- // In here prevrit could be set to rows().end(). (Lgb)
+ prevrit = rows().end();
} else {
first_phys_pit = tmprit->par();
while (tmprit != rows().begin()
--tmprit;
y -= tmprit->height();
}
-#warning FIXME
- // Is it possible to put the prevrit setting in here? (Lgb)
- }
-
- RowList::iterator prevrit;
- bool good_prevrit = false;
-#warning FIXME
- // It seems to mee that good_prevrit is not needed if we let
- // a bad prevrit have the value rows().end() (Lgb)
- if (tmprit != rows().begin()) {
prevrit = boost::prior(tmprit);
- good_prevrit = true;
}
// remove it
// Reinsert the paragraphs.
ParagraphList::iterator tmppit = first_phys_pit;
-#warning FIXME
- // See if this loop can be rewritten as a while loop instead.
- // That should also make the code a bit easier to read. (Lgb)
- do {
- if (tmppit != ownerParagraphs().end()) {
- insertParagraph(&*tmppit, tmprit);
- while (tmprit != rows().end()
- && tmprit->par() == tmppit) {
- ++tmprit;
- }
- ++tmppit;
- }
- } while (tmppit != ownerParagraphs().end() && tmppit != endpit);
-#warning FIXME
- // If the above changes are done, then we can compare prevrit
- // with rows().end() here. (Lgb)
- if (good_prevrit) {
+ while (tmppit != ownerParagraphs().end()) {
+ insertParagraph(tmppit, tmprit);
+ while (tmprit != rows().end()
+ && tmprit->par() == tmppit) {
+ ++tmprit;
+ }
+ ++tmppit;
+ if (tmppit == endpit)
+ break;
+ }
+ if (prevrit != rows().end()) {
setHeightOfRow(prevrit);
- const_cast<LyXText *>(this)->postPaint(y - prevrit->height());
+ postPaint(y - prevrit->height());
} else {
setHeightOfRow(rows().begin());
- const_cast<LyXText *>(this)->postPaint(0);
+ postPaint(0);
}
if (tmprit != rows().end())
setHeightOfRow(tmprit);
+
updateCounters();
}
init(bv());
return;
}
- if (need_break_row != rows().end()) {
+
+ RowList::iterator rows_end = rows().end();
+
+ if (need_break_row != rows_end) {
breakAgain(need_break_row);
- need_break_row = rows().end();
+ need_break_row = rows_end;
return;
}
}
if (!selection.set()) return string();
// should be const ...
- Paragraph * startpar(selection.start.par());
- Paragraph * endpar(selection.end.par());
+ ParagraphList::iterator startpit = selection.start.par();
+ ParagraphList::iterator endpit = selection.end.par();
pos_type const startpos(selection.start.pos());
pos_type const endpos(selection.end.pos());
- if (startpar == endpar) {
- return startpar->asString(buffer, startpos, endpos, label);
+ if (startpit == endpit) {
+ return startpit->asString(buffer, startpos, endpos, label);
}
string result;
// First paragraph in selection
- result += startpar->asString(buffer, startpos, startpar->size(), label) + "\n\n";
+ result += startpit->asString(buffer, startpos, startpit->size(), label) + "\n\n";
// The paragraphs in between (if any)
- LyXCursor tmpcur(selection.start);
- tmpcur.par(tmpcur.par()->next());
- while (tmpcur.par() != endpar) {
- result += tmpcur.par()->asString(buffer, 0,
- tmpcur.par()->size(),
- label) + "\n\n";
- tmpcur.par(tmpcur.par()->next());
+ ParagraphList::iterator pit = boost::next(startpit);
+ for (; pit != endpit; ++pit) {
+ result += pit->asString(buffer, 0, pit->size(), label) + "\n\n";
}
// Last paragraph in selection
- result += endpar->asString(buffer, 0, endpos, label);
+ result += endpit->asString(buffer, 0, endpos, label);
return result;
}
{
if (cursor.par()->empty())
return;
-#warning FIXME
-// There is a lot of unneeded recalculation going on here:
-// - boost::next(curosr.row())
-// - lastPost(*this, cursor.row())
-
- if (boost::next(cursor.row()) == rows().end()
- || boost::next(cursor.row())->par() != cursor.row()->par()) {
- setCursor(cursor.par(), lastPos(*this, cursor.row()) + 1);
+
+ RowList::iterator rit = cursor.row();
+ RowList::iterator next_rit = boost::next(rit);
+ ParagraphList::iterator pit = rit->par();
+ pos_type last_pos = lastPos(*this, rit);
+
+ if (next_rit == rows().end() || next_rit->par() != pit) {
+ ++last_pos;
} else {
- if (!cursor.par()->empty() &&
- (cursor.par()->getChar(lastPos(*this, cursor.row())) == ' '
- || cursor.par()->isNewline(lastPos(*this, cursor.row())))) {
- setCursor(cursor.par(), lastPos(*this, cursor.row()));
- } else {
- setCursor(cursor.par(),
- lastPos(*this, cursor.row()) + 1);
+ if (pit->empty() ||
+ (pit->getChar(last_pos) != ' ' && !pit->isNewline(last_pos))) {
+ ++last_pos;
}
}
+
+ setCursor(pit, last_pos);
}
void LyXText::cursorTop()
{
- while (cursor.par()->previous())
- cursor.par(cursor.par()->previous());
- setCursor(cursor.par(), 0);
+ setCursor(ownerParagraphs().begin(), 0);
}
void LyXText::cursorBottom()
{
- while (cursor.par()->next())
- cursor.par(cursor.par()->next());
- setCursor(cursor.par(), cursor.par()->size());
+ ParagraphList::iterator lastpit =
+ boost::prior(ownerParagraphs().end());
+ setCursor(lastpit, lastpit->size());
}
}
// make sure that the depth behind the selection are restored, too
- Paragraph * endpar = selection.end.par()->next();
- Paragraph * undoendpar = endpar;
-
- if (endpar && endpar->getDepth()) {
- while (endpar && endpar->getDepth()) {
- endpar = endpar->next();
- undoendpar = endpar;
+ ParagraphList::iterator endpit = boost::next(selection.end.par());
+ ParagraphList::iterator undoendpit = endpit;
+ ParagraphList::iterator pars_end = ownerParagraphs().end();
+
+ if (endpit != pars_end && endpit->getDepth()) {
+ while (endpit != pars_end && endpit->getDepth()) {
+ ++endpit;
+ undoendpit = endpit;
}
- }
- else if (endpar) {
+ } else if (endpit != pars_end) {
// because of parindents etc.
- endpar = endpar->next();
+ ++endpit;
}
- setUndo(bv(), Undo::EDIT, selection.start.par(), undoendpar);
+ setUndo(bv(), Undo::EDIT, selection.start.par(),
+ boost::prior(undoendpit));
- Paragraph * tmppar = selection.end.par();
+ ParagraphList::iterator tmppit = selection.end.par();
- while (tmppar != selection.start.par()->previous()) {
- setCursor(tmppar, 0);
+ while (tmppit != boost::prior(selection.start.par())) {
+ setCursor(tmppit, 0);
postPaint(cursor.y() - cursor.row()->baseline());
- cursor.par()->params().lineTop(line_top);
- cursor.par()->params().lineBottom(line_bottom);
- cursor.par()->params().pagebreakTop(pagebreak_top);
- cursor.par()->params().pagebreakBottom(pagebreak_bottom);
- cursor.par()->params().spaceTop(space_top);
- cursor.par()->params().spaceBottom(space_bottom);
- cursor.par()->params().spacing(spacing);
+
+ ParagraphList::iterator pit = cursor.par();
+ ParagraphParameters & params = pit->params();
+
+ params.lineTop(line_top);
+ params.lineBottom(line_bottom);
+ params.pagebreakTop(pagebreak_top);
+ params.pagebreakBottom(pagebreak_bottom);
+ params.spaceTop(space_top);
+ params.spaceBottom(space_bottom);
+ params.spacing(spacing);
// does the layout allow the new alignment?
- LyXLayout_ptr const & layout = cursor.par()->layout();
+ LyXLayout_ptr const & layout = pit->layout();
if (align == LYX_ALIGN_LAYOUT)
align = layout->align;
if (align & layout->alignpossible) {
if (align == layout->align)
- cursor.par()->params().align(LYX_ALIGN_LAYOUT);
+ params.align(LYX_ALIGN_LAYOUT);
else
- cursor.par()->params().align(align);
+ params.align(align);
}
- cursor.par()->setLabelWidthString(labelwidthstring);
- cursor.par()->params().noindent(noindent);
- tmppar = cursor.par()->previous();
+ pit->setLabelWidthString(labelwidthstring);
+ params.noindent(noindent);
+ tmppit = boost::prior(pit);
}
- redoParagraphs(selection.start, endpar);
+ redoParagraphs(selection.start, endpit);
clearSelection();
setCursor(selection.start.par(), selection.start.pos());
// set the counter of a paragraph. This includes the labels
-void LyXText::setCounter(Buffer const * buf, Paragraph * par)
+void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit)
{
LyXTextClass const & textclass = buf->params.getLyXTextClass();
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
- if (par->previous()) {
+ if (pit != ownerParagraphs().begin()) {
- par->params().appendix(par->previous()->params().appendix());
- if (!par->params().appendix() && par->params().startOfAppendix()) {
- par->params().appendix(true);
+ pit->params().appendix(boost::prior(pit)->params().appendix());
+ if (!pit->params().appendix() &&
+ pit->params().startOfAppendix()) {
+ pit->params().appendix(true);
textclass.counters().reset();
}
- par->enumdepth = par->previous()->enumdepth;
- par->itemdepth = par->previous()->itemdepth;
+ pit->enumdepth = boost::prior(pit)->enumdepth;
+ pit->itemdepth = boost::prior(pit)->itemdepth;
} else {
- par->params().appendix(par->params().startOfAppendix());
- par->enumdepth = 0;
- par->itemdepth = 0;
+ pit->params().appendix(pit->params().startOfAppendix());
+ pit->enumdepth = 0;
+ pit->itemdepth = 0;
}
/* Maybe we have to increment the enumeration depth.
* AND, bibliographies can't have their depth changed ie. they
* are always of depth 0
*/
- if (par->previous()
- && par->previous()->getDepth() < par->getDepth()
- && par->previous()->layout()->labeltype == LABEL_COUNTER_ENUMI
- && par->enumdepth < 3
+ if (pit != ownerParagraphs().begin()
+ && boost::prior(pit)->getDepth() < pit->getDepth()
+ && boost::prior(pit)->layout()->labeltype == LABEL_COUNTER_ENUMI
+ && pit->enumdepth < 3
&& layout->labeltype != LABEL_BIBLIO) {
- par->enumdepth++;
+ pit->enumdepth++;
}
// Maybe we have to decrement the enumeration depth, see note above
- if (par->previous()
- && par->previous()->getDepth() > par->getDepth()
+ if (pit != ownerParagraphs().begin()
+ && boost::prior(pit)->getDepth() > pit->getDepth()
&& layout->labeltype != LABEL_BIBLIO) {
- par->enumdepth = par->depthHook(par->getDepth())->enumdepth;
+ pit->enumdepth = depthHook(pit, ownerParagraphs(),
+ pit->getDepth())->enumdepth;
}
- if (!par->params().labelString().empty()) {
- par->params().labelString(string());
+ if (!pit->params().labelString().empty()) {
+ pit->params().labelString(string());
}
if (layout->margintype == MARGIN_MANUAL) {
- if (par->params().labelWidthString().empty()) {
- par->setLabelWidthString(layout->labelstring());
+ if (pit->params().labelWidthString().empty()) {
+ pit->setLabelWidthString(layout->labelstring());
}
} else {
- par->setLabelWidthString(string());
+ pit->setLabelWidthString(string());
}
// is it a layout that has an automatic label?
textclass.counters().step(layout->latexname());
// Is there a label? Useful for Chapter layout
- if (!par->params().appendix()) {
- s << layout->labelstring();
+ if (!pit->params().appendix()) {
+ s << buf->B_(layout->labelstring());
} else {
- s << layout->labelstring_appendix();
+ s << buf->B_(layout->labelstring_appendix());
}
// Use of an integer is here less than elegant. For now.
int head = textclass.maxcounter() - LABEL_COUNTER_CHAPTER;
- if (!par->params().appendix()) {
+ if (!pit->params().appendix()) {
numbertype = "sectioning";
} else {
numbertype = "appendix";
- if (par->isRightToLeftPar(buf->params))
+ if (pit->isRightToLeftPar(buf->params))
langtype = "hebrew";
else
langtype = "latin";
}
- s << textclass.counters()
+ s << " "
+ << textclass.counters()
.numberLabel(layout->latexname(),
numbertype, langtype, head);
- par->params().labelString(STRCONV(s.str()));
+ pit->params().labelString(STRCONV(s.str()));
// reset enum counters
textclass.counters().reset("enum");
// (Lgb)
string enumcounter("enum");
- switch (par->enumdepth) {
+ switch (pit->enumdepth) {
case 2:
enumcounter += 'i';
case 1:
s << textclass.counters()
.numberLabel(enumcounter, "enumeration");
- par->params().labelString(STRCONV(s.str()));
+ pit->params().labelString(STRCONV(s.str()));
}
} else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
textclass.counters().step("bibitem");
int number = textclass.counters().value("bibitem");
- if (par->bibitem()) {
- par->bibitem()->setCounter(number);
- par->params().labelString(layout->labelstring());
+ if (pit->bibitem()) {
+ pit->bibitem()->setCounter(number);
+ pit->params().labelString(layout->labelstring());
}
// In biblio should't be following counters but...
} else {
- string s = layout->labelstring();
+ string s = buf->B_(layout->labelstring());
// the caption hack:
if (layout->labeltype == LABEL_SENSITIVE) {
- Paragraph * tmppar = par;
+ ParagraphList::iterator tmppit = pit;
Inset * in = 0;
bool isOK = false;
- while (tmppar && tmppar->inInset()
+ while (tmppit != ownerParagraphs().end() &&
+ tmppit->inInset()
// the single '=' is intended below
- && (in = tmppar->inInset()->owner())) {
+ && (in = tmppit->inInset()->owner())) {
if (in->lyxCode() == Inset::FLOAT_CODE ||
in->lyxCode() == Inset::WRAP_CODE) {
isOK = true;
break;
} else {
- tmppar = in->parOwner();
+ tmppit = std::find(ownerParagraphs().begin(), ownerParagraphs().end(), *in->parOwner());
}
}
if (isOK) {
- Floating const & fl
- = textclass.floats().getType(static_cast<InsetFloat*>(in)->type());
+ string type;
+
+ if (in->lyxCode() == Inset::FLOAT_CODE)
+ type = static_cast<InsetFloat*>(in)->params().type;
+ else if (in->lyxCode() == Inset::WRAP_CODE)
+ type = static_cast<InsetWrap*>(in)->params().type;
+ else
+ lyx::Assert(0);
+
+ Floating const & fl = textclass.floats().getType(type);
textclass.counters().step(fl.type());
// Doesn't work... yet.
-#if USE_BOOST_FORMAT
- s = boost::io::str(boost::format(_("%1$s #:")) % fl.name());
- // s << boost::format(_("%1$s %1$d:")
- // % fl.name()
- // % buf->counters().value(fl.name());
-#else
- ostringstream o;
- //o << fl.name() << ' ' << buf->counters().value(fl.name()) << ":";
- o << fl.name() << " #:";
- s = STRCONV(o.str());
-#endif
+ s = bformat(_("%1$s #:"), buf->B_(fl.name()));
} else {
// par->SetLayout(0);
// s = layout->labelstring;
s = _("Senseless: ");
}
}
- par->params().labelString(s);
+ pit->params().labelString(s);
// reset the enumeration counter. They are always reset
// when there is any other layout between
// Just fall-through between the cases so that all
// enum counters deeper than enumdepth is also reset.
- switch (par->enumdepth) {
+ switch (pit->enumdepth) {
case 0:
textclass.counters().reset("enumi");
case 1:
// CHECK if this is really needed. (Lgb)
bv()->buffer()->params.getLyXTextClass().counters().reset();
- while (pit != ownerParagraphs().end()) {
+ ParagraphList::iterator beg = ownerParagraphs().begin();
+ ParagraphList::iterator end = ownerParagraphs().end();
+ for (; pit != end; ++pit) {
while (rowit->par() != pit)
++rowit;
string const oldLabel = pit->params().labelString();
+ size_t maxdepth = 0;
+ if (pit != beg)
+ maxdepth = boost::prior(pit)->getMaxDepthAfter();
+
+ if (pit->params().depth() > maxdepth)
+ pit->params().depth(maxdepth);
+
// setCounter can potentially change the labelString.
- setCounter(bv()->buffer(), &*pit);
+ setCounter(bv()->buffer(), pit);
string const & newLabel = pit->params().labelString();
removeParagraph(rowit);
appendParagraph(rowit);
}
-
- ++pit;
}
}
{
if (!cursor.par()->insetAllowed(inset->lyxCode()))
return;
- setUndo(bv(), Undo::FINISH, cursor.par(), cursor.par()->next());
+ setUndo(bv(), Undo::FINISH, cursor.par());
freezeUndo();
cursor.par()->insertInset(cursor.pos(), inset);
// Just to rebreak and refresh correctly.
}
-void LyXText::copyEnvironmentType()
-{
- copylayouttype = cursor.par()->layout()->name();
-}
-
-
-void LyXText::pasteEnvironmentType()
-{
- // do nothing if there has been no previous copyEnvironmentType()
- if (!copylayouttype.empty())
- setLayout(copylayouttype);
-}
-
-
void LyXText::cutSelection(bool doclear, bool realcut)
{
// Stuff what we got on the clipboard. Even if there is no selection.
// and selection.end
// make sure that the depth behind the selection are restored, too
- Paragraph * endpar = selection.end.par()->next();
- Paragraph * undoendpar = endpar;
-
- if (endpar && endpar->getDepth()) {
- while (endpar && endpar->getDepth()) {
- endpar = endpar->next();
- undoendpar = endpar;
+ ParagraphList::iterator endpit = boost::next(selection.end.par());
+ ParagraphList::iterator undoendpit = endpit;
+ ParagraphList::iterator pars_end = ownerParagraphs().end();
+
+ if (endpit != pars_end && endpit->getDepth()) {
+ while (endpit != pars_end && endpit->getDepth()) {
+ ++endpit;
+ undoendpit = endpit;
}
- } else if (endpar) {
- endpar = endpar->next(); // because of parindents etc.
+ } else if (endpit != pars_end) {
+ // because of parindents etc.
+ ++endpit;
}
- setUndo(bv(), Undo::DELETE,
- selection.start.par(), undoendpar);
+ setUndo(bv(), Undo::DELETE, selection.start.par(),
+ boost::prior(undoendpit));
- // there are two cases: cut only within one paragraph or
- // more than one paragraph
- if (selection.start.par() == selection.end.par()) {
- // only within one paragraph
- endpar = selection.end.par();
- int pos = selection.end.pos();
- CutAndPaste::cutSelection(selection.start.par(), &endpar,
- selection.start.pos(), pos,
- bv()->buffer()->params.textclass,
- doclear, realcut);
- selection.end.pos(pos);
- } else {
- endpar = selection.end.par();
- int pos = selection.end.pos();
- CutAndPaste::cutSelection(selection.start.par(), &endpar,
- selection.start.pos(), pos,
- bv()->buffer()->params.textclass,
- doclear, realcut);
- cursor.par(endpar);
- selection.end.par(endpar);
- selection.end.pos(pos);
- cursor.pos(selection.end.pos());
- }
- endpar = endpar->next();
+ endpit = selection.end.par();
+ int endpos = selection.end.pos();
+
+ boost::tie(endpit, endpos) = realcut ?
+ CutAndPaste::cutSelection(bv()->buffer()->params,
+ ownerParagraphs(),
+ selection.start.par(), endpit,
+ selection.start.pos(), endpos,
+ bv()->buffer()->params.textclass,
+ doclear)
+ : CutAndPaste::eraseSelection(bv()->buffer()->params,
+ ownerParagraphs(),
+ selection.start.par(), endpit,
+ selection.start.pos(), endpos,
+ doclear);
// sometimes necessary
if (doclear)
selection.start.par()->stripLeadingSpaces();
- redoParagraphs(selection.start, endpar);
-
+ redoParagraphs(selection.start, boost::next(endpit));
+#warning FIXME latent bug
+ // endpit will be invalidated on redoParagraphs once ParagraphList
+ // becomes a std::list? There are maybe other places on which this
+ // can happend? (Ab)
// cutSelection can invalidate the cursor so we need to set
// it anew. (Lgb)
// we prefer the end for when tracking changes
- cursor = selection.end;
+ cursor.pos(endpos);
+ cursor.par(endpit);
// need a valid cursor. (Lgb)
clearSelection();
|| selection.start.pos() < selection.end.pos()))
selection.start.pos(selection.start.pos() + 1);
- CutAndPaste::copySelection(selection.start.par(), selection.end.par(),
+ CutAndPaste::copySelection(selection.start.par(),
+ selection.end.par(),
selection.start.pos(), selection.end.pos(),
bv()->buffer()->params.textclass);
}
-void LyXText::pasteSelection()
+void LyXText::pasteSelection(size_t sel_index)
{
// this does not make sense, if there is nothing to paste
if (!CutAndPaste::checkPastePossible())
return;
- setUndo(bv(), Undo::INSERT,
- cursor.par(), cursor.par()->next());
+ setUndo(bv(), Undo::INSERT, cursor.par());
+
+ ParagraphList::iterator endpit;
+ PitPosPair ppp;
- Paragraph * endpar;
- Paragraph * actpar = cursor.par();
- int pos = cursor.pos();
+ ErrorList el;
- CutAndPaste::pasteSelection(&actpar, &endpar, pos,
- bv()->buffer()->params.textclass);
+ boost::tie(ppp, endpit) =
+ CutAndPaste::pasteSelection(*bv()->buffer(),
+ ownerParagraphs(),
+ cursor.par(), cursor.pos(),
+ bv()->buffer()->params.textclass,
+ sel_index, el);
+ bv()->setErrorList(el);
+ bv()->showErrorList(_("Paste"));
- redoParagraphs(cursor, endpar);
+ redoParagraphs(cursor, endpit);
setCursor(cursor.par(), cursor.pos());
clearSelection();
selection.cursor = cursor;
- setCursor(actpar, pos);
+ setCursor(ppp.first, ppp.second);
setSelection();
updateCounters();
}
selection.start.pos());
// Insert the new string
- for (string::const_iterator cit = str.begin(); cit != str.end(); ++cit) {
+ string::const_iterator cit = str.begin();
+ string::const_iterator end = str.end();
+ for (; cit != end; ++cit) {
selection.end.par()->insertChar(pos, (*cit), font);
++pos;
}
// needed to insert the selection
void LyXText::insertStringAsLines(string const & str)
{
- Paragraph * par = cursor.par();
+ ParagraphList::iterator pit = cursor.par();
pos_type pos = cursor.pos();
- Paragraph * endpar = cursor.par()->next();
+ ParagraphList::iterator endpit = boost::next(cursor.par());
setCursorParUndo(bv());
// only to be sure, should not be neccessary
clearSelection();
- bv()->buffer()->insertStringAsLines(par, pos, current_font, str);
+ bv()->buffer()->insertStringAsLines(pit, pos, current_font, str);
- redoParagraphs(cursor, endpar);
+ redoParagraphs(cursor, endpit);
setCursor(cursor.par(), cursor.pos());
selection.cursor = cursor;
- setCursor(par, pos);
+ setCursor(pit, pos);
setSelection();
}
{
string linestr(str);
bool newline_inserted = false;
- for (string::size_type i = 0; i < linestr.length(); ++i) {
+ string::size_type const siz = linestr.length();
+
+ for (string::size_type i = 0; i < siz; ++i) {
if (linestr[i] == '\n') {
if (newline_inserted) {
// we know that \r will be ignored by
}
-void LyXText::checkParagraph(Paragraph * par, pos_type pos)
+void LyXText::checkParagraph(ParagraphList::iterator pit, pos_type pos)
{
LyXCursor tmpcursor;
int y = 0;
pos_type z;
- RowList::iterator row = getRow(par, pos, y);
+ RowList::iterator row = getRow(pit, pos, y);
RowList::iterator beg = rows().begin();
// is there a break one row above
}
// check the special right address boxes
- if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
- tmpcursor.par(par);
+ if (pit->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+ tmpcursor.par(pit);
tmpcursor.row(row);
tmpcursor.y(y);
tmpcursor.x(0);
ParagraphList::iterator par = ownerParagraphs().begin();
ParagraphList::iterator end = ownerParagraphs().end();
-
- do {
+ for (; par != end; ++par) {
pos = par->getPositionOfInset(inset);
if (pos != -1) {
- checkParagraph(&*par, pos);
+ checkParagraph(par, pos);
return true;
}
- ++par;
- } while (par != end);
+ };
return false;
}
-bool LyXText::setCursor(Paragraph * par,
+bool LyXText::setCursor(ParagraphList::iterator pit,
pos_type pos,
bool setfont, bool boundary)
{
LyXCursor old_cursor = cursor;
- setCursorIntern(par, pos, setfont, boundary);
+ setCursorIntern(pit, pos, setfont, boundary);
return deleteEmptyParagraphMechanism(old_cursor);
}
-void LyXText::setCursor(LyXCursor & cur, Paragraph * par,
+void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit,
pos_type pos, bool boundary)
{
- lyx::Assert(par);
+ lyx::Assert(pit != ownerParagraphs().end());
- cur.par(par);
+ cur.par(pit);
cur.pos(pos);
cur.boundary(boundary);
// get the cursor y position in text
int y = 0;
- RowList::iterator row = getRow(par, pos, y);
+ RowList::iterator row = getRow(pit, pos, y);
RowList::iterator beg = rows().begin();
RowList::iterator old_row = row;
// same paragraph and there is a previous row then put the cursor on
// the end of the previous row
cur.iy(y + row->baseline());
- Inset * ins;
- if (row != beg && pos &&
- boost::prior(row)->par() == row->par() &&
- pos < par->size() &&
- par->getChar(pos) == Paragraph::META_INSET &&
- (ins = par->getInset(pos)) && (ins->needFullRow() || ins->display()))
- {
- --row;
- y -= row->height();
+ if (row != beg &&
+ pos &&
+ boost::prior(row)->par() == row->par() &&
+ pos < pit->size() &&
+ pit->getChar(pos) == Paragraph::META_INSET) {
+ Inset * ins = pit->getInset(pos);
+ if (ins && (ins->needFullRow() || ins->display())) {
+ --row;
+ y -= row->height();
+ }
}
cur.row(row);
pos_type last = lastPrintablePos(*this, old_row);
// None of these should happen, but we're scaredy-cats
- if (pos > par->size()) {
+ if (pos > pit->size()) {
lyxerr << "dont like 1 please report" << endl;
pos = 0;
cur.pos(0);
cur.ix(int(x));
} else
cur.ix(cur.x());
-/* We take out this for the time being because 1) the redraw code is not
+/* We take out this for the time being because 1) the redraw code is not
prepared to this yet and 2) because some good policy has yet to be decided
while editting: for instance how to act on rows being created/deleted
because of DEPM.
-*/
+*/
#if 0
//if the cursor is in a visible row, anchor to it
int topy = top_y();
prepareToPrint(rit, x, fill_separator, fill_hfill,
fill_label_hfill);
- if (last < rit->pos())
- cursor_vpos = rit->pos();
+ ParagraphList::iterator rit_par = rit->par();
+ pos_type const rit_pos = rit->pos();
+
+ if (last < rit_pos)
+ cursor_vpos = rit_pos;
else if (pos > last && !boundary)
- cursor_vpos = (rit->par()->isRightToLeftPar(bv()->buffer()->params))
- ? rit->pos() : last + 1;
- else if (pos > rit->pos() &&
- (pos > last || boundary))
+ cursor_vpos = (rit_par->isRightToLeftPar(bv()->buffer()->params))
+ ? rit_pos : last + 1;
+ else if (pos > rit_pos && (pos > last || boundary))
/// Place cursor after char at (logical) position pos - 1
cursor_vpos = (bidi_level(pos - 1) % 2 == 0)
? log2vis(pos - 1) + 1 : log2vis(pos - 1);
cursor_vpos = (bidi_level(pos) % 2 == 0)
? log2vis(pos) : log2vis(pos) + 1;
- pos_type body_pos = rit->par()->beginningOfBody();
+ pos_type body_pos = rit_par->beginningOfBody();
if ((body_pos > 0) &&
- ((body_pos - 1 > last) ||
- !rit->par()->isLineSeparator(body_pos - 1)))
+ ((body_pos - 1 > last) || !rit_par->isLineSeparator(body_pos - 1)))
body_pos = 0;
- for (pos_type vpos = rit->pos(); vpos < cursor_vpos; ++vpos) {
+ for (pos_type vpos = rit_pos; vpos < cursor_vpos; ++vpos) {
pos_type pos = vis2log(vpos);
if (body_pos > 0 && pos == body_pos - 1) {
x += fill_label_hfill +
font_metrics::width(
- rit->par()->layout()->labelsep,
- getLabelFont(bv()->buffer(),
- &*rit->par()));
- if (rit->par()->isLineSeparator(body_pos - 1))
- x -= singleWidth(&*rit->par(), body_pos - 1);
+ rit_par->layout()->labelsep,
+ getLabelFont(bv()->buffer(), rit_par));
+ if (rit_par->isLineSeparator(body_pos - 1))
+ x -= singleWidth(rit_par, body_pos - 1);
}
if (hfillExpansion(*this, rit, pos)) {
- x += singleWidth(&*rit->par(), pos);
+ x += singleWidth(rit_par, pos);
if (pos >= body_pos)
x += fill_hfill;
else
x += fill_label_hfill;
- } else if (rit->par()->isSeparator(pos)) {
- x += singleWidth(&*rit->par(), pos);
+ } else if (rit_par->isSeparator(pos)) {
+ x += singleWidth(rit_par, pos);
if (pos >= body_pos)
x += fill_separator;
} else
- x += singleWidth(&*rit->par(), pos);
+ x += singleWidth(rit_par, pos);
}
return x;
}
-void LyXText::setCursorIntern(Paragraph * par,
+void LyXText::setCursorIntern(ParagraphList::iterator pit,
pos_type pos, bool setfont, bool boundary)
{
- InsetText * it = static_cast<InsetText *>(par->inInset());
+ UpdatableInset * it = pit->inInset();
if (it) {
if (it != inset_owner) {
lyxerr[Debug::INSETS] << "InsetText is " << it
}
}
- setCursor(cursor, par, pos, boundary);
+ setCursor(cursor, pit, pos, boundary);
if (setfont)
setCurrentFont();
}
void LyXText::setCurrentFont()
{
pos_type pos = cursor.pos();
+ ParagraphList::iterator pit = cursor.par();
+
if (cursor.boundary() && pos > 0)
--pos;
if (pos > 0) {
- if (pos == cursor.par()->size())
+ if (pos == pit->size())
--pos;
else // potentional bug... BUG (Lgb)
- if (cursor.par()->isSeparator(pos)) {
+ if (pit->isSeparator(pos)) {
if (pos > cursor.row()->pos() &&
bidi_level(pos) % 2 ==
bidi_level(pos - 1) % 2)
--pos;
- else if (pos + 1 < cursor.par()->size())
+ else if (pos + 1 < pit->size())
++pos;
}
}
current_font =
- cursor.par()->getFontSettings(bv()->buffer()->params, pos);
- real_current_font = getFont(bv()->buffer(), cursor.par(), pos);
+ pit->getFontSettings(bv()->buffer()->params, pos);
+ real_current_font = getFont(bv()->buffer(), pit, pos);
- if (cursor.pos() == cursor.par()->size() &&
- isBoundary(bv()->buffer(), cursor.par(), cursor.pos()) &&
+ if (cursor.pos() == pit->size() &&
+ isBoundary(bv()->buffer(), *pit, cursor.pos()) &&
!cursor.boundary()) {
Language const * lang =
- cursor.par()->getParLanguage(bv()->buffer()->params);
+ pit->getParLanguage(bv()->buffer()->params);
current_font.setLanguage(lang);
current_font.setNumber(LyXFont::OFF);
real_current_font.setLanguage(lang);
pos_type last = lastPrintablePos(*this, rit);
pos_type c = 0;
+ ParagraphList::iterator rit_par = rit->par();
LyXLayout_ptr const & layout = rit->par()->layout();
bool left_side = false;
- pos_type body_pos = rit->par()->beginningOfBody();
+ pos_type body_pos = rit_par->beginningOfBody();
float last_tmpx = tmpx;
if (body_pos > 0 &&
(body_pos - 1 > last ||
- !rit->par()->isLineSeparator(body_pos - 1)))
+ !rit_par->isLineSeparator(body_pos - 1)))
body_pos = 0;
// check for empty row
- if (!rit->par()->size()) {
+ if (!rit_par->size()) {
x = int(tmpx);
return 0;
}
if (body_pos > 0 && c == body_pos - 1) {
tmpx += fill_label_hfill +
font_metrics::width(layout->labelsep,
- getLabelFont(bv()->buffer(), &*rit->par()));
- if (rit->par()->isLineSeparator(body_pos - 1))
- tmpx -= singleWidth(&*rit->par(), body_pos - 1);
+ getLabelFont(bv()->buffer(), rit_par));
+ if (rit_par->isLineSeparator(body_pos - 1))
+ tmpx -= singleWidth(rit_par, body_pos - 1);
}
if (hfillExpansion(*this, rit, c)) {
- tmpx += singleWidth(&*rit->par(), c);
+ tmpx += singleWidth(rit_par, c);
if (c >= body_pos)
tmpx += fill_hfill;
else
tmpx += fill_label_hfill;
- } else if (rit->par()->isSeparator(c)) {
- tmpx += singleWidth(&*rit->par(), c);
+ } else if (rit_par->isSeparator(c)) {
+ tmpx += singleWidth(rit_par, c);
if (c >= body_pos)
tmpx+= fill_separator;
} else {
- tmpx += singleWidth(&*rit->par(), c);
+ tmpx += singleWidth(rit_par, c);
}
++vc;
}
boundary = false;
// This (rtl_support test) is not needed, but gives
// some speedup if rtl_support=false
+ RowList::iterator next_rit = boost::next(rit);
+
bool const lastrow = lyxrc.rtl_support &&
- (boost::next(rit) == rowlist_.end() ||
- boost::next(rit)->par() != rit->par());
+ (next_rit == rowlist_.end() ||
+ next_rit->par() != rit_par);
+
// If lastrow is false, we don't need to compute
// the value of rtl.
bool const rtl = (lastrow)
- ? rit->par()->isRightToLeftPar(bv()->buffer()->params)
+ ? rit_par->isRightToLeftPar(bv()->buffer()->params)
: false;
if (lastrow &&
((rtl && left_side && vc == rit->pos() && x < tmpx - 5) ||
bool const rtl = (bidi_level(c) % 2 == 1);
if (left_side == rtl) {
++c;
- boundary = isBoundary(bv()->buffer(), &*rit->par(), c);
+ boundary = isBoundary(bv()->buffer(), *rit_par, c);
}
}
if (rit->pos() <= last && c > last
- && rit->par()->isNewline(last)) {
+ && rit_par->isNewline(last)) {
if (bidi_level(last) % 2 == 0)
- tmpx -= singleWidth(&*rit->par(), last);
+ tmpx -= singleWidth(rit_par, last);
else
- tmpx += singleWidth(&*rit->par(), last);
+ tmpx += singleWidth(rit_par, last);
c = last;
}
* and the next row is filled by an inset that spans an entire
* row.
*/
- bool beforeFullRowInset(LyXText & lt, RowList::iterator row,
- LyXCursor & cur) {
+ bool beforeFullRowInset(LyXText & lt, LyXCursor const & cur)
+ {
+ RowList::iterator row = cur.row();
if (boost::next(row) == lt.rows().end())
return false;
+
Row const & next = *boost::next(row);
if (next.pos() != cur.pos() || next.par() != cur.par())
return false;
- if (!cur.par()->isInset(cur.pos()))
+
+ if (cur.pos() == cur.par()->size()
+ || !cur.par()->isInset(cur.pos()))
return false;
+
Inset const * inset = cur.par()->getInset(cur.pos());
if (inset->needFullRow() || inset->display())
return true;
+
return false;
}
}
RowList::iterator row = getRowNearY(y);
bool bound = false;
pos_type const column = getColumnNearX(row, x, bound);
- cur.par(&*row->par());
+ cur.par(row->par());
cur.pos(row->pos() + column);
cur.x(x);
cur.y(y + row->baseline());
cur.row(row);
- if (beforeFullRowInset(*this, row, cur)) {
- pos_type last = lastPrintablePos(*this, row);
- float x = getCursorX(boost::next(row), cur.pos(), last, bound);
+ if (beforeFullRowInset(*this, cur)) {
+ pos_type const last = lastPrintablePos(*this, row);
+ RowList::iterator next_row = boost::next(row);
+
+ float x = getCursorX(next_row, cur.pos(), last, bound);
cur.ix(int(x));
- cur.iy(y + row->height() + boost::next(row)->baseline());
- cur.irow(boost::next(row));
+ cur.iy(y + row->height() + next_row->baseline());
+ cur.irow(next_row);
} else {
cur.iy(cur.y());
cur.ix(cur.x());
bool boundary = cursor.boundary();
setCursor(cursor.par(), cursor.pos() - 1, true, false);
if (!internal && !boundary &&
- isBoundary(bv()->buffer(), cursor.par(), cursor.pos() + 1))
+ isBoundary(bv()->buffer(), *cursor.par(), cursor.pos() + 1))
setCursor(cursor.par(), cursor.pos() + 1, true, true);
- } else if (cursor.par()->previous()) { // steps into the above paragraph.
- Paragraph * par = cursor.par()->previous();
- setCursor(par, par->size());
+ } else if (cursor.par() != ownerParagraphs().begin()) { // steps into the above paragraph.
+ ParagraphList::iterator pit = boost::prior(cursor.par());
+ setCursor(pit, pit->size());
}
}
void LyXText::cursorRight(bool internal)
{
- if (!internal && cursor.boundary() &&
- !cursor.par()->isNewline(cursor.pos()))
+ bool const at_end = (cursor.pos() == cursor.par()->size());
+ bool const at_newline = !at_end &&
+ cursor.par()->isNewline(cursor.pos());
+
+ if (!internal && cursor.boundary() && !at_newline)
setCursor(cursor.par(), cursor.pos(), true, false);
- else if (cursor.pos() < cursor.par()->size()) {
+ else if (!at_end) {
setCursor(cursor.par(), cursor.pos() + 1, true, false);
if (!internal &&
- isBoundary(bv()->buffer(), cursor.par(), cursor.pos()))
+ isBoundary(bv()->buffer(), *cursor.par(), cursor.pos()))
setCursor(cursor.par(), cursor.pos(), true, true);
- } else if (cursor.par()->next())
- setCursor(cursor.par()->next(), 0);
+ } else if (boost::next(cursor.par()) != ownerParagraphs().end())
+ setCursor(boost::next(cursor.par()), 0);
}
y -= topy;
Inset * inset_hit = checkInsetHit(x, y1);
if (inset_hit && isHighlyEditableInset(inset_hit)) {
- inset_hit->edit(bv(), x, y - (y2 - y1), mouse_button::none);
+ inset_hit->localDispatch(
+ FuncRequest(bv(), LFUN_INSET_EDIT, x, y - (y2 - y1), mouse_button::none));
}
}
#else
y -= topy;
Inset * inset_hit = checkInsetHit(x, y1);
if (inset_hit && isHighlyEditableInset(inset_hit)) {
- inset_hit->edit(bv(), x, y - (y2 - y1), mouse_button::none);
+ FuncRequest cmd(bv(), LFUN_INSET_EDIT, x, y - (y2 - y1), mouse_button::none);
+ inset_hit->localDispatch(cmd);
}
}
#else
if (cursor.pos() > 0) {
setCursor(cursor.par(), 0);
}
- else if (cursor.par()->previous()) {
- setCursor(cursor.par()->previous(), 0);
+ else if (cursor.par() != ownerParagraphs().begin()) {
+ setCursor(boost::prior(cursor.par()), 0);
}
}
void LyXText::cursorDownParagraph()
{
- if (cursor.par()->next()) {
- setCursor(cursor.par()->next(), 0);
+ ParagraphList::iterator par = cursor.par();
+ ParagraphList::iterator next_par = boost::next(par);
+
+ if (next_par != ownerParagraphs().end()) {
+ setCursor(next_par, 0);
} else {
- setCursor(cursor.par(), cursor.par()->size());
+ setCursor(par, par->size());
}
}
&& old_cursor.par()->isLineSeparator(old_cursor.pos())
&& old_cursor.par()->isLineSeparator(old_cursor.pos() - 1)) {
old_cursor.par()->erase(old_cursor.pos() - 1);
- redoParagraphs(old_cursor, old_cursor.par()->next());
+ redoParagraphs(old_cursor, boost::next(old_cursor.par()));
#ifdef WITH_WARNINGS
#warning This will not work anymore when we have multiple views of the same buffer
}
// don't delete anything if this is the ONLY paragraph!
- if (!old_cursor.par()->next() && !old_cursor.par()->previous())
+ if (ownerParagraphs().size() == 1)
return false;
// Do not delete empty paragraphs with keepempty set.
- if (old_cursor.par()->layout()->keepempty)
+ if (old_cursor.par()->allowEmpty())
return false;
// only do our magic if we changed paragraph
// we can't possibly have deleted a paragraph before this point
bool deleted = false;
- if ((old_cursor.par()->empty()
- || (old_cursor.par()->size() == 1
- && old_cursor.par()->isLineSeparator(0)))) {
+ if (old_cursor.par()->empty() ||
+ (old_cursor.par()->size() == 1 &&
+ old_cursor.par()->isLineSeparator(0))) {
// ok, we will delete anything
LyXCursor tmpcursor;
deleted = true;
+ bool selection_position_was_oldcursor_position = (
+ selection.cursor.par() == old_cursor.par()
+ && selection.cursor.pos() == old_cursor.pos());
+
if (old_cursor.row() != rows().begin()) {
- RowList::iterator
+ RowList::iterator
prevrow = boost::prior(old_cursor.row());
const_cast<LyXText *>(this)->postPaint(old_cursor.y() - old_cursor.row()->baseline() - prevrow->height());
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
- Paragraph * endpar = old_cursor.par()->next();
- if (endpar && endpar->getDepth()) {
- while (endpar && endpar->getDepth()) {
- endpar = endpar->next();
- }
+ #warning FIXME. --end() iterator is usable here
+ ParagraphList::iterator endpit = boost::next(old_cursor.par());
+ while (endpit != ownerParagraphs().end() &&
+ endpit->getDepth()) {
+ ++endpit;
}
- setUndo(bv(), Undo::DELETE, old_cursor.par(), endpar);
+
+ setUndo(bv(), Undo::DELETE, old_cursor.par(),
+ boost::prior(endpit));
cursor = tmpcursor;
// delete old row
removeRow(old_cursor.row());
- if (ownerParagraphs().begin() == old_cursor.par()) {
- ownerParagraph(&*boost::next(ownerParagraphs().begin()));
- }
// delete old par
- delete old_cursor.par();
+ ownerParagraphs().erase(old_cursor.par());
/* Breakagain the next par. Needed because of
* the parindent that can occur or dissappear.
* The next row can change its height, if
* there is another layout before */
- if (boost::next(prevrow) != rows().end()) {
- breakAgain(boost::next(prevrow));
+ RowList::iterator tmprit = boost::next(prevrow);
+ if (tmprit != rows().end()) {
+ breakAgain(tmprit);
updateCounters();
}
setHeightOfRow(prevrow);
tmpcursor = cursor;
cursor = old_cursor; // that undo can restore the right cursor position
- Paragraph * endpar = old_cursor.par()->next();
- if (endpar && endpar->getDepth()) {
- while (endpar && endpar->getDepth()) {
- endpar = endpar->next();
- }
+#warning FIXME. --end() iterator is usable here
+ ParagraphList::iterator endpit = boost::next(old_cursor.par());
+ while (endpit != ownerParagraphs().end() &&
+ endpit->getDepth()) {
+ ++endpit;
}
- setUndo(bv(), Undo::DELETE, old_cursor.par(), endpar);
+
+ setUndo(bv(), Undo::DELETE, old_cursor.par(), boost::prior(endpit));
cursor = tmpcursor;
// delete old row
removeRow(old_cursor.row());
// delete old par
- if (ownerParagraphs().begin() == old_cursor.par()) {
- ownerParagraph(&*boost::next(ownerParagraphs().begin()));
- }
-
- delete old_cursor.par();
+ ownerParagraphs().erase(old_cursor.par());
/* Breakagain the next par. Needed because of
the parindent that can occur or dissappear.
// correct cursor y
setCursorIntern(cursor.par(), cursor.pos());
- if (selection.cursor.par() == old_cursor.par()
- && selection.cursor.pos() == old_cursor.pos()) {
+ if (selection_position_was_oldcursor_position) {
// correct selection
selection.cursor = cursor;
}
}
if (!deleted) {
if (old_cursor.par()->stripLeadingSpaces()) {
- redoParagraphs(old_cursor,
- old_cursor.par()->next());
+ redoParagraphs(old_cursor, boost::next(old_cursor.par()));
// correct cursor y
setCursorIntern(cursor.par(), cursor.pos());
selection.cursor = cursor;
}
-void LyXText::ownerParagraph(Paragraph * p) const
-{
- if (inset_owner) {
- inset_owner->paragraph(p);
- } else {
- bv_owner->buffer()->paragraphs.set(p);
- }
-}
-
-
-void LyXText::ownerParagraph(int id, Paragraph * p) const
-{
- Paragraph * op = bv_owner->buffer()->getParFromID(id);
- if (op && op->inInset()) {
- static_cast<InsetText *>(op->inInset())->paragraph(p);
- } else {
- ownerParagraph(p);
- }
-}
-
-
LyXText::refresh_status LyXText::refreshStatus() const
{
return refresh_status_;