mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Change tracking cue: paint over labels in text and prepare for further work
* Inset::canTrackChange() had two meanings: can it deal with change tracking? Will it paint its own CT status? The latter information is now given by Inset::canPaintChange(). * Line thickness computation is moved from RowPainter to MetricsBase. * Painting function for Changes moved to lyx::Change. (One new, that strikes diagonally.)
This commit is contained in:
parent
e2bc7ffae3
commit
760bca8265
@ -19,6 +19,7 @@
|
||||
#include "BufferParams.h"
|
||||
#include "Encoding.h"
|
||||
#include "LaTeXFeatures.h"
|
||||
#include "MetricsInfo.h"
|
||||
#include "OutputParams.h"
|
||||
#include "Paragraph.h"
|
||||
#include "TocBackend.h"
|
||||
@ -30,6 +31,8 @@
|
||||
#include "support/mutex.h"
|
||||
|
||||
#include "frontends/alert.h"
|
||||
#include "frontends/FontMetrics.h"
|
||||
#include "frontends/Painter.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
@ -37,6 +40,9 @@ using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
using frontend::Painter;
|
||||
using frontend::FontMetrics;
|
||||
|
||||
/*
|
||||
* Class Change has a changetime field that specifies the exact time at which
|
||||
* a specific change was made. The change time is used as a guidance for the
|
||||
@ -545,6 +551,46 @@ void Changes::updateBuffer(Buffer const & buf)
|
||||
}
|
||||
|
||||
|
||||
void Change::paintCue(PainterInfo & pi, double const x1, double const y,
|
||||
double const x2, FontInfo const & font) const
|
||||
{
|
||||
if (!changed())
|
||||
return;
|
||||
// Calculate 1/3 height of font
|
||||
FontMetrics const & fm = theFontMetrics(font);
|
||||
int const y_bar = deleted() ? y - fm.maxAscent() / 3
|
||||
: y + 2 * pi.base.solidLineOffset() + pi.base.solidLineThickness();
|
||||
pi.pain.line(int(x1), y_bar, int(x2), y_bar, color(),
|
||||
Painter::line_solid, pi.base.solidLineThickness());
|
||||
}
|
||||
|
||||
|
||||
void Change::paintCue(PainterInfo & pi, double const x1, double const y1,
|
||||
double const x2, double const y2) const
|
||||
{
|
||||
/*
|
||||
* y1 /
|
||||
* /
|
||||
* /
|
||||
* /
|
||||
* /
|
||||
* y2 /_____
|
||||
* x1 x2
|
||||
*/
|
||||
double y = 0;
|
||||
switch(type) {
|
||||
case UNCHANGED:
|
||||
return;
|
||||
case INSERTED:
|
||||
y = y2;
|
||||
break;
|
||||
case DELETED:
|
||||
y = y1;
|
||||
break;
|
||||
}
|
||||
pi.pain.line(x1, y2, x2, y, color(), Painter::line_solid,
|
||||
pi.base.solidLineThickness());
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -32,6 +32,8 @@ class AuthorList;
|
||||
class Buffer;
|
||||
class DocIterator;
|
||||
class OutputParams;
|
||||
class PainterInfo;
|
||||
class FontInfo;
|
||||
|
||||
class Change {
|
||||
public:
|
||||
@ -64,6 +66,20 @@ public:
|
||||
/// Is this change made by the current author ?
|
||||
bool currentAuthor() const { return author == 0; }
|
||||
|
||||
/// Paint under- or strike-through line
|
||||
///
|
||||
/// Text : underline or strike through
|
||||
/// \param x1 begin
|
||||
/// \param x2 end
|
||||
/// \param y baseline
|
||||
void paintCue(PainterInfo & pi, double const x1, double const y,
|
||||
double const x2, FontInfo const & font) const;
|
||||
/// Box : line below or diagonal
|
||||
/// \param x1,y1 top-left corner
|
||||
/// \param x2,y2 bottom-right corner
|
||||
void paintCue(PainterInfo & pi, double const x1, double const y1,
|
||||
double const x2, double const y2) const;
|
||||
|
||||
Type type;
|
||||
|
||||
int author;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "BufferView.h"
|
||||
#include "ColorSet.h"
|
||||
#include "LyXRC.h"
|
||||
#include "MetricsInfo.h"
|
||||
|
||||
#include "insets/Inset.h"
|
||||
@ -36,15 +37,33 @@ namespace lyx {
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MetricsBase::MetricsBase()
|
||||
: bv(0), font(), style(LM_ST_TEXT), fontname("mathnormal"),
|
||||
textwidth(0)
|
||||
{}
|
||||
: bv(0), font(), style(LM_ST_TEXT), fontname("mathnormal"), textwidth(0),
|
||||
solid_line_thickness_(1), solid_line_offset_(1), dotted_line_thickness_(1)
|
||||
{
|
||||
if (lyxrc.zoom >= 200) {
|
||||
// derive the line thickness from zoom factor
|
||||
// the zoom is given in percent
|
||||
// (increase thickness at 250%, 450% etc.)
|
||||
solid_line_thickness_ = (lyxrc.zoom + 50) / 200;
|
||||
// adjust line_offset_ too
|
||||
solid_line_offset_ = 1 + solid_line_thickness_ / 2;
|
||||
}
|
||||
if (lyxrc.zoom >= 100) {
|
||||
// derive the line thickness from zoom factor
|
||||
// the zoom is given in percent
|
||||
// (increase thickness at 150%, 250% etc.)
|
||||
dotted_line_thickness_ = (lyxrc.zoom + 50) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MetricsBase::MetricsBase(BufferView * b, FontInfo const & f, int w)
|
||||
: bv(b), font(f), style(LM_ST_TEXT), fontname("mathnormal"),
|
||||
textwidth(w)
|
||||
{}
|
||||
MetricsBase::MetricsBase(BufferView * b, FontInfo f, int w)
|
||||
: MetricsBase()
|
||||
{
|
||||
bv = b;
|
||||
font = f;
|
||||
textwidth = w;
|
||||
}
|
||||
|
||||
|
||||
Changer MetricsBase::changeFontSet(docstring const & name, bool cond)
|
||||
@ -80,8 +99,8 @@ Changer MetricsBase::changeFontSet(char const * name, bool cond)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MetricsInfo::MetricsInfo(BufferView * bv, FontInfo const & font, int textwidth,
|
||||
MacroContext const & mc)
|
||||
MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
|
||||
MacroContext const & mc)
|
||||
: base(bv, font, textwidth), macrocontext(mc)
|
||||
{}
|
||||
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
///
|
||||
MetricsBase();
|
||||
///
|
||||
MetricsBase(BufferView * bv, FontInfo const & font, int textwidth);
|
||||
MetricsBase(BufferView * bv, FontInfo font, int textwidth);
|
||||
|
||||
/// the current view
|
||||
BufferView * bv;
|
||||
@ -76,6 +76,16 @@ public:
|
||||
Changer changeFrac(bool cond = true);
|
||||
// Temporarily change the style to (script)script style
|
||||
Changer changeScript(bool cond = true);
|
||||
///
|
||||
int solidLineThickness() const { return solid_line_thickness_; }
|
||||
///
|
||||
int solidLineOffset() const { return solid_line_offset_; }
|
||||
///
|
||||
int dottedLineThickness() const { return dotted_line_thickness_; }
|
||||
private:
|
||||
int solid_line_thickness_;
|
||||
int solid_line_offset_;
|
||||
int dotted_line_thickness_;
|
||||
};
|
||||
|
||||
|
||||
@ -88,7 +98,8 @@ public:
|
||||
///
|
||||
MetricsInfo();
|
||||
///
|
||||
MetricsInfo(BufferView * bv, FontInfo const & font, int textwidth, MacroContext const & mc);
|
||||
MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
|
||||
MacroContext const & mc);
|
||||
|
||||
///
|
||||
MetricsBase base;
|
||||
|
@ -60,25 +60,8 @@ RowPainter::RowPainter(PainterInfo & pi,
|
||||
pars_(text.paragraphs()),
|
||||
row_(row), par_(text.paragraphs()[row.pit()]),
|
||||
pm_(text_metrics_.parMetrics(row.pit())), change_(pi_.change_),
|
||||
xo_(x), yo_(y), width_(text_metrics_.width()),
|
||||
solid_line_thickness_(1), solid_line_offset_(1),
|
||||
dotted_line_thickness_(1)
|
||||
xo_(x), yo_(y), width_(text_metrics_.width())
|
||||
{
|
||||
if (lyxrc.zoom >= 200) {
|
||||
// derive the line thickness from zoom factor
|
||||
// the zoom is given in percent
|
||||
// (increase thickness at 250%, 450% etc.)
|
||||
solid_line_thickness_ = (lyxrc.zoom + 50) / 200;
|
||||
// adjust line_offset_ too
|
||||
solid_line_offset_ = 1 + solid_line_thickness_ / 2;
|
||||
}
|
||||
if (lyxrc.zoom >= 100) {
|
||||
// derive the line thickness from zoom factor
|
||||
// the zoom is given in percent
|
||||
// (increase thickness at 150%, 250% etc.)
|
||||
dotted_line_thickness_ = (lyxrc.zoom + 50) / 100;
|
||||
}
|
||||
|
||||
x_ = row_.left_margin + xo_;
|
||||
|
||||
//lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
|
||||
@ -165,9 +148,10 @@ void RowPainter::paintForeignMark(Row::Element const & e) const
|
||||
return;
|
||||
|
||||
int const desc = e.inset ? e.dim.descent() : 0;
|
||||
int const y = yo_ + solid_line_offset_ + desc + solid_line_thickness_ / 2;
|
||||
int const y = yo_ + pi_.base.solidLineOffset()
|
||||
+ desc + pi_.base.solidLineThickness() / 2;
|
||||
pi_.pain.line(int(x_), y, int(x_ + e.full_width()), y, Color_language,
|
||||
Painter::line_solid, solid_line_thickness_);
|
||||
Painter::line_solid, pi_.base.solidLineThickness());
|
||||
}
|
||||
|
||||
|
||||
@ -177,8 +161,8 @@ void RowPainter::paintMisspelledMark(Row::Element const & e) const
|
||||
// to avoid drawing at the same vertical offset
|
||||
FontMetrics const & fm = theFontMetrics(e.font);
|
||||
int const thickness = max(fm.lineWidth(), 2);
|
||||
int const y = yo_ + solid_line_offset_ + solid_line_thickness_
|
||||
+ (e.change.changed() ? solid_line_thickness_ + 1 : 0)
|
||||
int const y = yo_ + pi_.base.solidLineOffset() + pi_.base.solidLineThickness()
|
||||
+ (e.change.changed() ? pi_.base.solidLineThickness() + 1 : 0)
|
||||
+ 1 + thickness / 2;
|
||||
|
||||
//FIXME: this could be computed only once, it is probably not costly.
|
||||
@ -255,14 +239,7 @@ void RowPainter::paintStringAndSel(Row::Element const & e) const
|
||||
|
||||
void RowPainter::paintChange(Row::Element const & e) const
|
||||
{
|
||||
if (!e.change.changed())
|
||||
return;
|
||||
// Calculate 1/3 height of font
|
||||
FontMetrics const & fm = theFontMetrics(e.font);
|
||||
int const y_bar = e.change.deleted() ? yo_ - fm.maxAscent() / 3
|
||||
: yo_ + 2 * solid_line_offset_ + solid_line_thickness_;
|
||||
pi_.pain.line(int(x_), y_bar, int(x_ + e.full_width()), y_bar,
|
||||
e.change.color(), Painter::line_solid, solid_line_thickness_);
|
||||
e.change.paintCue(pi_, x_, yo_, x_ + e.full_width(), e.font.fontInfo());
|
||||
}
|
||||
|
||||
|
||||
@ -373,16 +350,17 @@ void RowPainter::paintAppendixStart(int y) const
|
||||
void RowPainter::paintTooLargeMarks(bool const left, bool const right) const
|
||||
{
|
||||
if (left)
|
||||
pi_.pain.line(dotted_line_thickness_, yo_ - row_.ascent(),
|
||||
dotted_line_thickness_, yo_ + row_.descent(),
|
||||
Color_scroll,
|
||||
Painter::line_onoffdash, dotted_line_thickness_);
|
||||
pi_.pain.line(pi_.base.dottedLineThickness(), yo_ - row_.ascent(),
|
||||
pi_.base.dottedLineThickness(), yo_ + row_.descent(),
|
||||
Color_scroll, Painter::line_onoffdash,
|
||||
pi_.base.dottedLineThickness());
|
||||
if (right) {
|
||||
int const wwidth = pi_.base.bv->workWidth() - dotted_line_thickness_;
|
||||
int const wwidth =
|
||||
pi_.base.bv->workWidth() - pi_.base.dottedLineThickness();
|
||||
pi_.pain.line(wwidth, yo_ - row_.ascent(),
|
||||
wwidth, yo_ + row_.descent(),
|
||||
Color_scroll,
|
||||
Painter::line_onoffdash, dotted_line_thickness_);
|
||||
Color_scroll, Painter::line_onoffdash,
|
||||
pi_.base.dottedLineThickness());
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,8 +589,8 @@ void RowPainter::paintText()
|
||||
// The line that indicates word in a different language
|
||||
paintForeignMark(e);
|
||||
|
||||
// change tracking (not for insets that track their own changes)
|
||||
if (e.type != Row::INSET || ! e.inset->canTrackChanges())
|
||||
// change tracking (not for insets that handle it themselves)
|
||||
if (e.type != Row::INSET || ! e.inset->canPaintChange(*pi_.base.bv))
|
||||
paintChange(e);
|
||||
|
||||
x_ += e.full_width();
|
||||
|
@ -97,9 +97,6 @@ private:
|
||||
int const yo_; // current baseline
|
||||
double x_;
|
||||
int width_;
|
||||
int solid_line_thickness_;
|
||||
int solid_line_offset_;
|
||||
int dotted_line_thickness_;
|
||||
};
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -352,6 +352,9 @@ public:
|
||||
|
||||
/// does this contain text that can be change track marked in DVI?
|
||||
virtual bool canTrackChanges() const { return false; }
|
||||
/// Will this inset paint its own change tracking status (in the parent
|
||||
/// paragraph) or will it let RowPainter handle it?
|
||||
virtual bool canPaintChange(BufferView const &) const { return false; }
|
||||
/// return true if the inset should be removed automatically
|
||||
virtual bool autoDelete() const;
|
||||
|
||||
|
@ -615,4 +615,21 @@ string InsetCollapsable::contextMenuName() const
|
||||
return "context-collapsable";
|
||||
}
|
||||
|
||||
|
||||
bool InsetCollapsable::canPaintChange(BufferView const & bv) const
|
||||
{
|
||||
switch (geometry(bv)) {
|
||||
case Corners:
|
||||
case SubLabel:
|
||||
case ButtonOnly:
|
||||
// these cases are handled by RowPainter since the inset is inline.
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// TODO: implement the drawing in the remaining cases
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -127,6 +127,8 @@ public:
|
||||
/// and of course decoration().
|
||||
Geometry geometry(BufferView const & bv) const;
|
||||
///
|
||||
bool canPaintChange(BufferView const & bv) const;
|
||||
///
|
||||
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
|
||||
///
|
||||
bool setMouseHover(BufferView const * bv, bool mouse_hover) const;
|
||||
|
@ -877,6 +877,8 @@ public:
|
||||
bool allowSpellCheck() const { return true; }
|
||||
///
|
||||
bool canTrackChanges() const { return true; }
|
||||
///
|
||||
bool canPaintChange(BufferView const &) const { return true; }
|
||||
/** returns false if, when outputing LaTeX, font changes should
|
||||
be closed before generating this inset. This is needed for
|
||||
insets that may contain several paragraphs */
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
///
|
||||
bool canTrackChanges() const { return true; }
|
||||
///
|
||||
bool canPaintChange(BufferView const &) const { return false; }
|
||||
///
|
||||
InsetText * asInsetText() { return this; }
|
||||
///
|
||||
InsetText const * asInsetText() const { return this; }
|
||||
|
Loading…
Reference in New Issue
Block a user