Skip to content

Commit 8e6830c

Browse files
committed
Support Shift+click to extend message text selection.
1 parent 2573a14 commit 8e6830c

6 files changed

Lines changed: 65 additions & 8 deletions

File tree

Telegram/SourceFiles/history/history_inner_widget.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,10 +1916,13 @@ void HistoryInner::mousePressEvent(QMouseEvent *e) {
19161916
}
19171917
_mouseActive = true;
19181918
registerReadMetricsActivity();
1919-
mouseActionStart(e->globalPos(), e->button());
1919+
mouseActionStart(e->globalPos(), e->button(), e->modifiers());
19201920
}
19211921

1922-
void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton button) {
1922+
void HistoryInner::mouseActionStart(
1923+
const QPoint &screenPos,
1924+
Qt::MouseButton button,
1925+
Qt::KeyboardModifiers modifiers) {
19231926
mouseActionUpdate(screenPos);
19241927
if (button != Qt::LeftButton) return;
19251928

@@ -1998,7 +2001,25 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
19982001
}
19992002
}
20002003
}
2001-
if (uponSelected) {
2004+
const auto canShiftExtend = (modifiers & Qt::ShiftModifier)
2005+
&& (_selected.size() == 1)
2006+
&& (_selected.cbegin()->first == _mouseActionItem)
2007+
&& (_selected.cbegin()->second != FullSelection)
2008+
&& (_selected.cbegin()->second.from
2009+
!= _selected.cbegin()->second.to);
2010+
if (canShiftExtend) {
2011+
auto symbol = _mouseTextSymbol;
2012+
if (dragState.afterSymbol) ++symbol;
2013+
const auto extended = HistoryView::ExtendTextSelectionTo(
2014+
_selected.cbegin()->second,
2015+
symbol);
2016+
_mouseTextSymbol = (extended.from == symbol)
2017+
? extended.to
2018+
: extended.from;
2019+
_selected.begin()->second = extended;
2020+
_mouseAction = MouseAction::Selecting;
2021+
repaintItem(_mouseActionItem);
2022+
} else if (uponSelected) {
20022023
_mouseAction = MouseAction::PrepareDrag; // start text drag
20032024
} else if (!_pressWasInactive) {
20042025
if (_mouseCursorState == CursorState::Date) {

Telegram/SourceFiles/history/history_inner_widget.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,10 @@ class HistoryInner
345345
void scrollDateHideByTimer();
346346
void scrollDateCheckDownward();
347347
bool canHaveFromUserpics() const;
348-
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
348+
void mouseActionStart(
349+
const QPoint &screenPos,
350+
Qt::MouseButton button,
351+
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
349352
void mouseActionUpdate();
350353
void mouseActionUpdate(const QPoint &screenPos);
351354
void mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button);

Telegram/SourceFiles/history/view/history_view_element.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,17 @@ TextSelection ShiftItemSelection(
643643
return ShiftItemSelection(selection, byText.length());
644644
}
645645

646+
TextSelection ExtendTextSelectionTo(
647+
TextSelection current,
648+
uint16 symbol) {
649+
const auto anchor = (symbol * 2 < current.from + current.to)
650+
? current.to
651+
: current.from;
652+
return TextSelection(
653+
std::min(symbol, anchor),
654+
std::max(symbol, anchor));
655+
}
656+
646657
QString DateTooltipText(not_null<Element*> view) {
647658
const auto locale = QLocale();
648659
const auto format = QLocale::LongFormat;

Telegram/SourceFiles/history/view/history_view_element.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ TextSelection ShiftItemSelection(
245245
TextSelection selection,
246246
const Ui::Text::String &byText);
247247

248+
[[nodiscard]] TextSelection ExtendTextSelectionTo(
249+
TextSelection current,
250+
uint16 symbol);
251+
248252
QString DateTooltipText(not_null<Element*> view);
249253

250254
// Any HistoryView::Element can have this Component for

Telegram/SourceFiles/history/view/history_view_list_widget.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,7 +3172,7 @@ void ListWidget::mousePressEvent(QMouseEvent *e) {
31723172
}
31733173
_mouseActive = true;
31743174
registerReadMetricsActivity();
3175-
mouseActionStart(e->globalPos(), e->button());
3175+
mouseActionStart(e->globalPos(), e->button(), e->modifiers());
31763176
}
31773177

31783178
void ListWidget::onTouchScrollTimer() {
@@ -3650,7 +3650,8 @@ void ListWidget::clearDragSelection() {
36503650

36513651
void ListWidget::mouseActionStart(
36523652
const QPoint &globalPosition,
3653-
Qt::MouseButton button) {
3653+
Qt::MouseButton button,
3654+
Qt::KeyboardModifiers modifiers) {
36543655
mouseActionUpdate(globalPosition);
36553656
if (button != Qt::LeftButton) {
36563657
return;
@@ -3713,7 +3714,23 @@ void ListWidget::mouseActionStart(
37133714
}
37143715
if (_mouseSelectType != TextSelectType::Paragraphs) {
37153716
_mouseTextSymbol = dragState.symbol;
3716-
if (isPressInSelectedText(dragState)) {
3717+
const auto canShiftExtend = (modifiers & Qt::ShiftModifier)
3718+
&& (dragState.cursor == CursorState::Text)
3719+
&& (_selectedTextItem == pressElement->data())
3720+
&& (_selectedTextRange != FullSelection)
3721+
&& (_selectedTextRange.from != _selectedTextRange.to);
3722+
if (canShiftExtend) {
3723+
auto symbol = _mouseTextSymbol;
3724+
if (dragState.afterSymbol) ++symbol;
3725+
const auto extended = ExtendTextSelectionTo(
3726+
_selectedTextRange,
3727+
symbol);
3728+
_mouseTextSymbol = (extended.from == symbol)
3729+
? extended.to
3730+
: extended.from;
3731+
setTextSelection(pressElement, extended);
3732+
_mouseAction = MouseAction::Selecting;
3733+
} else if (isPressInSelectedText(dragState)) {
37173734
_mouseAction = MouseAction::PrepareDrag; // start text drag
37183735
} else if (!_pressWasInactive) {
37193736
if (requiredToStartDragging(pressElement)

Telegram/SourceFiles/history/view/history_view_list_widget.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,8 @@ class ListWidget final
582582

583583
void mouseActionStart(
584584
const QPoint &globalPosition,
585-
Qt::MouseButton button);
585+
Qt::MouseButton button,
586+
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
586587
void mouseActionUpdate(const QPoint &globalPosition);
587588
void mouseActionUpdate();
588589
void mouseActionFinish(

0 commit comments

Comments
 (0)