diff --git a/src/Changes.cpp b/src/Changes.cpp index 7b711172ec..c2677736cd 100644 --- a/src/Changes.cpp +++ b/src/Changes.cpp @@ -39,7 +39,7 @@ namespace lyx { * the later change time is preserved. */ -bool Change::isSimilarTo(Change const & change) +bool Change::isSimilarTo(Change const & change) const { if (type != change.type) return false; @@ -51,6 +51,30 @@ bool Change::isSimilarTo(Change const & change) } +ColorCode Change::color() const +{ + ColorCode color = Color_none; + switch (author % 5) { + case 0: + color = Color_changedtextauthor1; + break; + case 1: + color = Color_changedtextauthor2; + break; + case 2: + color = Color_changedtextauthor3; + break; + case 3: + color = Color_changedtextauthor4; + break; + case 4: + color = Color_changedtextauthor5; + break; + } + return color; +} + + bool operator==(Change const & l, Change const & r) { if (l.type != r.type) diff --git a/src/Changes.h b/src/Changes.h index 8f91407431..631419bc30 100644 --- a/src/Changes.h +++ b/src/Changes.h @@ -15,6 +15,8 @@ #ifndef CHANGES_H #define CHANGES_H +#include "ColorCode.h" + #include "support/strfwd.h" #include "support/types.h" #include "support/lyxtime.h" @@ -35,11 +37,25 @@ public: DELETED // deleted text }; - explicit Change(Type t, int a = 0, time_t ct = current_time()) + explicit Change(Type t = UNCHANGED, int a = 0, time_t ct = current_time()) : type(t), author(a), changetime(ct) {} /// is the change similar to the given change such that both can be merged? - bool isSimilarTo(Change const & change); + bool isSimilarTo(Change const & change) const; + /// The color of this change on screen + ColorCode color() const; + /// + bool changed() const { return type != UNCHANGED; } + /// + void setUnchanged() { type = UNCHANGED; } + /// + bool inserted() const { return type == INSERTED; } + /// + void setInserted() { type = INSERTED; } + /// + bool deleted() const { return type == DELETED; } + /// + void setDeleted() { type = DELETED; } Type type; diff --git a/src/Color.cpp b/src/Color.cpp index 27012290a7..b64e042b56 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -158,6 +158,11 @@ ColorSet::ColorSet() { Color_changebar, N_("change bar"), "changebar", "Blue", "changebar" }, { Color_deletedtext, N_("Deleted text"), "deletedtext", "#ff0000", "deletedtext" }, { Color_addedtext, N_("Added text"), "addedtext", "#0000ff", "addedtext" }, + { Color_changedtextauthor1, N_("changed text 1st author"), "changedtextauthor1", "#0000ff", "changedtextauthor1" }, + { Color_changedtextauthor2, N_("changed text 2nd author"), "changedtextauthor2", "#ff00ff", "changedtextauthor2" }, + { Color_changedtextauthor3, N_("changed text 3rd author"), "changedtextauthor3", "#ff0000", "changedtextauthor3" }, + { Color_changedtextauthor4, N_("changed text 4th author"), "changedtextauthor4", "#aa00ff", "changedtextauthor4" }, + { Color_changedtextauthor5, N_("changed text 5th author"), "changedtextauthor5", "#55aa00", "changedtextauthor5" }, { Color_added_space, N_("added space markers"), "added_space", "Brown", "added_space" }, { Color_topline, N_("top/bottom line"), "topline", "Brown", "topline" }, { Color_tabularline, N_("table line"), "tabularline", "black", "tabularline" }, diff --git a/src/ColorCode.h b/src/ColorCode.h index 707eadb0c3..744eb51ca8 100644 --- a/src/ColorCode.h +++ b/src/ColorCode.h @@ -155,6 +155,16 @@ enum ColorCode Color_deletedtext, /// added text color Color_addedtext, + /// changed text color author 1 + Color_changedtextauthor1, + /// changed text color author 2 + Color_changedtextauthor2, + /// changed text color author 3 + Color_changedtextauthor3, + /// changed text color author 4 + Color_changedtextauthor4, + /// changed text color author 5 + Color_changedtextauthor5, /// Top and bottom line color Color_topline, /// Table line color diff --git a/src/rowpainter.cpp b/src/rowpainter.cpp index 98e79de498..7d391a68ae 100644 --- a/src/rowpainter.cpp +++ b/src/rowpainter.cpp @@ -241,7 +241,8 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font, pos_type const end = row_.endpos(); FontSpan const font_span = par_.fontSpan(pos); // Track-change status. - Change::Type const change_type = par_.lookupChange(pos).type; + Change const & change_running = par_.lookupChange(pos); + // selected text? bool const selection = pos >= row_.sel_beg && pos < row_.sel_end; @@ -256,8 +257,9 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font, // Selection ends or starts here. break; - if (change_type != par_.lookupChange(pos).type) - // Track change type has changed. + Change const & change = par_.lookupChange(pos); + if (!change_running.isSimilarTo(change)) + // Track change type or author has changed. break; char_type c = par_.getChar(pos); @@ -306,16 +308,14 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font, docstring s(&str[0], str.size()); - if (!selection && change_type == Change::UNCHANGED) { + if (!selection && !change_running.changed()) { x_ += pi_.pain.text(int(x_), yo_, s, font); return; } FontInfo copy = font; - if (change_type == Change::DELETED) - copy.setColor(Color_deletedtext); - else if (change_type == Change::INSERTED) - copy.setColor(Color_addedtext); + if (change_running.changed()) + copy.setColor(change_running.color()); else if (selection) copy.setColor(Color_selectiontext); @@ -601,15 +601,24 @@ void RowPainter::paintLast() // paint imaginary end-of-paragraph character - if (par_.isInserted(par_.size()) || par_.isDeleted(par_.size())) { - FontMetrics const & fm = theFontMetrics(pi_.base.bv->buffer().params().getFont()); + Change const & change = par_.lookupChange(par_.size()); + if (change.changed()) { + FontMetrics const & fm = + theFontMetrics(pi_.base.bv->buffer().params().getFont()); int const length = fm.maxAscent() / 2; - ColorCode col = par_.isInserted(par_.size()) ? Color_addedtext : Color_deletedtext; + ColorCode col = change.color(); pi_.pain.line(int(x_) + 1, yo_ + 2, int(x_) + 1, yo_ + 2 - length, col, Painter::line_solid, Painter::line_thick); - pi_.pain.line(int(x_) + 1 - length, yo_ + 2, int(x_) + 1, yo_ + 2, col, - Painter::line_solid, Painter::line_thick); + + if (change.deleted()) { + pi_.pain.line(int(x_) + 1 - length, yo_ + 2, int(x_) + 1 + length, + yo_ + 2, col, Painter::line_solid, Painter::line_thick); + } else { + pi_.pain.line(int(x_) + 1 - length, yo_ + 2, int(x_) + 1, + yo_ + 2, col, Painter::line_solid, Painter::line_thick); + } + } // draw an endlabel @@ -687,10 +696,9 @@ void RowPainter::paintText() Layout const & layout = par_.layout(); - bool running_strikeout = false; - bool is_struckout = false; - int last_strikeout_x = 0; - + Change change_running; + int change_last_x = 0; + // check for possible inline completion DocIterator const & inlineCompletionPos = pi_.base.bv->inlineCompletionPos(); pos_type inlineCompletionVPos = -1; @@ -747,28 +755,35 @@ void RowPainter::paintText() ++vpos; continue; } - - is_struckout = par_.isDeleted(pos); - - if (is_struckout && !running_strikeout) { - running_strikeout = true; - last_strikeout_x = int(x_); + Change const & change = par_.lookupChange(pos); + if (change.changed() && !change_running.changed()) { + change_running = change; + change_last_x = int(x_); } Inset const * inset = par_.getInset(pos); bool const highly_editable_inset = inset && inset->editable() == Inset::HIGHLY_EDITABLE; - // If we reach the end of a struck out range, paint it. + // If we reach the end of a change or if the author changes, paint it. // We also don't paint across things like tables - if (running_strikeout && (highly_editable_inset || !is_struckout)) { + if (change_running.changed() && (highly_editable_inset + || !change.changed() || !change_running.isSimilarTo(change))) { // Calculate 1/3 height of the buffer's default font FontMetrics const & fm = theFontMetrics(pi_.base.bv->buffer().params().getFont()); - int const middle = yo_ - fm.maxAscent() / 3; - pi_.pain.line(last_strikeout_x, middle, int(x_), middle, - Color_deletedtext, Painter::line_solid, Painter::line_thin); - running_strikeout = false; + int const y_bar = change_running.deleted() ? + yo_ - fm.maxAscent() / 3 : yo_ + fm.maxAscent() / 6; + pi_.pain.line(change_last_x, y_bar, int(x_), y_bar, + change_running.color(), Painter::line_solid, + Painter::line_thin); + + // Change might continue with a different author or type + if (change.changed() && !highly_editable_inset) { + change_running = change; + change_last_x = int(x_); + } else + change_running.setUnchanged(); } if (body_pos > 0 && pos == body_pos - 1) { @@ -808,14 +823,14 @@ void RowPainter::paintText() } // if we reach the end of a struck out range, paint it - if (running_strikeout) { - // calculate 1/3 height of the buffer's default font + if (change_running.changed()) { FontMetrics const & fm = theFontMetrics(pi_.base.bv->buffer().params().getFont()); - int const middle = yo_ - fm.maxAscent() / 3; - pi_.pain.line(last_strikeout_x, middle, int(x_), middle, - Color_deletedtext, Painter::line_solid, Painter::line_thin); - running_strikeout = false; + int const y_bar = change_running.deleted() ? + yo_ - fm.maxAscent() / 3 : yo_ + fm.maxAscent() / 6; + pi_.pain.line(change_last_x, y_bar, int(x_), y_bar, + change_running.color(), Painter::line_solid, Painter::line_thin); + change_running.setUnchanged(); } }