From 52a2eb2c52bd990b44c35927338341fb6aefa4b0 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 7 Sep 2005 10:37:05 +0000 Subject: [PATCH] John&JMarc's change tracking patch git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10424 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 29 +++++++++++++++++++++++++++ src/insets/ChangeLog | 17 ++++++++++++++++ src/insets/insetbase.C | 2 +- src/insets/insetbase.h | 6 +++--- src/insets/insettabular.C | 41 ++++++++++++++++++++++++++------------- src/insets/insettabular.h | 4 ++-- src/insets/insettext.C | 19 ++++++++++-------- src/insets/insettext.h | 7 ++++--- src/lyxfunc.C | 31 +++++++++++++++++++++++++++++ src/metricsinfo.C | 2 +- src/metricsinfo.h | 2 ++ src/paragraph.C | 4 ++-- src/paragraph.h | 4 ++-- src/paragraph_pimpl.C | 29 ++++++++++++++++----------- src/paragraph_pimpl.h | 2 +- src/rowpainter.C | 10 +++++++--- src/tabular.C | 4 ++-- src/text.C | 9 +++------ 18 files changed, 163 insertions(+), 59 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a667b441a1..39d240e13d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2005-08-03 Jean-Marc Lasgouttes + + * 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 + + * 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 * lyxfind.C (findNextChange): tiny cleanup. diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index 2b99c1c14b..d7cf4199e4 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,20 @@ +2005-08-03 Jean-Marc Lasgouttes + + * insettabular.C (draw): pass PainterInfro::erased_ to + drawCellLines + (drawCellLines): add an erased bool and handle it. + +2005-08-03 John Levon + + * 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 * insettabular.C: mark tabular_stack_ (of CutAndPaste) dirty diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index 6ae08685df..0736f60fc4 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -273,7 +273,7 @@ std::string const & InsetBase::getInsetName() const } -void InsetBase::markErased() +void InsetBase::markErased(bool) {} diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 7c496f256b..37c0e6cb42 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -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 diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 93d063c772..30a26e8a83 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -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 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); } diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index 3a421375eb..b4bba0227f 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -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; diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 61ce57fe8a..8bc16c1b85 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -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); diff --git a/src/insets/insettext.h b/src/insets/insettext.h index 65bdbedd8e..0914da33a2 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -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 diff --git a/src/lyxfunc.C b/src/lyxfunc.C index ff41335154..3edf198430 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -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")); diff --git a/src/metricsinfo.C b/src/metricsinfo.C index 0e6a2aac8d..9d6568640c 100644 --- a/src/metricsinfo.C +++ b/src/metricsinfo.C @@ -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; } diff --git a/src/metricsinfo.h b/src/metricsinfo.h index d3ff26ad3b..ad9b33f677 100644 --- a/src/metricsinfo.h +++ b/src/metricsinfo.h @@ -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 {}; diff --git a/src/paragraph.C b/src/paragraph.C index 36eafed96a..12d91ccb62 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -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); } diff --git a/src/paragraph.h b/src/paragraph.h index ecf745159f..13c99ca873 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -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 diff --git a/src/paragraph_pimpl.C b/src/paragraph_pimpl.C index 0606d440f0..f5ca835b38 100644 --- a/src/paragraph_pimpl.C +++ b/src/paragraph_pimpl.C @@ -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; } } diff --git a/src/paragraph_pimpl.h b/src/paragraph_pimpl.h index 5d15a82ec3..ed2e809270 100644 --- a/src/paragraph_pimpl.h +++ b/src/paragraph_pimpl.h @@ -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 diff --git a/src/rowpainter.C b/src/rowpainter.C index 6f285643ab..d59934d19e 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -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(&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(); diff --git a/src/tabular.C b/src/tabular.C index 334e2151ef..7775055f3e 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -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(); } diff --git a/src/text.C b/src/text.C index 8726bed96b..fa9ab877ad 100644 --- a/src/text.C +++ b/src/text.C @@ -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()) {