Partial cleanup of the row selection code

This is preliminary work, this code still feels too complicated for
its own good.

Let Row::isMarginSelected return false when Row::selection() is false
(the other changes are indentation).

This allows to remove the test for selection() in
setSelectionAndMargins, so that begin/end_margin_sel are always set
correctly.

Add clearSelectionAndMargins() instead of calling directly setSelection
(which is now private) with arguments (-1, -1).

Fixes bug #10972.
This commit is contained in:
Jean-Marc Lasgouttes 2018-01-15 16:14:21 +01:00
parent 0bc542ab7e
commit 654cded167
3 changed files with 40 additions and 32 deletions

View File

@ -175,25 +175,24 @@ bool Row::isMarginSelected(bool left, DocIterator const & beg,
pos_type const sel_pos = left ? sel_beg : sel_end; pos_type const sel_pos = left ? sel_beg : sel_end;
pos_type const margin_pos = left ? pos_ : end_; pos_type const margin_pos = left ? pos_ : end_;
// Is the chosen margin selected ? // Is there a selection and is the chosen margin selected ?
if (sel_pos == margin_pos) { if (!selection() || sel_pos != margin_pos)
if (beg.pos() == end.pos()) return false;
// This is a special case in which the space between after else if (beg.pos() == end.pos())
// pos i-1 and before pos i is selected, i.e. the margins // This is a special case in which the space between after
// (see DocIterator::boundary_). // pos i-1 and before pos i is selected, i.e. the margins
return beg.boundary() && !end.boundary(); // (see DocIterator::boundary_).
else if (end.pos() == margin_pos) return beg.boundary() && !end.boundary();
// If the selection ends around the margin, it is only else if (end.pos() == margin_pos)
// drawn if the cursor is after the margin. // If the selection ends around the margin, it is only
return !end.boundary(); // drawn if the cursor is after the margin.
else if (beg.pos() == margin_pos) return !end.boundary();
// If the selection begins around the margin, it is else if (beg.pos() == margin_pos)
// only drawn if the cursor is before the margin. // If the selection begins around the margin, it is
return beg.boundary(); // only drawn if the cursor is before the margin.
else return beg.boundary();
return true; else
} return true;
return false;
} }
@ -202,10 +201,17 @@ void Row::setSelectionAndMargins(DocIterator const & beg,
{ {
setSelection(beg.pos(), end.pos()); setSelection(beg.pos(), end.pos());
if (selection()) { change(end_margin_sel, isMarginSelected(false, beg, end));
change(end_margin_sel, isMarginSelected(false, beg, end)); change(begin_margin_sel, isMarginSelected(true, beg, end));
change(begin_margin_sel, isMarginSelected(true, beg, end)); }
}
void Row::clearSelectionAndMargins() const
{
change(sel_beg, -1);
change(sel_end, -1);
change(end_margin_sel, false);
change(begin_margin_sel, false);
} }

View File

@ -163,18 +163,18 @@ public:
bool changed() const { return changed_; } bool changed() const { return changed_; }
/// ///
void changed(bool c) const { changed_ = c; } void changed(bool c) const { changed_ = c; }
/// Set the selection begin and end.
/**
* This is const because we update the selection status only at draw()
* time.
*/
void setSelection(pos_type sel_beg, pos_type sel_end) const;
/// ///
bool selection() const; bool selection() const;
/// Set the selection begin and end and whether the left and/or right /**
/// margins are selected. * Set the selection begin and end and whether the left and/or
* right margins are selected.
* This is const because we update the selection status only at
* draw() time.
*/
void setSelectionAndMargins(DocIterator const & beg, void setSelectionAndMargins(DocIterator const & beg,
DocIterator const & end) const; DocIterator const & end) const;
/// no selection on this row.
void clearSelectionAndMargins() const;
/// ///
void pit(pit_type p) { pit_ = p; } void pit(pit_type p) { pit_ = p; }
@ -323,6 +323,8 @@ private:
*/ */
bool isMarginSelected(bool left, DocIterator const & beg, bool isMarginSelected(bool left, DocIterator const & beg,
DocIterator const & end) const; DocIterator const & end) const;
/// Set the selection begin and end.
void setSelection(pos_type sel_beg, pos_type sel_end) const;
/** /**
* Returns true if a char or string with font \c f and change * Returns true if a char or string with font \c f and change

View File

@ -1878,7 +1878,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
if (selection) if (selection)
row.setSelectionAndMargins(sel_beg_par, sel_end_par); row.setSelectionAndMargins(sel_beg_par, sel_end_par);
else else
row.setSelection(-1, -1); row.clearSelectionAndMargins();
// The row knows nothing about the paragraph, so we have to check // The row knows nothing about the paragraph, so we have to check
// whether this row is the first or last and update the margins. // whether this row is the first or last and update the margins.