Commit 836b1d98 authored by Luis Javier Merino's avatar Luis Javier Merino Committed by Tomaz Canabrava
Browse files

Selecting past last char -> extend to last column

When selecting past the last character, extend the selection to the last
column.  This allows the user to know when the selection has extended
past the last character on a line, even in the presence of trailing
spaces, and will get a newline added to the last line.

This is the behavior of xterm, VTE and rxvt.  mlterm doesn't allow
selections to extend past the last non-space character on a line.

BUG: 413426
CCBUG: 158726
parent 9046680f
Pipeline #181004 passed with stage
in 2 minutes and 13 seconds
......@@ -1459,7 +1459,7 @@ void Screen::setSelectionStart(const int x, const int y, const bool blockSelecti
_blockSelectionMode = blockSelectionMode;
}
void Screen::setSelectionEnd(const int x, const int y)
void Screen::setSelectionEnd(const int x, const int y, const bool trimTrailingWhitespace)
{
if (_selBegin == -1) {
return;
......@@ -1480,8 +1480,8 @@ void Screen::setSelectionEnd(const int x, const int y)
_selBottomRight = endPos;
}
// Normalize the selection in column mode
if (_blockSelectionMode) {
// Normalize the selection in column mode
const int topRow = _selTopLeft / _columns;
const int topColumn = _selTopLeft % _columns;
const int bottomRow = _selBottomRight / _columns;
......@@ -1489,6 +1489,40 @@ void Screen::setSelectionEnd(const int x, const int y)
_selTopLeft = loc(qMin(topColumn, bottomColumn), topRow);
_selBottomRight = loc(qMax(topColumn, bottomColumn), bottomRow);
} else {
// Extend the selection to the rightmost column if beyond the last character in the line
const int bottomRow = _selBottomRight / _columns;
const int bottomColumn = _selBottomRight % _columns;
bool beyondLastColumn = true;
if (bottomRow < _history->getLines()) {
ImageLine histLine;
const int histLineLen = _history->getLineLen(bottomRow);
histLine.resize(histLineLen);
_history->getCells(bottomRow, 0, histLineLen, histLine.data());
for (int x = bottomColumn; x < histLineLen; x++) {
if (histLine.at(x).isRealCharacter && (!trimTrailingWhitespace || !QChar(histLine.at(x).character).isSpace())) {
beyondLastColumn = false;
}
}
} else {
const size_t line = bottomRow - _history->getLines();
const int lastColumn = (line < _lineProperties.size() && _lineProperties[line] & LINE_DOUBLEWIDTH) ? _columns / 2 : _columns;
const auto *data = _screenLines[line].data();
const int length = _screenLines.at(line).count();
for (int x = bottomColumn; x < lastColumn && x < length; x++) {
if (data[x].isRealCharacter && (!trimTrailingWhitespace || !QChar(data[x].character).isSpace())) {
beyondLastColumn = false;
}
}
}
if (beyondLastColumn) {
_selBottomRight = loc(_columns - 1, bottomRow);
}
}
}
......
......@@ -452,8 +452,9 @@ public:
*
* @param x The column index of the last character in the selection.
* @param y The line index of the last character in the selection.
* @param trimTrailingWhitespace True if trailing whitespace is trimmed from the selection
*/
void setSelectionEnd(const int x, const int y);
void setSelectionEnd(const int x, const int y, const bool trimTrailingWhitespace);
/**
* Retrieves the start of the selection or the cursor position if there
......
......@@ -140,9 +140,9 @@ void ScreenWindow::setSelectionStart(int column, int line, bool columnMode)
Q_EMIT selectionChanged();
}
void ScreenWindow::setSelectionEnd(int column, int line)
void ScreenWindow::setSelectionEnd(int column, int line, bool trimTrailingWhitespace)
{
_screen->setSelectionEnd(column, line + currentLine());
_screen->setSelectionEnd(column, line + currentLine(), trimTrailingWhitespace);
_bufferNeedsUpdate = true;
Q_EMIT selectionChanged();
......@@ -153,7 +153,7 @@ void ScreenWindow::setSelectionByLineRange(int start, int end)
clearSelection();
_screen->setSelectionStart(0, start, false);
_screen->setSelectionEnd(windowColumns(), end);
_screen->setSelectionEnd(windowColumns(), end, false);
_bufferNeedsUpdate = true;
Q_EMIT selectionChanged();
......
......@@ -114,7 +114,7 @@ public:
* Sets the end of the selection to the given @p line and @p column within
* the window.
*/
void setSelectionEnd(int column, int line);
void setSelectionEnd(int column, int line, bool trimTrailingWhitespace);
/**
* Sets the selection as the range specified by line @p start and line @p
......
......@@ -24,7 +24,7 @@ void ScreenTest::doLargeScreenCopyVerification(const QString &putToScreen, const
}
screen.setSelectionStart(0, 0, false);
screen.setSelectionEnd(largeScreenColumns, 0);
screen.setSelectionEnd(largeScreenColumns, 0, false);
QCOMPARE(screen.selectedText(Screen::PlainText), expectedSelection);
}
......@@ -55,7 +55,7 @@ void ScreenTest::testBlockSelection()
// True here means block selection.
screen.setSelectionStart(0, 0, true);
screen.setSelectionEnd(3, 1);
screen.setSelectionEnd(3, 1, false);
// after the resize, the string should be:
// abcd efgh
......
......@@ -1491,9 +1491,9 @@ void TerminalDisplay::extendSelection(const QPoint &position)
_pntSel.ry() += _scrollBar->value();
if (_columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode) {
_screenWindow->setSelectionEnd(here.x(), here.y());
_screenWindow->setSelectionEnd(here.x(), here.y(), _trimTrailingSpaces);
} else {
_screenWindow->setSelectionEnd(here.x() + offset, here.y());
_screenWindow->setSelectionEnd(here.x() + offset, here.y(), _trimTrailingSpaces);
}
}
......@@ -1624,7 +1624,7 @@ void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent *ev)
_actSel = 2; // within selection
_screenWindow->setSelectionStart(bgnSel.x(), bgnSel.y(), false);
_screenWindow->setSelectionEnd(endSel.x(), endSel.y());
_screenWindow->setSelectionEnd(endSel.x(), endSel.y(), _trimTrailingSpaces);
copyToX11Selection();
}
......@@ -2013,7 +2013,7 @@ void TerminalDisplay::selectLine(QPoint pos, bool entireLine)
}
_iPntSel = findLineEnd(_iPntSel);
_screenWindow->setSelectionEnd(_iPntSel.x(), _iPntSel.y());
_screenWindow->setSelectionEnd(_iPntSel.x(), _iPntSel.y(), _trimTrailingSpaces);
copyToX11Selection();
......
......@@ -354,6 +354,11 @@ public:
// returns 0 - not selecting, 1 - pending selection (button pressed but no movement yet), 2 - selecting
int selectionState() const;
bool trimTrailingWhitespace() const
{
return _trimTrailingSpaces;
}
Qt::Edge droppedEdge() const
{
return _overlayEdge;
......
......@@ -93,7 +93,7 @@ void TerminalDisplayAccessible::addSelection(int startOffset, int endOffset)
return;
}
display()->screenWindow()->setSelectionStart(columnForOffset(startOffset), lineForOffset(startOffset), false);
display()->screenWindow()->setSelectionEnd(columnForOffset(endOffset), lineForOffset(endOffset));
display()->screenWindow()->setSelectionEnd(columnForOffset(endOffset), lineForOffset(endOffset), display()->trimTrailingWhitespace());
}
QString TerminalDisplayAccessible::attributes(int offset, int *startOffset, int *endOffset) const
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment