par.insertInset(par.size(), new InsetLine, font, change);
} else if (token == "\\newpage") {
par.insertInset(par.size(), new InsetPagebreak, font, change);
+ } else if (token == "\\clearpage") {
+ par.insertInset(par.size(), new InsetClearPage, font, change);
+ } else if (token == "\\cleardoublepage") {
+ par.insertInset(par.size(), new InsetClearDoublePage, font, change);
} else if (token == "\\change_unchanged") {
change = Change(Change::UNCHANGED);
} else if (token == "\\change_inserted") {
}
-namespace {
-
-}
-
void LyXText::breakParagraph(LCursor & cur, bool keep_layout)
{
BOOST_ASSERT(this == cur.text());
// this is only allowed, if the current paragraph is not empty
// or caption and if it has not the keepempty flag active
- if (cur.lastpos() == 0 && !cpar.allowEmpty()
- && layout->labeltype != LABEL_SENSITIVE)
+ if (cur.lastpos() == 0 && !cpar.allowEmpty() &&
+ layout->labeltype != LABEL_SENSITIVE)
return;
// a layout change may affect also the following paragraph
// Always break behind a space
// It is better to erase the space (Dekel)
if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
- // FIXME: change tracking (MG)
cpar.eraseChar(cur.pos(), cur.buffer().params().trackChanges);
- // How should the layout for the new paragraph be?
+ // What should the layout for the new paragraph be?
int preserve_layout = 0;
if (keep_layout)
preserve_layout = 2;
}
while (!pars_[next_par].empty() && pars_[next_par].isNewline(0))
- // FIXME: change tracking (MG)
pars_[next_par].eraseChar(0, cur.buffer().params().trackChanges);
ParIterator current_it(cur);
updateLabels(cur.buffer(), current_it, last_it);
- // Mark "carriage return" as inserted if change tracking:
- if (cur.buffer().params().trackChanges) {
- // FIXME: Change tracking (MG)
- cur.paragraph().setChange(cur.paragraph().size(),
- Change(Change::INSERTED));
- }
-
// FIXME: Breaking a paragraph has nothing to do with setting a cursor.
// Because of the mix between the model (the paragraph contents) and the
// view (the paragraph breaking in rows, we have to do this here before
// A singlePar update is not enough in this case.
cur.updateFlags(Update::Force);
-
// This check is necessary. Otherwise the new empty paragraph will
// be deleted automatically. And it is more friendly for the user!
if (cur.pos() != 0 || isempty)
void LyXText::acceptChange(LCursor & cur)
{
+ // FIXME: change tracking (MG)
+
BOOST_ASSERT(this == cur.text());
+
if (!cur.selection() && cur.lastpos() != 0)
return;
+ // FIXME: we must handle start = end = 0
+
recordUndoSelection(cur, Undo::INSERT);
DocIterator it = cur.selectionBegin();
DocIterator et = cur.selectionEnd();
pit_type pit = it.pit();
- bool isDeleted = pars_[pit].isDeleted(it.pos());
for (; pit <= et.pit(); ++pit) {
- pos_type left = ( pit == it.pit() ? it.pos() : 0 );
- pos_type right =
- ( pit == et.pit() ? et.pos() : pars_[pit].size() + 1 );
+ pos_type left = (pit == it.pit() ? it.pos() : 0);
+ pos_type right = (pit == et.pit() ? et.pos() : pars_[pit].size());
pars_[pit].acceptChanges(left, right);
- }
- if (isDeleted) {
- ParagraphList & plist = paragraphs();
- if (it.pit() + 1 < et.pit())
- pars_.erase(boost::next(plist.begin(), it.pit() + 1),
- boost::next(plist.begin(), et.pit()));
- // Paragraph merge if appropriate:
- // FIXME: change tracking (MG)
- if (pars_[it.pit()].isDeleted(pars_[it.pit()].size())) {
- setCursorIntern(cur, it.pit() + 1, 0);
- backspacePos0(cur);
- }
+ // merge paragraph if appropriate:
+ // if (right >= pars_[pit].size() && pit + 1 < et.pit() &&
+ // pars_[pit].isDeleted(pars_[pit].size())) {
+ // setCursorIntern(cur, pit + 1, 0);
+ // backspacePos0(cur);
+ //}
}
finishUndo();
cur.clearSelection();
void LyXText::rejectChange(LCursor & cur)
{
+ // FIXME: change tracking (MG)
+
BOOST_ASSERT(this == cur.text());
+
if (!cur.selection() && cur.lastpos() != 0)
return;
+ // FIXME: we must handle start = end = 0
+
recordUndoSelection(cur, Undo::INSERT);
DocIterator it = cur.selectionBegin();
DocIterator et = cur.selectionEnd();
pit_type pit = it.pit();
- bool isInserted = pars_[pit].isInserted(it.pos());
for (; pit <= et.pit(); ++pit) {
- pos_type left = ( pit == it.pit() ? it.pos() : 0 );
- pos_type right =
- ( pit == et.pit() ? et.pos() : pars_[pit].size() + 1 );
+ pos_type left = (pit == it.pit() ? it.pos() : 0);
+ pos_type right = (pit == et.pit() ? et.pos() : pars_[pit].size());
pars_[pit].rejectChanges(left, right);
- }
- if (isInserted) {
- ParagraphList & plist = paragraphs();
- if (it.pit() + 1 < et.pit())
- pars_.erase(boost::next(plist.begin(), it.pit() + 1),
- boost::next(plist.begin(), et.pit()));
- // Paragraph merge if appropriate:
- // FIXME: change tracking (MG)
- if (pars_[it.pit()].isInserted(pars_[it.pit()].size())) {
- setCursorIntern(cur, it.pit() + 1, 0);
- backspacePos0(cur);
- }
+
+ // merge paragraph if appropriate:
+ // if (right >= pars_[pit].size() && pit + 1 < et.pit() &&
+ // pars_[pit].isInserted(pars_[pit].size())) {
+ // setCursorIntern(cur, pit + 1, 0);
+ // backspacePos0(cur);
+ //}
}
finishUndo();
cur.clearSelection();
if (par.isDeleted(cur.pos()))
cur.forwardPosNoDescend();
needsUpdate = true;
- } else if (cur.pit() != cur.lastpit()) {
- if (cur.buffer().params().trackChanges
- && par.isInserted(cur.pos())) {
- // mark "carriage return" as deleted:
- // FIXME: Change tracking (MG)
+ } else {
+ if (cur.pit() == cur.lastpit())
+ return dissolveInset(cur);
+
+ if (!par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) {
par.setChange(cur.pos(), Change(Change::DELETED));
cur.forwardPos();
needsUpdate = true;
} else {
setCursorIntern(cur, cur.pit() + 1, 0);
needsUpdate = backspacePos0(cur);
- // FIXME: Change tracking (MG)
- if (cur.paragraph().isDeleted(cur.pos()))
- cur.forwardPos();
}
- } else
- needsUpdate = dissolveInset(cur);
+ }
// FIXME: Inserting characters has nothing to do with setting a cursor.
// Because of the mix between the model (the paragraph contents)
needsUpdate = true;
}
// Pasting is not allowed, if the paragraphs have different
- // layout. I think it is a real bug of all other
+ // layouts. I think it is a real bug of all other
// word processors to allow it. It confuses the user.
// Correction: Pasting is always allowed with standard-layout
else if (par.layout() == prevpar.layout()
}
-
-
bool LyXText::backspace(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
if (cur.pit() == 0)
return dissolveInset(cur);
- if (cur.buffer().params().trackChanges) {
- // FIXME: Change tracking (MG)
- // Previous paragraph, mark "carriage return" as
- // deleted:
- Paragraph & par = pars_[cur.pit() - 1];
- // Take care of a just inserted para break:
- // FIXME: change tracking (MG)
- if (!par.isInserted(par.size())) {
- // FIXME: change tracking (MG)
- par.setChange(par.size(), Change(Change::DELETED));
- setCursorIntern(cur, cur.pit() - 1, par.size());
- return true;
- }
- }
+ Paragraph & prev_par = pars_[cur.pit() - 1];
+ if (!prev_par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) {
+ prev_par.setChange(prev_par.size(), Change(Change::DELETED));
+ setCursorIntern(cur, cur.pit() - 1, prev_par.size());
+ return true;
+ }
// The cursor is at the beginning of a paragraph, so
// the backspace will collapse two paragraphs into one.
needsUpdate = backspacePos0(cur);
// without the dreaded mechanism. (JMarc)
setCursorIntern(cur, cur.pit(), cur.pos() - 1,
false, cur.boundary());
- // FIXME: change tracking (MG)
cur.paragraph().eraseChar(cur.pos(), cur.buffer().params().trackChanges);
}
spos += cur.pos();
spit += cur.pit();
Buffer & b = cur.buffer();
- // FIXME: change tracking (MG)
cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges);
if (!plist.empty()) {
if (in_ert) {
Paragraph & par = pars_[pit];
Buffer const & buffer = *bv.buffer();
+ bool changed = false;
+
// Add bibitem insets if necessary
if (par.layout()->labeltype == LABEL_BIBLIO) {
bool hasbibitem(false);
// FIXME: We should always use getFont(), see documentation of
// noFontChange() in insetbase.h.
LyXFont const bufferfont = buffer.params().getFont();
- InsetList::iterator ii = par.insetlist.begin();
- InsetList::iterator iend = par.insetlist.end();
+ InsetList::const_iterator ii = par.insetlist.begin();
+ InsetList::const_iterator iend = par.insetlist.end();
for (; ii != iend; ++ii) {
Dimension dim;
int const w = maxwidth_ - leftMargin(buffer, pit, ii->pos)
bufferfont :
getFont(buffer, par, ii->pos);
MetricsInfo mi(&bv, font, w);
- ii->inset->metrics(mi, dim);
+ changed |= ii->inset->metrics(mi, dim);
}
// rebreak the paragraph
dim.asc += par.rows()[0].ascent();
dim.des -= par.rows()[0].ascent();
- bool const same = dim.height() == par.dim().height();
+ changed |= dim.height() != par.dim().height();
par.dim() = dim;
//lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
- return !same;
+ return changed;
}
-void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
+bool LyXText::metrics(MetricsInfo & mi, Dimension & dim)
{
//BOOST_ASSERT(mi.base.textwidth);
if (mi.base.textwidth)
// save the caller's font locally:
font_ = mi.base.font;
+ bool changed = false;
+
unsigned int h = 0;
unsigned int w = 0;
for (pit_type pit = 0, n = paragraphs().size(); pit != n; ++pit) {
- redoParagraph(*mi.base.bv, pit);
+ changed |= redoParagraph(*mi.base.bv, pit);
Paragraph & par = paragraphs()[pit];
h += par.height();
if (w < par.width())
dim.asc = pars_[0].ascent();
dim.des = h - dim.asc;
+ changed |= dim_ != dim;
dim_ = dim;
+ return changed;
}