#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 "buffer_funcs.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 "metricsinfo.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>
+
+#include <algorithm>
+
+using namespace lyx::support;
using std::vector;
using std::copy;
inset_owner(0), the_locking_inset(0), bv_owner(bv)
{
anchor_row_ = rows().end();
- need_break_row = rows().end();
- refresh_row = rows().end();
-
- clearPaint();
+ need_refresh_ = true;
}
inset_owner(inset), the_locking_inset(0), bv_owner(bv)
{
anchor_row_ = rows().end();
- need_break_row = rows().end();
- refresh_row = rows().end();
-
- clearPaint();
+ need_refresh_ = true;
}
-void LyXText::init(BufferView * bview, bool reinit)
+void LyXText::init(BufferView * bview)
{
- if (reinit) {
- 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 end = ownerParagraphs().end();
-
- current_font = getFont(bview->buffer(), &*par, 0);
-
- for (; par != end; ++par) {
- insertParagraph(&*par, rowlist_.end());
- }
- setCursorIntern(&*rowlist_.begin()->par(), 0);
- selection.cursor = cursor;
-
- updateCounters();
-}
+ bv_owner = bview;
+ rowlist_.clear();
+ width = height = 0;
+ need_refresh_ = true;
-namespace {
+ anchor_row_ = rows().end();
+ anchor_row_offset_ = 0;
-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();
+ ParagraphList::iterator pit = ownerParagraphs().begin();
+ ParagraphList::iterator end = ownerParagraphs().end();
- // 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();
- }
- }
+ current_font = getFont(pit, 0);
- tmpfont.realize(tclass.defaultfont());
+ for (; pit != end; ++pit)
+ insertParagraph(pit, rowlist_.end());
- return tmpfont;
-}
+ setCursorIntern(rowlist_.begin()->par(), 0);
+ selection.cursor = cursor;
+ updateCounters();
}
// 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,
- pos_type pos) const
+LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const
{
- lyx::Assert(pos >= 0);
+ Assert(pos >= 0);
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = pit->layout();
+#warning broken?
+ BufferParams const & params = bv()->buffer()->params;
// 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(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(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(params, pos);
tmpfont.realize(layoutfont);
- if (par->inInset())
- par->inInset()->getDrawFont(tmpfont);
+ if (pit->inInset())
+ pit->inInset()->getDrawFont(tmpfont);
- return realizeFont(tmpfont, buf, par);
+ // Realize with the fonts of lesser depth.
+ tmpfont.realize(outerFont(pit, ownerParagraphs()));
+ //tmpfont.realize(defaultfont_);
+
+ return tmpfont;
}
-LyXFont const LyXText::getLayoutFont(Buffer const * buf, Paragraph * par) const
+LyXFont LyXText::getLayoutFont(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()));
+ //font.realize(defaultfont_);
+
+ return font;
}
-LyXFont const LyXText::getLabelFont(Buffer const * buf, Paragraph * par) const
+LyXFont LyXText::getLabelFont(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()));
+ //font.realize(defaultfont_);
+
+ return font;
}
-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);
- font.update(fnt, buf->params.language, toggleall);
+ BufferParams const & params = bv()->buffer()->params;
+ LyXFont font = getFont(pit, pos);
+ font.update(fnt, params.language, toggleall);
// Let the insets convert their font
- if (par->isInset(pos)) {
- Inset * inset = par->getInset(pos);
+ if (pit->isInset(pos)) {
+ InsetOld * inset = pit->getInset(pos);
if (isEditableInset(inset)) {
- UpdatableInset * uinset =
- static_cast<UpdatableInset *>(inset);
- uinset->setFont(bv(), fnt, toggleall, true);
+ static_cast<UpdatableInset *>(inset)
+ ->setFont(bv(), fnt, toggleall, true);
}
}
- // Plug thru to version below:
- setCharFont(buf, par, pos, font);
+ // Plug through to version below:
+ setCharFont(pit, pos, font);
}
-void LyXText::setCharFont(Buffer const * buf, Paragraph * par,
- pos_type pos, LyXFont const & fnt)
+void LyXText::setCharFont(
+ ParagraphList::iterator pit, pos_type pos, LyXFont const & fnt)
{
- LyXFont font(fnt);
-
- LyXTextClass const & tclass = buf->params.getLyXTextClass();
- LyXLayout_ptr const & layout = par->layout();
+ LyXFont font = fnt;
+ 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);
}
}
- layoutfont.realize(tclass.defaultfont());
+ //layoutfont.realize(defaultfont_);
// Now, reduce font against full layout font
font.reduce(layoutfont);
- par->setFont(pos, font);
+ pit->setFont(pos, font);
}
// removes the row and reset the touched counters
void LyXText::removeRow(RowList::iterator rit)
{
- /* FIXME: when we cache the bview, this should just
- * become a postPaint(), I think */
- if (refresh_row == rit) {
- if (rit == rows().begin())
- refresh_row = boost::next(rit);
- else
- refresh_row = boost::prior(rit);
-
- // what about refresh_y
- }
-
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
+InsetOld * 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;
}
void LyXText::toggleInset()
{
- Inset * inset = getInset();
+ InsetOld * inset = getInset();
// is there an editable inset at cursor position?
if (!isEditableInset(inset)) {
// 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());
}
// do we want to keep this?? (JMarc)
if (!isHighlyEditableInset(inset))
- setCursorParUndo(bv());
+ recordUndo(bv(), Undo::ATOMIC);
if (inset->isOpen()) {
inset->close(bv());
/* used in setlayout */
// Asger is not sure we want to do this...
-void LyXText::makeFontEntriesLayoutSpecific(Buffer const & buf,
+void LyXText::makeFontEntriesLayoutSpecific(BufferParams const & params,
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
layoutfont = layout->font;
- LyXFont tmpfont = par.getFontSettings(buf.params, pos);
+ LyXFont tmpfont = par.getFontSettings(params, pos);
tmpfont.reduce(layoutfont);
par.setFont(pos, tmpfont);
}
}
-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);
+ recordUndo(bv(), Undo::ATOMIC, 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()->params, *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));
+ InsetOld * 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)
+ recordUndo(bv(), Undo::ATOMIC, 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);
// 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());
// Determine basis font
LyXFont layoutfont;
if (cursor.pos() < cursor.par()->beginningOfBody()) {
- layoutfont = getLabelFont(bv()->buffer(),
- cursor.par());
+ layoutfont = getLabelFont(cursor.par());
} else {
- layoutfont = getLayoutFont(bv()->buffer(),
- cursor.par());
+ layoutfont = getLayoutFont(cursor.par());
}
// Update current font
real_current_font.update(font,
// 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());
+ recordUndo(bv(), Undo::ATOMIC, 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
void LyXText::redoHeightOfParagraph()
{
- RowList::iterator tmprow = cursor.row();
- int y = cursor.y() - tmprow->baseline();
+ RowList::iterator tmprow = cursorRow();
setHeightOfRow(tmprow);
while (tmprow != rows().begin()
&& boost::prior(tmprow)->par() == tmprow->par()) {
--tmprow;
- y -= tmprow->height();
setHeightOfRow(tmprow);
}
- postPaint(y);
+ postPaint();
setCursor(cursor.par(), cursor.pos(), false, cursor.boundary());
}
-void LyXText::redoDrawingOfParagraph(LyXCursor const & cur)
-{
- RowList::iterator tmprow = cur.row();
-
- int y = cur.y() - tmprow->baseline();
- setHeightOfRow(tmprow);
-
- while (tmprow != rows().begin()
- && boost::prior(tmprow)->par() == tmprow->par()) {
- --tmprow;
- y -= tmprow->height();
- }
-
- postPaint(y);
- setCursor(cur.par(), cur.pos());
-}
-
-
-// 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();
+ RowList::iterator tmprit = getRow(cur);
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()
&& boost::prior(tmprit)->par() == first_phys_pit)
{
--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());
- } else {
+ else
setHeightOfRow(rows().begin());
- const_cast<LyXText *>(this)->postPaint(0);
- }
+ postPaint();
if (tmprit != rows().end())
setHeightOfRow(tmprit);
+
updateCounters();
}
void LyXText::fullRebreak()
{
- if (rows().empty()) {
- init(bv());
- return;
- }
- if (need_break_row != rows().end()) {
- breakAgain(need_break_row);
- need_break_row = rows().end();
- return;
- }
+ init(bv());
+ setCursorIntern(cursor.par(), cursor.pos());
}
-// important for the screen
-
-
-// the cursor set functions have a special mechanism. When they
-// realize, that you left an empty paragraph, they will delete it.
-// They also delete the corresponding row
-
-// need the selection cursor:
-void LyXText::setSelection()
+void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
{
- bool const lsel = selection.set();
+ //lyxerr << "LyXText::metrics: width: " << mi.base.textwidth << "\n";
- if (!selection.set()) {
- last_sel_cursor = selection.cursor;
- selection.start = selection.cursor;
- selection.end = selection.cursor;
- }
+ // rebuild row cache
+ rowlist_.clear();
+ width = height = 0;
- selection.set(true);
+ anchor_row_ = rows().end();
+ anchor_row_offset_ = 0;
- // first the toggling area
- if (cursor.y() < last_sel_cursor.y()
- || (cursor.y() == last_sel_cursor.y()
- && cursor.x() < last_sel_cursor.x())) {
- toggle_end_cursor = last_sel_cursor;
- toggle_cursor = cursor;
- } else {
- toggle_end_cursor = cursor;
- toggle_cursor = last_sel_cursor;
- }
+ ParagraphList::iterator pit = ownerParagraphs().begin();
+ ParagraphList::iterator end = ownerParagraphs().end();
- last_sel_cursor = cursor;
+ for (; pit != end; ++pit) {
+ InsetList::iterator ii = pit->insetlist.begin();
+ InsetList::iterator iend = pit->insetlist.end();
+ for (; ii != iend; ++ii) {
+ Dimension dim;
+ MetricsInfo m = mi;
+ ii->inset->metrics(m, dim);
+ }
- // and now the whole selection
+ // insert a new row, starting at position 0
+ Row newrow(pit, 0);
+ RowList::iterator rit = rowlist_.insert(rowlist_.end(), newrow);
- if (selection.cursor.par() == cursor.par())
- if (selection.cursor.pos() < cursor.pos()) {
- selection.end = cursor;
- selection.start = selection.cursor;
- } else {
- selection.end = selection.cursor;
- selection.start = cursor;
- }
- else if (selection.cursor.y() < cursor.y() ||
- (selection.cursor.y() == cursor.y()
- && selection.cursor.x() < cursor.x())) {
- selection.end = cursor;
- selection.start = selection.cursor;
- }
- else {
- selection.end = selection.cursor;
- selection.start = cursor;
+ // and now append the whole paragraph before the new row
+ appendParagraph(rit);
}
- // a selection with no contents is not a selection
- if (selection.start.par() == selection.end.par() &&
- selection.start.pos() == selection.end.pos())
- selection.set(false);
+ // compute height
+ //lyxerr << "height 0: " << height << "\n";
+ //for (RowList::iterator rit = rows().begin(); rit != rows().end(); ++rit) {
+ // height += rit->height();
+ //}
+ //lyxerr << "height 1: " << height << "\n";
- if (inset_owner && (selection.set() || lsel))
- inset_owner->setUpdateStatus(bv(), InsetText::SELECTION);
+ // final dimension
+ dim.asc = rows().begin()->ascent_of_text();
+ dim.des = height - dim.asc;
+ dim.wid = std::max(mi.base.textwidth, int(width));
}
-string const LyXText::selectionAsString(Buffer const * buffer,
- bool label) const
+void LyXText::partialRebreak()
{
- if (!selection.set()) return string();
-
- // should be const ...
- Paragraph * startpar(selection.start.par());
- Paragraph * endpar(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 (rows().empty()) {
+ init(bv());
+ return;
}
+ breakAgain(rows().begin());
+}
- string result;
- // First paragraph in selection
- result += startpar->asString(buffer, startpos, startpar->size(), label) + "\n\n";
+// important for the screen
- // 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());
- }
- // Last paragraph in selection
- result += endpar->asString(buffer, 0, endpos, label);
+// the cursor set functions have a special mechanism. When they
+// realize, that you left an empty paragraph, they will delete it.
+// They also delete the corresponding row
- return result;
+// need the selection cursor:
+void LyXText::setSelection()
+{
+ bool const lsel = TextCursor::setSelection();
+
+ if (inset_owner && (selection.set() || lsel))
+ inset_owner->setUpdateStatus(InsetText::SELECTION);
}
+
void LyXText::clearSelection()
{
- selection.set(false);
- selection.mark(false);
- last_sel_cursor = selection.end = selection.start = selection.cursor = cursor;
+ TextCursor::clearSelection();
+
// reset this in the bv_owner!
if (bv_owner && bv_owner->text)
bv_owner->text->xsel_cache.set(false);
void LyXText::cursorHome()
{
- setCursor(cursor.par(), cursor.row()->pos());
+ setCursor(cursor.par(), cursorRow()->pos());
}
{
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 = cursorRow();
+ 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());
}
LyXCursor resetCursor = cursor;
bool implicitSelection = (font.language() == ignore_language
&& font.number() == LyXFont::IGNORE)
- ? selectWordWhenUnderCursor(WHOLE_WORD_STRICT) : false;
+ ? selectWordWhenUnderCursor(lyx::WHOLE_WORD_STRICT) : false;
// Set font
setFont(font, toggleall);
selection.cursor = cursor;
}
if (inset_owner)
- inset_owner->setUpdateStatus(bv(), InsetText::CURSOR_PAR);
+ inset_owner->setUpdateStatus(InsetText::CURSOR_PAR);
}
// If there is a change in the language the implicit word selection
// is disabled.
LyXCursor const reset_cursor = cursor;
- bool const implicitSelection = selectWordWhenUnderCursor(PREVIOUS_WORD);
+ bool const implicitSelection =
+ selectWordWhenUnderCursor(lyx::PREVIOUS_WORD);
string idxstring;
if (!selection.set())
}
// 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);
+ recordUndo(bv(), Undo::ATOMIC, selection.start.par(),
+ boost::prior(undoendpit));
+
+ ParagraphList::iterator tmppit = selection.end.par();
- Paragraph * tmppar = selection.end.par();
+ while (tmppit != boost::prior(selection.start.par())) {
+ setCursor(tmppit, 0);
- while (tmppar != selection.start.par()->previous()) {
- setCursor(tmppar, 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);
}
+ postPaint();
- 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;
- Inset * in = 0;
+ ParagraphList::iterator tmppit = pit;
+ InsetOld * in = 0;
bool isOK = false;
- while (tmppar && tmppar->inInset()
+ while (tmppit != ownerParagraphs().end() &&
+ tmppit->inInset()
// the single '=' is intended below
- && (in = tmppar->inInset()->owner())) {
- if (in->lyxCode() == Inset::FLOAT_CODE ||
- in->lyxCode() == Inset::WRAP_CODE) {
+ && (in = tmppit->inInset()->owner())) {
+ if (in->lyxCode() == InsetOld::FLOAT_CODE ||
+ in->lyxCode() == InsetOld::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() == InsetOld::FLOAT_CODE)
+ type = static_cast<InsetFloat*>(in)->params().type;
+ else if (in->lyxCode() == InsetOld::WRAP_CODE)
+ type = static_cast<InsetWrap*>(in)->params().type;
+ else
+ 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;
}
}
-void LyXText::insertInset(Inset * inset)
+void LyXText::insertInset(InsetOld * inset)
{
if (!cursor.par()->insetAllowed(inset->lyxCode()))
return;
- setUndo(bv(), Undo::FINISH, cursor.par(), cursor.par()->next());
+ recordUndo(bv(), Undo::ATOMIC, 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);
+ recordUndo(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());
+ recordUndo(bv(), Undo::INSERT, cursor.par());
- Paragraph * endpar;
- Paragraph * actpar = cursor.par();
- int pos = cursor.pos();
+ ParagraphList::iterator endpit;
+ PitPosPair ppp;
- CutAndPaste::pasteSelection(&actpar, &endpar, pos,
- bv()->buffer()->params.textclass);
+ ErrorList el;
- redoParagraphs(cursor, endpar);
+ boost::tie(ppp, endpit) =
+ CutAndPaste::pasteSelection(*bv()->buffer(),
+ ownerParagraphs(),
+ cursor.par(), cursor.pos(),
+ bv()->buffer()->params.textclass,
+ sel_index, el);
+ bufferErrors(*bv()->buffer(), el);
+ bv()->showErrorList(_("Paste"));
+
+ redoParagraphs(cursor, endpit);
setCursor(cursor.par(), cursor.pos());
clearSelection();
selection.cursor = cursor;
- setCursor(actpar, pos);
+ setCursor(ppp.first, ppp.second);
setSelection();
updateCounters();
}
// simple replacing. The font of the first selected character is used
void LyXText::replaceSelectionWithString(string const & str)
{
- setCursorParUndo(bv());
+ recordUndo(bv(), Undo::ATOMIC);
freezeUndo();
if (!selection.set()) { // create a dummy selection
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());
+ recordUndo(bv(), Undo::ATOMIC);
// 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 beg = rows().begin();
-
- // is there a break one row above
- if (row != beg
- && boost::prior(row)->par() == row->par()) {
- z = rowBreakPoint(*boost::prior(row));
- if (z >= row->pos()) {
- // set the dimensions of the row above
- y -= boost::prior(row)->height();
- postPaint(y);
-
- breakAgain(boost::prior(row));
-
- // set the cursor again. Otherwise
- // dangling pointers are possible
- setCursor(cursor.par(), cursor.pos(),
- false, cursor.boundary());
- selection.cursor = cursor;
- return;
- }
- }
-
- int const tmpheight = row->height();
- pos_type const tmplast = lastPos(*this, row);
-
- breakAgain(row);
- if (row->height() == tmpheight && lastPos(*this, row) == tmplast) {
- postRowPaint(row, y);
- } else {
- postPaint(y);
- }
-
- // check the special right address boxes
- if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
- tmpcursor.par(par);
- tmpcursor.row(row);
- tmpcursor.y(y);
- tmpcursor.x(0);
- tmpcursor.x_fix(0);
- tmpcursor.pos(pos);
- redoDrawingOfParagraph(tmpcursor);
- }
-
- // set the cursor again. Otherwise dangling pointers are possible
- // also set the selection
-
- if (selection.set()) {
- tmpcursor = cursor;
- setCursorIntern(selection.cursor.par(), selection.cursor.pos(),
- false, selection.cursor.boundary());
- selection.cursor = cursor;
- setCursorIntern(selection.start.par(),
- selection.start.pos(),
- false, selection.start.boundary());
- selection.start = cursor;
- setCursorIntern(selection.end.par(),
- selection.end.pos(),
- false, selection.end.boundary());
- selection.end = cursor;
- setCursorIntern(last_sel_cursor.par(),
- last_sel_cursor.pos(),
- false, last_sel_cursor.boundary());
- last_sel_cursor = cursor;
- cursor = tmpcursor;
- }
- setCursorIntern(cursor.par(), cursor.pos(),
- false, cursor.boundary());
+ breakAgain(getRow(pit, pos));
+ postPaint();
+ setCursorIntern(cursor.par(), cursor.pos(), false, cursor.boundary());
}
// returns false if inset wasn't found
-bool LyXText::updateInset(Inset * inset)
+bool LyXText::updateInset(InsetOld * inset)
{
// first check the current paragraph
int pos = cursor.par()->getPositionOfInset(inset);
}
// check every paragraph
-
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);
+ Assert(pit != ownerParagraphs().end());
- cur.par(par);
+ cur.par(pit);
cur.pos(pos);
cur.boundary(boundary);
+ if (rows().empty())
+ return;
// 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;
- cur.irow(row);
// if we are before the first char of this row and are still in the
// 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) {
+ InsetOld * ins = pit->getInset(pos);
+ if (ins && (ins->needFullRow() || ins->display())) {
+ --row;
+ y -= row->height();
+ }
}
- cur.row(row);
// y is now the beginning of the cursor row
y += row->baseline();
// y is now the cursor baseline
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();
pos_type pos, pos_type last, bool boundary) const
{
pos_type cursor_vpos = 0;
- float x;
- float fill_separator;
- float fill_hfill;
- float fill_label_hfill;
+ int x;
+ int fill_separator;
+ int fill_hfill;
+ int fill_label_hfill;
// This call HAS to be here because of the BidiTables!!!
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(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 (pos > cursor.row()->pos() &&
+ if (pit->isSeparator(pos)) {
+ if (pos > cursorRow()->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);
+ current_font = pit->getFontSettings(bv()->buffer()->params, pos);
+ real_current_font = getFont(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
LyXText::getColumnNearX(RowList::iterator rit, int & x, bool & boundary) const
{
- float tmpx = 0.0;
- float fill_separator;
- float fill_hfill;
- float fill_label_hfill;
+ int tmpx = 0;
+ int fill_separator;
+ int fill_hfill;
+ int fill_label_hfill;
- prepareToPrint(rit, tmpx, fill_separator,
- fill_hfill, fill_label_hfill);
+ prepareToPrint(rit, tmpx, fill_separator, fill_hfill, fill_label_hfill);
pos_type vc = rit->pos();
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();
- float last_tmpx = tmpx;
+ pos_type body_pos = rit_par->beginningOfBody();
+ int 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()) {
- x = int(tmpx);
+ if (!rit_par->size()) {
+ x = tmpx;
return 0;
}
last_tmpx = tmpx;
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);
+ font_metrics::width(layout->labelsep, getLabelFont(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;
+ 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;
}
void LyXText::setCursorFromCoordinates(int x, int y)
{
- LyXCursor old_cursor = cursor;
-
+ //LyXCursor old_cursor = cursor;
setCursorFromCoordinates(cursor, x, y);
setCurrentFont();
- deleteEmptyParagraphMechanism(old_cursor);
+#warning DEPM disabled, otherwise crash when entering new table
+ //deleteEmptyParagraphMechanism(old_cursor);
}
* 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 = lt.getRow(cur);
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());
+
+ InsetOld 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());
} else {
cur.iy(cur.y());
cur.ix(cur.x());
- cur.irow(row);
}
cur.boundary(bound);
}
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);
}
{
#if 1
int x = cursor.x_fix();
- int y = cursor.y() - cursor.row()->baseline() - 1;
+ int y = cursor.y() - cursorRow()->baseline() - 1;
setCursorFromCoordinates(x, y);
if (!selecting) {
int topy = top_y();
int y1 = cursor.iy() - topy;
int y2 = y1;
y -= topy;
- Inset * inset_hit = checkInsetHit(x, y1);
+ InsetOld * 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
setCursorFromCoordinates(bv(), cursor.x_fix(),
- cursor.y() - cursor.row()->baseline() - 1);
+ cursor.y() - cursorRow()->baseline() - 1);
#endif
}
{
#if 1
int x = cursor.x_fix();
- int y = cursor.y() - cursor.row()->baseline() +
- cursor.row()->height() + 1;
+ int y = cursor.y() - cursorRow()->baseline() + cursorRow()->height() + 1;
setCursorFromCoordinates(x, y);
- if (!selecting && cursor.row() == cursor.irow()) {
+ if (!selecting && cursorRow() == cursorIRow()) {
int topy = top_y();
int y1 = cursor.iy() - topy;
int y2 = y1;
y -= topy;
- Inset * inset_hit = checkInsetHit(x, y1);
+ InsetOld * 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
setCursorFromCoordinates(bv(), cursor.x_fix(),
- cursor.y() - cursor.row()->baseline()
- + cursor.row()->height() + 1);
+ cursor.y() - cursorRow()->baseline()
+ + cursorRow()->height() + 1);
#endif
}
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;
- if (old_cursor.row() != rows().begin()) {
- RowList::iterator
- prevrow = boost::prior(old_cursor.row());
- const_cast<LyXText *>(this)->postPaint(old_cursor.y() - old_cursor.row()->baseline() - prevrow->height());
+ bool selection_position_was_oldcursor_position = (
+ selection.cursor.par() == old_cursor.par()
+ && selection.cursor.pos() == old_cursor.pos());
+
+ if (getRow(old_cursor) != rows().begin()) {
+ RowList::iterator prevrow = boost::prior(getRow(old_cursor));
+ postPaint();
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);
+
+ recordUndo(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()));
- }
+ removeRow(getRow(old_cursor));
// 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);
} else {
- RowList::iterator nextrow = boost::next(old_cursor.row());
- const_cast<LyXText *>(this)->postPaint(
- old_cursor.y() - old_cursor.row()->baseline());
+ RowList::iterator nextrow = boost::next(getRow(old_cursor));
+ postPaint();
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);
+
+ recordUndo(bv(), Undo::DELETE, old_cursor.par(), boost::prior(endpit));
cursor = tmpcursor;
// delete old row
- removeRow(old_cursor.row());
+ removeRow(getRow(old_cursor));
// 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
+bool LyXText::needRefresh() const
{
- return refresh_status_;
+ return need_refresh_;
}
void LyXText::clearPaint()
{
- refresh_status_ = REFRESH_NONE;
- refresh_row = rows().end();
- refresh_y = 0;
+ need_refresh_ = false;
}
-void LyXText::postPaint(int start_y)
+void LyXText::postPaint()
{
- refresh_status old = refresh_status_;
-
- refresh_status_ = REFRESH_AREA;
- refresh_row = rows().end();
-
- if (old != REFRESH_NONE && refresh_y < start_y)
- return;
-
- refresh_y = start_y;
-
- if (!inset_owner)
- return;
+ need_refresh_ = true;
// We are an inset's lyxtext. Tell the top-level lyxtext
// it needs to update the row we're in.
- LyXText * t = bv()->text;
- t->postRowPaint(t->cursor.row(), t->cursor.y() - t->cursor.row()->baseline());
-}
-
-
-// FIXME: we should probably remove this y parameter,
-// make refresh_y be 0, and use row->y etc.
-void LyXText::postRowPaint(RowList::iterator rit, int start_y)
-{
- if (refresh_status_ != REFRESH_NONE && refresh_y < start_y) {
- refresh_status_ = REFRESH_AREA;
- return;
- } else {
- refresh_y = start_y;
- }
-
- if (refresh_status_ == REFRESH_AREA)
- return;
-
- refresh_status_ = REFRESH_ROW;
- refresh_row = rit;
-
- if (!inset_owner)
- return;
-
- // We are an inset's lyxtext. Tell the top-level lyxtext
- // it needs to update the row we're in.
- LyXText * t = bv()->text;
- t->postRowPaint(t->cursor.row(), t->cursor.y() - t->cursor.row()->baseline());
+ if (inset_owner)
+ bv()->text->postPaint();
}