Colors for multi-author track changes.

Patch by Vincent.

http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg143215.html


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26497 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Pavel Sanda 2008-09-22 15:30:26 +00:00
parent 76b64cded1
commit 29e02eff76
5 changed files with 108 additions and 38 deletions

View File

@ -39,7 +39,7 @@ namespace lyx {
* the later change time is preserved. * the later change time is preserved.
*/ */
bool Change::isSimilarTo(Change const & change) bool Change::isSimilarTo(Change const & change) const
{ {
if (type != change.type) if (type != change.type)
return false; 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) bool operator==(Change const & l, Change const & r)
{ {
if (l.type != r.type) if (l.type != r.type)

View File

@ -15,6 +15,8 @@
#ifndef CHANGES_H #ifndef CHANGES_H
#define CHANGES_H #define CHANGES_H
#include "ColorCode.h"
#include "support/strfwd.h" #include "support/strfwd.h"
#include "support/types.h" #include "support/types.h"
#include "support/lyxtime.h" #include "support/lyxtime.h"
@ -35,11 +37,25 @@ public:
DELETED // deleted text 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) {} : type(t), author(a), changetime(ct) {}
/// is the change similar to the given change such that both can be merged? /// 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; Type type;

View File

@ -158,6 +158,11 @@ ColorSet::ColorSet()
{ Color_changebar, N_("change bar"), "changebar", "Blue", "changebar" }, { Color_changebar, N_("change bar"), "changebar", "Blue", "changebar" },
{ Color_deletedtext, N_("Deleted text"), "deletedtext", "#ff0000", "deletedtext" }, { Color_deletedtext, N_("Deleted text"), "deletedtext", "#ff0000", "deletedtext" },
{ Color_addedtext, N_("Added text"), "addedtext", "#0000ff", "addedtext" }, { 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_added_space, N_("added space markers"), "added_space", "Brown", "added_space" },
{ Color_topline, N_("top/bottom line"), "topline", "Brown", "topline" }, { Color_topline, N_("top/bottom line"), "topline", "Brown", "topline" },
{ Color_tabularline, N_("table line"), "tabularline", "black", "tabularline" }, { Color_tabularline, N_("table line"), "tabularline", "black", "tabularline" },

View File

@ -155,6 +155,16 @@ enum ColorCode
Color_deletedtext, Color_deletedtext,
/// added text color /// added text color
Color_addedtext, 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 /// Top and bottom line color
Color_topline, Color_topline,
/// Table line color /// Table line color

View File

@ -241,7 +241,8 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font,
pos_type const end = row_.endpos(); pos_type const end = row_.endpos();
FontSpan const font_span = par_.fontSpan(pos); FontSpan const font_span = par_.fontSpan(pos);
// Track-change status. // Track-change status.
Change::Type const change_type = par_.lookupChange(pos).type; Change const & change_running = par_.lookupChange(pos);
// selected text? // selected text?
bool const selection = pos >= row_.sel_beg && pos < row_.sel_end; 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. // Selection ends or starts here.
break; break;
if (change_type != par_.lookupChange(pos).type) Change const & change = par_.lookupChange(pos);
// Track change type has changed. if (!change_running.isSimilarTo(change))
// Track change type or author has changed.
break; break;
char_type c = par_.getChar(pos); 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()); 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); x_ += pi_.pain.text(int(x_), yo_, s, font);
return; return;
} }
FontInfo copy = font; FontInfo copy = font;
if (change_type == Change::DELETED) if (change_running.changed())
copy.setColor(Color_deletedtext); copy.setColor(change_running.color());
else if (change_type == Change::INSERTED)
copy.setColor(Color_addedtext);
else if (selection) else if (selection)
copy.setColor(Color_selectiontext); copy.setColor(Color_selectiontext);
@ -601,15 +601,24 @@ void RowPainter::paintLast()
// paint imaginary end-of-paragraph character // paint imaginary end-of-paragraph character
if (par_.isInserted(par_.size()) || par_.isDeleted(par_.size())) { Change const & change = par_.lookupChange(par_.size());
FontMetrics const & fm = theFontMetrics(pi_.base.bv->buffer().params().getFont()); if (change.changed()) {
FontMetrics const & fm =
theFontMetrics(pi_.base.bv->buffer().params().getFont());
int const length = fm.maxAscent() / 2; 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, pi_.pain.line(int(x_) + 1, yo_ + 2, int(x_) + 1, yo_ + 2 - length, col,
Painter::line_solid, Painter::line_thick); 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 // draw an endlabel
@ -687,10 +696,9 @@ void RowPainter::paintText()
Layout const & layout = par_.layout(); Layout const & layout = par_.layout();
bool running_strikeout = false; Change change_running;
bool is_struckout = false; int change_last_x = 0;
int last_strikeout_x = 0;
// check for possible inline completion // check for possible inline completion
DocIterator const & inlineCompletionPos = pi_.base.bv->inlineCompletionPos(); DocIterator const & inlineCompletionPos = pi_.base.bv->inlineCompletionPos();
pos_type inlineCompletionVPos = -1; pos_type inlineCompletionVPos = -1;
@ -747,28 +755,35 @@ void RowPainter::paintText()
++vpos; ++vpos;
continue; continue;
} }
Change const & change = par_.lookupChange(pos);
is_struckout = par_.isDeleted(pos); if (change.changed() && !change_running.changed()) {
change_running = change;
if (is_struckout && !running_strikeout) { change_last_x = int(x_);
running_strikeout = true;
last_strikeout_x = int(x_);
} }
Inset const * inset = par_.getInset(pos); Inset const * inset = par_.getInset(pos);
bool const highly_editable_inset = inset bool const highly_editable_inset = inset
&& inset->editable() == Inset::HIGHLY_EDITABLE; && 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 // 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 // Calculate 1/3 height of the buffer's default font
FontMetrics const & fm FontMetrics const & fm
= theFontMetrics(pi_.base.bv->buffer().params().getFont()); = theFontMetrics(pi_.base.bv->buffer().params().getFont());
int const middle = yo_ - fm.maxAscent() / 3; int const y_bar = change_running.deleted() ?
pi_.pain.line(last_strikeout_x, middle, int(x_), middle, yo_ - fm.maxAscent() / 3 : yo_ + fm.maxAscent() / 6;
Color_deletedtext, Painter::line_solid, Painter::line_thin); pi_.pain.line(change_last_x, y_bar, int(x_), y_bar,
running_strikeout = false; 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) { 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 we reach the end of a struck out range, paint it
if (running_strikeout) { if (change_running.changed()) {
// calculate 1/3 height of the buffer's default font
FontMetrics const & fm FontMetrics const & fm
= theFontMetrics(pi_.base.bv->buffer().params().getFont()); = theFontMetrics(pi_.base.bv->buffer().params().getFont());
int const middle = yo_ - fm.maxAscent() / 3; int const y_bar = change_running.deleted() ?
pi_.pain.line(last_strikeout_x, middle, int(x_), middle, yo_ - fm.maxAscent() / 3 : yo_ + fm.maxAscent() / 6;
Color_deletedtext, Painter::line_solid, Painter::line_thin); pi_.pain.line(change_last_x, y_bar, int(x_), y_bar,
running_strikeout = false; change_running.color(), Painter::line_solid, Painter::line_thin);
change_running.setUnchanged();
} }
} }