mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 10:58:52 +00:00
John&JMarc's change tracking patch
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10424 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
a18c3cda5c
commit
52a2eb2c52
@ -1,3 +1,32 @@
|
||||
2005-08-03 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
|
||||
|
||||
* text.C (read): remove unused variable.
|
||||
(readParToken): remove static Change variable (never good in
|
||||
recursive settings...); add it as a parameter instead.
|
||||
|
||||
* paragraph_pimpl.C (acceptChange): make debug info conditional.
|
||||
|
||||
* metricsinfo.C (PainterInfo): add new member erased_.
|
||||
|
||||
* rowpainter.C (RowPainter): add erased_ member, initialized from
|
||||
PainterInfo.
|
||||
(paintInset): pass erased_ to Inset::draw.
|
||||
|
||||
* lyxfunc.C (lookupChange): new function. Tells whether change
|
||||
tracking is disabled at a given postion.
|
||||
(getStatus): disable some actions when in deleted text with change
|
||||
tracking.
|
||||
|
||||
2005-08-03 John Levon <levon@movementarian.org>
|
||||
|
||||
* tabular.C (appendColumn, setMultiColumn): adapt to change to
|
||||
InsetText::clear().
|
||||
|
||||
* paragraph_pimpl.C (markErased): add bool argument and handle it.
|
||||
Also make sure to mark insets recursively.
|
||||
(rejectChange, erase): be recursive
|
||||
|
||||
* paragraph.C (markErased): add bool argument.
|
||||
2005-08-04 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
|
||||
|
||||
* lyxfind.C (findNextChange): tiny cleanup.
|
||||
|
@ -1,3 +1,20 @@
|
||||
2005-08-03 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
|
||||
|
||||
* insettabular.C (draw): pass PainterInfro::erased_ to
|
||||
drawCellLines
|
||||
(drawCellLines): add an erased bool and handle it.
|
||||
|
||||
2005-08-03 John Levon <levon@movementarian.org>
|
||||
|
||||
* insettext.C (clear): remove bool argument.
|
||||
(read): adapt to clear() changes.
|
||||
|
||||
* insettabular.C (cutSelection): adapt to MarkErased changes.
|
||||
|
||||
* insettext.C (markErased):
|
||||
* insettabular.C (markErased):
|
||||
* insetbase.C (markErased): add bool argument.
|
||||
|
||||
2005-09-06 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||
|
||||
* insettabular.C: mark tabular_stack_ (of CutAndPaste) dirty
|
||||
|
@ -273,7 +273,7 @@ std::string const & InsetBase::getInsetName() const
|
||||
}
|
||||
|
||||
|
||||
void InsetBase::markErased()
|
||||
void InsetBase::markErased(bool)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -372,12 +372,12 @@ public:
|
||||
virtual mode_type currentMode() const { return UNDECIDED_MODE; }
|
||||
/// returns whether this inset is allowed in other insets of given mode
|
||||
virtual bool allowedIn(mode_type) const { return true; }
|
||||
|
||||
/// is this inset allowed within a font change?
|
||||
virtual bool noFontChange() const { return false; }
|
||||
|
||||
///
|
||||
virtual void markErased();
|
||||
/// mark the inset as erased or not
|
||||
virtual void markErased(bool erased);
|
||||
|
||||
/// pretty arbitrary
|
||||
virtual int width() const { return 10; }
|
||||
/// pretty arbitrary
|
||||
|
@ -304,10 +304,10 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
|
||||
|| y + d < 0
|
||||
|| y - a > bv->workHeight()) {
|
||||
cell(idx)->draw(nullpi, cx, y);
|
||||
drawCellLines(nop, nx, y, i, idx);
|
||||
drawCellLines(nop, nx, y, i, idx, pi.erased_);
|
||||
} else {
|
||||
cell(idx)->draw(pi, cx, y);
|
||||
drawCellLines(pi.pain, nx, y, i, idx);
|
||||
drawCellLines(pi.pain, nx, y, i, idx, pi.erased_);
|
||||
}
|
||||
nx += tabular.getWidthOfColumn(idx);
|
||||
++idx;
|
||||
@ -366,28 +366,35 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
|
||||
|
||||
void InsetTabular::drawCellLines(Painter & pain, int x, int y,
|
||||
row_type row, idx_type cell) const
|
||||
row_type row, idx_type cell, bool erased) const
|
||||
{
|
||||
int x2 = x + tabular.getWidthOfColumn(cell);
|
||||
bool on_off = false;
|
||||
LColor::color col = LColor::tabularline;
|
||||
LColor::color onoffcol = LColor::tabularonoffline;
|
||||
|
||||
if (erased) {
|
||||
col = LColor::strikeout;
|
||||
onoffcol = LColor::strikeout;
|
||||
}
|
||||
|
||||
if (!tabular.topAlreadyDrawn(cell)) {
|
||||
on_off = !tabular.topLine(cell);
|
||||
pain.line(x, y - tabular.getAscentOfRow(row),
|
||||
x2, y - tabular.getAscentOfRow(row),
|
||||
on_off ? LColor::tabularonoffline : LColor::tabularline,
|
||||
on_off ? onoffcol : col,
|
||||
on_off ? Painter::line_onoffdash : Painter::line_solid);
|
||||
}
|
||||
on_off = !tabular.bottomLine(cell);
|
||||
pain.line(x, y + tabular.getDescentOfRow(row),
|
||||
x2, y + tabular.getDescentOfRow(row),
|
||||
on_off ? LColor::tabularonoffline : LColor::tabularline,
|
||||
on_off ? onoffcol : col,
|
||||
on_off ? Painter::line_onoffdash : Painter::line_solid);
|
||||
if (!tabular.leftAlreadyDrawn(cell)) {
|
||||
on_off = !tabular.leftLine(cell);
|
||||
pain.line(x, y - tabular.getAscentOfRow(row),
|
||||
x, y + tabular.getDescentOfRow(row),
|
||||
on_off ? LColor::tabularonoffline : LColor::tabularline,
|
||||
on_off ? onoffcol : col,
|
||||
on_off ? Painter::line_onoffdash : Painter::line_solid);
|
||||
}
|
||||
on_off = !tabular.rightLine(cell);
|
||||
@ -395,7 +402,7 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
|
||||
y - tabular.getAscentOfRow(row),
|
||||
x2 - tabular.getAdditionalWidth(cell),
|
||||
y + tabular.getDescentOfRow(row),
|
||||
on_off ? LColor::tabularonoffline : LColor::tabularline,
|
||||
on_off ? onoffcol : col,
|
||||
on_off ? Painter::line_onoffdash : Painter::line_solid);
|
||||
}
|
||||
|
||||
@ -435,7 +442,7 @@ void InsetTabular::edit(LCursor & cur, bool left)
|
||||
|
||||
void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
{
|
||||
lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl;
|
||||
lyxerr << "# InsetTabular::doDispatch: cmd: " << cmd << endl;
|
||||
lyxerr << " cur:\n" << cur << endl;
|
||||
CursorSlice sl = cur.top();
|
||||
LCursor & bvcur = cur.bv().cursor();
|
||||
@ -1770,13 +1777,19 @@ void InsetTabular::cutSelection(LCursor & cur)
|
||||
if (!cur.selection())
|
||||
return;
|
||||
|
||||
bool const track = cur.buffer().params().tracking_changes;
|
||||
row_type rs, re;
|
||||
col_type cs, ce;
|
||||
getSelection(cur, rs, re, cs, ce);
|
||||
for (row_type i = rs; i <= re; ++i)
|
||||
for (col_type j = cs; j <= ce; ++j)
|
||||
cell(tabular.getCellNumber(i, j))->clear(track);
|
||||
for (row_type i = rs; i <= re; ++i) {
|
||||
for (col_type j = cs; j <= ce; ++j) {
|
||||
shared_ptr<InsetText> t
|
||||
= cell(tabular.getCellNumber(i, j));
|
||||
if (cur.buffer().params().tracking_changes)
|
||||
t->markErased(true);
|
||||
else
|
||||
t->clear();
|
||||
}
|
||||
}
|
||||
|
||||
// cursor position might be invalid now
|
||||
cur.pos() = cur.lastpos();
|
||||
@ -1821,10 +1834,10 @@ LyXText * InsetTabular::getText(int idx) const
|
||||
}
|
||||
|
||||
|
||||
void InsetTabular::markErased()
|
||||
void InsetTabular::markErased(bool erased)
|
||||
{
|
||||
for (idx_type idx = 0; idx < nargs(); ++idx)
|
||||
cell(idx)->markErased();
|
||||
cell(idx)->markErased(erased);
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
LyXText * getText(int) const;
|
||||
|
||||
///
|
||||
void markErased();
|
||||
void markErased(bool);
|
||||
|
||||
// this should return true if we have a "normal" cell, otherwise true.
|
||||
// "normal" means without width set!
|
||||
@ -156,7 +156,7 @@ private:
|
||||
|
||||
///
|
||||
void drawCellLines(Painter &, int x, int y, row_type row,
|
||||
idx_type cell) const;
|
||||
idx_type cell, bool erased) const;
|
||||
///
|
||||
void setCursorFromCoordinates(LCursor & cur, int x, int y) const;
|
||||
|
||||
|
@ -108,14 +108,17 @@ void InsetText::init()
|
||||
}
|
||||
|
||||
|
||||
void InsetText::clear(bool just_mark_erased)
|
||||
void InsetText::markErased(bool erased)
|
||||
{
|
||||
ParagraphList & pars = paragraphs();
|
||||
for_each(pars.begin(), pars.end(),
|
||||
bind(&Paragraph::markErased, _1, erased));
|
||||
}
|
||||
|
||||
|
||||
void InsetText::clear()
|
||||
{
|
||||
ParagraphList & pars = paragraphs();
|
||||
if (just_mark_erased) {
|
||||
for_each(pars.begin(), pars.end(),
|
||||
bind(&Paragraph::markErased, _1));
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a gross hack...
|
||||
LyXLayout_ptr old_layout = pars.begin()->layout();
|
||||
@ -142,7 +145,7 @@ void InsetText::write(Buffer const & buf, ostream & os) const
|
||||
|
||||
void InsetText::read(Buffer const & buf, LyXLex & lex)
|
||||
{
|
||||
clear(false);
|
||||
clear();
|
||||
|
||||
#ifdef WITH_WARNINGS
|
||||
#warning John, look here. Doesnt make much sense.
|
||||
@ -352,7 +355,7 @@ void InsetText::markNew(bool track_changes)
|
||||
|
||||
void InsetText::setText(string const & data, LyXFont const & font)
|
||||
{
|
||||
clear(false);
|
||||
clear();
|
||||
Paragraph & first = paragraphs().front();
|
||||
for (unsigned int i = 0; i < data.length(); ++i)
|
||||
first.insertChar(i, data[i], font);
|
||||
|
@ -40,8 +40,8 @@ public:
|
||||
explicit InsetText(BufferParams const &);
|
||||
///
|
||||
InsetText();
|
||||
/// empty inset to empty par, or just mark as erased
|
||||
void clear(bool just_mark_erased);
|
||||
/// empty inset to empty par
|
||||
void clear();
|
||||
///
|
||||
void read(Buffer const & buf, LyXLex & lex);
|
||||
///
|
||||
@ -107,7 +107,8 @@ public:
|
||||
bool getStatus(LCursor & cur, FuncRequest const & cmd, FuncStatus &) const;
|
||||
|
||||
/// mark as erased for change tracking
|
||||
void markErased() { clear(true); }
|
||||
void markErased(bool erased);
|
||||
|
||||
/**
|
||||
* Mark as new. Used when pasting in tabular, and adding rows
|
||||
* or columns. Note that pasting will ensure that tracking already
|
||||
|
@ -174,6 +174,28 @@ bool getStatus(LCursor cursor,
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/** Return the change status at cursor position, taking in account the
|
||||
* status at each level of the document iterator (a table in a deleted
|
||||
* footnote is deleted).
|
||||
* When \param outer is true, the top slice is not looked at.
|
||||
*/
|
||||
Change::Type lookupChange(DocIterator const & dit, bool outer = false)
|
||||
{
|
||||
size_t const depth = dit.depth() - outer ? 1 : 0;
|
||||
|
||||
for (size_t i = 0 ; i < depth ; ++i) {
|
||||
CursorSlice const & slice = dit[i];
|
||||
if (!slice.inset().inMathed()
|
||||
&& slice.pos() < slice.paragraph().size()) {
|
||||
Change::Type const ch = slice.paragraph().lookupChange(slice.pos());
|
||||
if (ch != Change::UNCHANGED)
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return Change::UNCHANGED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LyXFunc::LyXFunc(LyXView * lv)
|
||||
@ -594,6 +616,15 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
|
||||
flag.enabled(false);
|
||||
}
|
||||
|
||||
// Are we in a DELETED change-tracking region?
|
||||
if (buf && buf->params().tracking_changes
|
||||
&& lookupChange(cur, true) == Change::DELETED
|
||||
&& !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)
|
||||
&& !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) {
|
||||
flag.message(N_("This portion of the document is deleted."));
|
||||
flag.enabled(false);
|
||||
}
|
||||
|
||||
// the default error message if we disable the command
|
||||
if (!flag.enabled() && flag.message().empty())
|
||||
flag.message(N_("Command disabled"));
|
||||
|
@ -47,7 +47,7 @@ MetricsInfo::MetricsInfo(BufferView * bv, LyXFont const & font, int textwidth)
|
||||
|
||||
|
||||
PainterInfo::PainterInfo(BufferView * bv, Painter & painter)
|
||||
: pain(painter), ltr_pos(false)
|
||||
: pain(painter), ltr_pos(false), erased_(false)
|
||||
{
|
||||
base.bv = bv;
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ public:
|
||||
Painter & pain;
|
||||
/// Whether the text at this point is right-to-left (for InsetNewline)
|
||||
bool ltr_pos;
|
||||
/// Whether the parent is deleted (change tracking)
|
||||
bool erased_;
|
||||
};
|
||||
|
||||
class TextMetricsInfo {};
|
||||
|
@ -1659,9 +1659,9 @@ void Paragraph::setChange(lyx::pos_type pos, Change::Type type)
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::markErased()
|
||||
void Paragraph::markErased(bool erased)
|
||||
{
|
||||
pimpl_->markErased();
|
||||
pimpl_->markErased(erased);
|
||||
}
|
||||
|
||||
|
||||
|
@ -231,8 +231,8 @@ public:
|
||||
/// reject change
|
||||
void rejectChange(lyx::pos_type start, lyx::pos_type end);
|
||||
|
||||
/// mark whole par as erased
|
||||
void markErased();
|
||||
/// mark whole par as erased or not
|
||||
void markErased(bool erased);
|
||||
|
||||
/// Paragraphs can contain "manual labels", for example, Description
|
||||
/// environment. The text for this user-editable label is stored in
|
||||
|
@ -165,15 +165,21 @@ Change const Paragraph::Pimpl::lookupChangeFull(pos_type pos) const
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::Pimpl::markErased()
|
||||
void Paragraph::Pimpl::markErased(bool erased)
|
||||
{
|
||||
BOOST_ASSERT(tracking());
|
||||
|
||||
// FIXME: we should actually remove INSERTED chars.
|
||||
// difficult because owning insettexts/tabulars need
|
||||
// to update themselves when rows etc. change
|
||||
changes_->set(Change::DELETED, 0, size());
|
||||
changes_->reset(Change::DELETED);
|
||||
if (erased) {
|
||||
erase(0, size());
|
||||
} else {
|
||||
pos_type i = 0;
|
||||
|
||||
for (pos_type i = 0; i < size(); ++i) {
|
||||
changes_->set(Change::UNCHANGED, i);
|
||||
if (owner_->isInset(i))
|
||||
owner_->getInset(i)->markErased(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,7 +193,7 @@ void Paragraph::Pimpl::acceptChange(pos_type start, pos_type end)
|
||||
return;
|
||||
}
|
||||
|
||||
lyxerr << "acceptchange" << endl;
|
||||
lyxerr[Debug::CHANGES] << "acceptchange" << endl;
|
||||
pos_type i = start;
|
||||
|
||||
for (; i < end; ++i) {
|
||||
@ -208,7 +214,7 @@ void Paragraph::Pimpl::acceptChange(pos_type start, pos_type end)
|
||||
}
|
||||
}
|
||||
|
||||
lyxerr << "endacceptchange" << endl;
|
||||
lyxerr[Debug::CHANGES] << "endacceptchange" << endl;
|
||||
changes_->reset(Change::UNCHANGED);
|
||||
}
|
||||
|
||||
@ -239,6 +245,8 @@ void Paragraph::Pimpl::rejectChange(pos_type start, pos_type end)
|
||||
|
||||
case Change::DELETED:
|
||||
changes_->set(Change::UNCHANGED, i);
|
||||
if (owner_->isInset(i))
|
||||
owner_->getInset(i)->markErased(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -353,9 +361,8 @@ bool Paragraph::Pimpl::erase(pos_type pos)
|
||||
|
||||
// only allow the actual removal if it was /new/ text
|
||||
if (changetype != Change::INSERTED) {
|
||||
if (owner_->text_[pos] == Paragraph::META_INSET) {
|
||||
owner_->getInset(pos)->markErased();
|
||||
}
|
||||
if (owner_->isInset(pos))
|
||||
owner_->getInset(pos)->markErased(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
/// set change at pos
|
||||
void setChange(lyx::pos_type pos, Change::Type type);
|
||||
/// mark as erased
|
||||
void markErased();
|
||||
void markErased(bool);
|
||||
/// accept change
|
||||
void acceptChange(lyx::pos_type start, lyx::pos_type end);
|
||||
/// reject change
|
||||
|
@ -101,6 +101,9 @@ private:
|
||||
pit_type const pit_;
|
||||
Paragraph const & par_;
|
||||
|
||||
/// is row erased? (change tracking)
|
||||
bool erased_;
|
||||
|
||||
// Looks ugly - is
|
||||
double const xo_;
|
||||
int const yo_; // current baseline
|
||||
@ -116,6 +119,7 @@ RowPainter::RowPainter(PainterInfo & pi,
|
||||
LyXText const & text, pit_type pit, Row const & row, int x, int y)
|
||||
: bv_(*pi.base.bv), pain_(pi.pain), text_(text), pars_(text.paragraphs()),
|
||||
row_(row), pit_(pit), par_(text.paragraphs()[pit]),
|
||||
erased_(pi.erased_),
|
||||
xo_(x), yo_(y), width_(text_.width())
|
||||
{
|
||||
RowMetrics m = text_.computeRowMetrics(pit, row_);
|
||||
@ -152,6 +156,7 @@ void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
|
||||
PainterInfo pi(const_cast<BufferView *>(&bv_), pain_);
|
||||
pi.base.font = font;
|
||||
pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
|
||||
pi.erased_ = erased_ || isDeletedText(par_, pos);
|
||||
theCoords.insets().add(inset, int(x_), yo_);
|
||||
inset->drawSelection(pi, int(x_), yo_);
|
||||
inset->draw(pi, int(x_), yo_);
|
||||
@ -299,9 +304,7 @@ void RowPainter::paintFromPos(pos_type & vpos)
|
||||
|
||||
double const orig_x = x_;
|
||||
|
||||
char const c = par_.getChar(pos);
|
||||
|
||||
if (c == Paragraph::META_INSET) {
|
||||
if (par_.isInset(pos)) {
|
||||
paintInset(pos, orig_font);
|
||||
++vpos;
|
||||
paintForeignMark(orig_x, orig_font);
|
||||
@ -309,6 +312,7 @@ void RowPainter::paintFromPos(pos_type & vpos)
|
||||
}
|
||||
|
||||
// usual characters, no insets
|
||||
char const c = par_.getChar(pos);
|
||||
|
||||
// special case languages
|
||||
std::string const & lang = orig_font.language()->lang();
|
||||
|
@ -515,7 +515,7 @@ void LyXTabular::appendColumn(BufferParams const & bp, idx_type const cell)
|
||||
}
|
||||
//++column;
|
||||
for (row_type i = 0; i < rows_; ++i) {
|
||||
cell_info[i][column + 1].inset->clear(false);
|
||||
cell_info[i][column + 1].inset->clear();
|
||||
if (bp.tracking_changes)
|
||||
cell_info[i][column + 1].inset->markNew(true);
|
||||
}
|
||||
@ -1350,7 +1350,7 @@ void LyXTabular::setMultiColumn(Buffer * buffer, idx_type cell,
|
||||
cellstruct & cs1 = cellinfo_of_cell(cell + i);
|
||||
cs1.multicolumn = CELL_PART_OF_MULTICOLUMN;
|
||||
cs.inset->appendParagraphs(buffer, cs1.inset->paragraphs());
|
||||
cs1.inset->clear(false);
|
||||
cs1.inset->clear();
|
||||
}
|
||||
set_row_column_number_info();
|
||||
}
|
||||
|
@ -152,10 +152,8 @@ int numberOfHfills(Paragraph const & par, Row const & row)
|
||||
|
||||
|
||||
void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
|
||||
string const & token, LyXFont & font)
|
||||
string const & token, LyXFont & font, Change & change)
|
||||
{
|
||||
static Change change;
|
||||
|
||||
BufferParams const & bp = buf.params();
|
||||
|
||||
if (token[0] != '\\') {
|
||||
@ -346,10 +344,11 @@ void readParagraph(Buffer const & buf, Paragraph & par, LyXLex & lex)
|
||||
lex.nextToken();
|
||||
string token = lex.getString();
|
||||
LyXFont font;
|
||||
Change change;
|
||||
|
||||
while (lex.isOK()) {
|
||||
|
||||
readParToken(buf, par, lex, token, font);
|
||||
readParToken(buf, par, lex, token, font, change);
|
||||
|
||||
lex.nextToken();
|
||||
token = lex.getString();
|
||||
@ -1989,8 +1988,6 @@ void LyXText::write(Buffer const & buf, std::ostream & os) const
|
||||
|
||||
bool LyXText::read(Buffer const & buf, LyXLex & lex)
|
||||
{
|
||||
static Change current_change;
|
||||
|
||||
Paragraph::depth_type depth = 0;
|
||||
|
||||
while (lex.isOK()) {
|
||||
|
Loading…
Reference in New Issue
Block a user