mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Shared media multiple items selection.
This commit is contained in:
parent
66146c382d
commit
54cc3e6315
23 changed files with 1117 additions and 579 deletions
|
@ -64,12 +64,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#error Please add support for your architecture in base/build_config.h
|
#error Please add support for your architecture in base/build_config.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
||||||
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
|
||||||
#else
|
|
||||||
#define WARN_UNUSED_RESULT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define FORCE_INLINE inline __attribute__((always_inline))
|
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
|
|
|
@ -109,7 +109,18 @@ public:
|
||||||
flat_multi_map_iterator_base_impl operator-(difference_type offset) const {
|
flat_multi_map_iterator_base_impl operator-(difference_type offset) const {
|
||||||
return _impl - offset;
|
return _impl - offset;
|
||||||
}
|
}
|
||||||
difference_type operator-(const flat_multi_map_iterator_base_impl &right) const {
|
template <
|
||||||
|
typename other_iterator_impl,
|
||||||
|
typename other_pointer_impl,
|
||||||
|
typename other_reference_impl>
|
||||||
|
difference_type operator-(
|
||||||
|
const flat_multi_map_iterator_base_impl<
|
||||||
|
Key,
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl,
|
||||||
|
other_pointer_impl,
|
||||||
|
other_reference_impl> &right) const {
|
||||||
return _impl - right._impl;
|
return _impl - right._impl;
|
||||||
}
|
}
|
||||||
reference operator[](difference_type offset) {
|
reference operator[](difference_type offset) {
|
||||||
|
@ -119,13 +130,46 @@ public:
|
||||||
return _impl[offset];
|
return _impl[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const flat_multi_map_iterator_base_impl &right) const {
|
template <
|
||||||
|
typename other_iterator_impl,
|
||||||
|
typename other_pointer_impl,
|
||||||
|
typename other_reference_impl>
|
||||||
|
bool operator==(
|
||||||
|
const flat_multi_map_iterator_base_impl<
|
||||||
|
Key,
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl,
|
||||||
|
other_pointer_impl,
|
||||||
|
other_reference_impl> &right) const {
|
||||||
return _impl == right._impl;
|
return _impl == right._impl;
|
||||||
}
|
}
|
||||||
bool operator!=(const flat_multi_map_iterator_base_impl &right) const {
|
template <
|
||||||
|
typename other_iterator_impl,
|
||||||
|
typename other_pointer_impl,
|
||||||
|
typename other_reference_impl>
|
||||||
|
bool operator!=(
|
||||||
|
const flat_multi_map_iterator_base_impl<
|
||||||
|
Key,
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl,
|
||||||
|
other_pointer_impl,
|
||||||
|
other_reference_impl> &right) const {
|
||||||
return _impl != right._impl;
|
return _impl != right._impl;
|
||||||
}
|
}
|
||||||
bool operator<(const flat_multi_map_iterator_base_impl &right) const {
|
template <
|
||||||
|
typename other_iterator_impl,
|
||||||
|
typename other_pointer_impl,
|
||||||
|
typename other_reference_impl>
|
||||||
|
bool operator<(
|
||||||
|
const flat_multi_map_iterator_base_impl<
|
||||||
|
Key,
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl,
|
||||||
|
other_pointer_impl,
|
||||||
|
other_reference_impl> &right) const {
|
||||||
return _impl < right._impl;
|
return _impl < right._impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +177,15 @@ private:
|
||||||
iterator_impl _impl;
|
iterator_impl _impl;
|
||||||
friend class flat_multi_map<Key, Type, Compare>;
|
friend class flat_multi_map<Key, Type, Compare>;
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename OtherKey,
|
||||||
|
typename OtherType,
|
||||||
|
typename OtherCompare,
|
||||||
|
typename other_iterator_impl,
|
||||||
|
typename other_pointer_impl,
|
||||||
|
typename other_reference_impl>
|
||||||
|
friend class flat_multi_map_iterator_base_impl;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Key, typename Type, typename Compare>
|
template <typename Key, typename Type, typename Compare>
|
||||||
|
@ -418,10 +471,10 @@ public:
|
||||||
return (range.second - range.first);
|
return (range.second - range.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator erase(iterator where) {
|
iterator erase(const_iterator where) {
|
||||||
return _impl.erase(where._impl);
|
return _impl.erase(where._impl);
|
||||||
}
|
}
|
||||||
iterator erase(iterator from, iterator till) {
|
iterator erase(const_iterator from, const_iterator till) {
|
||||||
return _impl.erase(from._impl, till._impl);
|
return _impl.erase(from._impl, till._impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,37 +578,69 @@ public:
|
||||||
using parent::erase;
|
using parent::erase;
|
||||||
using parent::contains;
|
using parent::contains;
|
||||||
|
|
||||||
iterator insert(const value_type &value) {
|
std::pair<iterator, bool> insert(const value_type &value) {
|
||||||
if (this->empty() || compare()(value.first, this->front().first)) {
|
if (this->empty() || compare()(value.first, this->front().first)) {
|
||||||
this->_impl.push_front(value);
|
this->_impl.push_front(value);
|
||||||
return this->begin();
|
return { this->begin(), true };
|
||||||
} else if (compare()(this->back().first, value.first)) {
|
} else if (compare()(this->back().first, value.first)) {
|
||||||
this->_impl.push_back(value);
|
this->_impl.push_back(value);
|
||||||
return (this->end() - 1);
|
return { this->end() - 1, true };
|
||||||
}
|
}
|
||||||
auto where = this->getLowerBound(value.first);
|
auto where = this->getLowerBound(value.first);
|
||||||
if (compare()(value.first, where->first)) {
|
if (compare()(value.first, where->first)) {
|
||||||
return this->_impl.insert(where, value);
|
return { this->_impl.insert(where, value), true };
|
||||||
}
|
}
|
||||||
return this->end();
|
return { where, false };
|
||||||
}
|
}
|
||||||
iterator insert(value_type &&value) {
|
std::pair<iterator, bool> insert(value_type &&value) {
|
||||||
if (this->empty() || compare()(value.first, this->front().first)) {
|
if (this->empty() || compare()(value.first, this->front().first)) {
|
||||||
this->_impl.push_front(std::move(value));
|
this->_impl.push_front(std::move(value));
|
||||||
return this->begin();
|
return { this->begin(), true };
|
||||||
} else if (compare()(this->back().first, value.first)) {
|
} else if (compare()(this->back().first, value.first)) {
|
||||||
this->_impl.push_back(std::move(value));
|
this->_impl.push_back(std::move(value));
|
||||||
return (this->end() - 1);
|
return { this->end() - 1, true };
|
||||||
}
|
}
|
||||||
auto where = this->getLowerBound(value.first);
|
auto where = this->getLowerBound(value.first);
|
||||||
if (compare()(value.first, where->first)) {
|
if (compare()(value.first, where->first)) {
|
||||||
return this->_impl.insert(where, std::move(value));
|
return { this->_impl.insert(where, std::move(value)), true };
|
||||||
}
|
}
|
||||||
return this->end();
|
return { where, false };
|
||||||
}
|
}
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
iterator emplace(Args&&... args) {
|
std::pair<iterator, bool> emplace(
|
||||||
return this->insert(value_type(std::forward<Args>(args)...));
|
const Key &key,
|
||||||
|
Args&&... args) {
|
||||||
|
return this->insert(value_type(
|
||||||
|
key,
|
||||||
|
Type(std::forward<Args>(args)...)));
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
std::pair<iterator, bool> try_emplace(
|
||||||
|
const Key &key,
|
||||||
|
Args&&... args) {
|
||||||
|
if (this->empty() || compare()(key, this->front().first)) {
|
||||||
|
this->_impl.push_front(value_type(
|
||||||
|
key,
|
||||||
|
Type(std::forward<Args>(args)...)));
|
||||||
|
return { this->begin(), true };
|
||||||
|
} else if (compare()(this->back().first, key)) {
|
||||||
|
this->_impl.push_back(value_type(
|
||||||
|
key,
|
||||||
|
Type(std::forward<Args>(args)...)));
|
||||||
|
return { this->end() - 1, true };
|
||||||
|
}
|
||||||
|
auto where = this->getLowerBound(key);
|
||||||
|
if (compare()(key, where->first)) {
|
||||||
|
return {
|
||||||
|
this->_impl.insert(
|
||||||
|
where,
|
||||||
|
value_type(
|
||||||
|
key,
|
||||||
|
Type(std::forward<Args>(args)...))),
|
||||||
|
true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { where, false };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool remove(const Key &key) {
|
bool remove(const Key &key) {
|
||||||
|
|
|
@ -47,6 +47,13 @@ public:
|
||||||
flat_multi_set_iterator_base_impl(iterator_impl impl = iterator_impl())
|
flat_multi_set_iterator_base_impl(iterator_impl impl = iterator_impl())
|
||||||
: _impl(impl) {
|
: _impl(impl) {
|
||||||
}
|
}
|
||||||
|
template <typename other_iterator_impl>
|
||||||
|
flat_multi_set_iterator_base_impl(
|
||||||
|
const flat_multi_set_iterator_base_impl<
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl> &other) : _impl(other._impl) {
|
||||||
|
}
|
||||||
|
|
||||||
reference operator*() const {
|
reference operator*() const {
|
||||||
return *_impl;
|
return *_impl;
|
||||||
|
@ -82,20 +89,40 @@ public:
|
||||||
flat_multi_set_iterator_base_impl operator-(difference_type offset) const {
|
flat_multi_set_iterator_base_impl operator-(difference_type offset) const {
|
||||||
return _impl - offset;
|
return _impl - offset;
|
||||||
}
|
}
|
||||||
difference_type operator-(const flat_multi_set_iterator_base_impl &right) const {
|
template <typename other_iterator_impl>
|
||||||
|
difference_type operator-(
|
||||||
|
const flat_multi_set_iterator_base_impl<
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl> &right) const {
|
||||||
return _impl - right._impl;
|
return _impl - right._impl;
|
||||||
}
|
}
|
||||||
reference operator[](difference_type offset) const {
|
reference operator[](difference_type offset) const {
|
||||||
return _impl[offset];
|
return _impl[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const flat_multi_set_iterator_base_impl &right) const {
|
template <typename other_iterator_impl>
|
||||||
|
bool operator==(
|
||||||
|
const flat_multi_set_iterator_base_impl<
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl> &right) const {
|
||||||
return _impl == right._impl;
|
return _impl == right._impl;
|
||||||
}
|
}
|
||||||
bool operator!=(const flat_multi_set_iterator_base_impl &right) const {
|
template <typename other_iterator_impl>
|
||||||
|
bool operator!=(
|
||||||
|
const flat_multi_set_iterator_base_impl<
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl> &right) const {
|
||||||
return _impl != right._impl;
|
return _impl != right._impl;
|
||||||
}
|
}
|
||||||
bool operator<(const flat_multi_set_iterator_base_impl &right) const {
|
template <typename other_iterator_impl>
|
||||||
|
bool operator<(
|
||||||
|
const flat_multi_set_iterator_base_impl<
|
||||||
|
Type,
|
||||||
|
Compare,
|
||||||
|
other_iterator_impl> &right) const {
|
||||||
return _impl < right._impl;
|
return _impl < right._impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +131,12 @@ private:
|
||||||
friend class flat_multi_set<Type, Compare>;
|
friend class flat_multi_set<Type, Compare>;
|
||||||
friend class flat_set<Type, Compare>;
|
friend class flat_set<Type, Compare>;
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename OtherType,
|
||||||
|
typename OtherCompare,
|
||||||
|
typename other_iterator_impl>
|
||||||
|
friend class flat_multi_set_iterator_base_impl;
|
||||||
|
|
||||||
Type &wrapped() {
|
Type &wrapped() {
|
||||||
return _impl->wrapped();
|
return _impl->wrapped();
|
||||||
}
|
}
|
||||||
|
@ -205,43 +238,24 @@ public:
|
||||||
using pointer = const Type*;
|
using pointer = const Type*;
|
||||||
using reference = const Type&;
|
using reference = const Type&;
|
||||||
|
|
||||||
class const_iterator;
|
|
||||||
class iterator : public iterator_base {
|
class iterator : public iterator_base {
|
||||||
public:
|
public:
|
||||||
using iterator_base::iterator_base;
|
using iterator_base::iterator_base;
|
||||||
iterator(const iterator_base &other) : iterator_base(other) {
|
|
||||||
}
|
|
||||||
friend class const_iterator;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
class const_iterator : public const_iterator_base {
|
class const_iterator : public const_iterator_base {
|
||||||
public:
|
public:
|
||||||
using const_iterator_base::const_iterator_base;
|
using const_iterator_base::const_iterator_base;
|
||||||
const_iterator(const_iterator_base other) : const_iterator_base(other) {
|
|
||||||
}
|
|
||||||
const_iterator(const iterator &other) : const_iterator_base(other._impl) {
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
class const_reverse_iterator;
|
|
||||||
class reverse_iterator : public reverse_iterator_base {
|
class reverse_iterator : public reverse_iterator_base {
|
||||||
public:
|
public:
|
||||||
using reverse_iterator_base::reverse_iterator_base;
|
using reverse_iterator_base::reverse_iterator_base;
|
||||||
reverse_iterator(reverse_iterator_base other)
|
|
||||||
: reverse_iterator_base(other) {
|
|
||||||
}
|
|
||||||
friend class const_reverse_iterator;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
class const_reverse_iterator : public const_reverse_iterator_base {
|
class const_reverse_iterator : public const_reverse_iterator_base {
|
||||||
public:
|
public:
|
||||||
using const_reverse_iterator_base::const_reverse_iterator_base;
|
using const_reverse_iterator_base::const_reverse_iterator_base;
|
||||||
const_reverse_iterator(const_reverse_iterator_base other)
|
|
||||||
: const_reverse_iterator_base(other) {
|
|
||||||
}
|
|
||||||
const_reverse_iterator(const reverse_iterator &other)
|
|
||||||
: const_reverse_iterator_base(other._impl) {
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -366,10 +380,10 @@ public:
|
||||||
return (range.second - range.first);
|
return (range.second - range.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator erase(iterator where) {
|
iterator erase(const_iterator where) {
|
||||||
return _impl.erase(where._impl);
|
return _impl.erase(where._impl);
|
||||||
}
|
}
|
||||||
iterator erase(iterator from, iterator till) {
|
iterator erase(const_iterator from, const_iterator till) {
|
||||||
return _impl.erase(from._impl, till._impl);
|
return _impl.erase(from._impl, till._impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -894,7 +894,9 @@ void GifsListWidget::updateSelected() {
|
||||||
}
|
}
|
||||||
if (col < inlineItems.size()) {
|
if (col < inlineItems.size()) {
|
||||||
sel = row * MatrixRowShift + col;
|
sel = row * MatrixRowShift + col;
|
||||||
inlineItems.at(col)->getState(lnk, cursor, QPoint(sx, sy));
|
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
|
||||||
|
lnk = result.link;
|
||||||
|
cursor = result.cursor;
|
||||||
lnkhost = inlineItems.at(col);
|
lnkhost = inlineItems.at(col);
|
||||||
} else {
|
} else {
|
||||||
row = col = -1;
|
row = col = -1;
|
||||||
|
|
|
@ -1033,10 +1033,11 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
void HistoryInner::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
|
void HistoryInner::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
|
||||||
mouseActionUpdate(screenPos);
|
mouseActionUpdate(screenPos);
|
||||||
|
|
||||||
ClickHandlerPtr activated = ClickHandler::unpressed();
|
auto pressedLinkItem = App::pressedLinkItem();
|
||||||
|
auto activated = ClickHandler::unpressed();
|
||||||
if (_mouseAction == MouseAction::Dragging) {
|
if (_mouseAction == MouseAction::Dragging) {
|
||||||
activated.clear();
|
activated.clear();
|
||||||
} else if (auto pressed = App::pressedLinkItem()) {
|
} else if (auto pressed = pressedLinkItem) {
|
||||||
// if we are in selecting items mode perhaps we want to
|
// if we are in selecting items mode perhaps we want to
|
||||||
// toggle selection instead of activating the pressed link
|
// toggle selection instead of activating the pressed link
|
||||||
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && !_selected.empty() && _selected.cbegin()->second == FullSelection && button != Qt::RightButton) {
|
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && !_selected.empty() && _selected.cbegin()->second == FullSelection && button != Qt::RightButton) {
|
||||||
|
@ -2249,23 +2250,21 @@ void HistoryInner::onUpdateSelected() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) {
|
void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting) {
|
||||||
if (_dragSelFrom != dragSelFrom || _dragSelTo != dragSelTo || _dragSelecting != dragSelecting) {
|
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
|
||||||
_dragSelFrom = dragSelFrom;
|
return;
|
||||||
_dragSelTo = dragSelTo;
|
}
|
||||||
int32 fromy = itemTop(_dragSelFrom), toy = itemTop(_dragSelTo);
|
_dragSelFrom = dragSelFrom;
|
||||||
if (fromy >= 0 && toy >= 0 && fromy > toy) {
|
_dragSelTo = dragSelTo;
|
||||||
qSwap(_dragSelFrom, _dragSelTo);
|
int32 fromy = itemTop(_dragSelFrom), toy = itemTop(_dragSelTo);
|
||||||
}
|
if (fromy >= 0 && toy >= 0 && fromy > toy) {
|
||||||
_dragSelecting = dragSelecting;
|
qSwap(_dragSelFrom, _dragSelTo);
|
||||||
if (!_wasSelectedText && _dragSelFrom && _dragSelTo && _dragSelecting) {
|
}
|
||||||
_wasSelectedText = true;
|
_dragSelecting = dragSelecting;
|
||||||
setFocus();
|
if (!_wasSelectedText && _dragSelFrom && _dragSelTo && _dragSelecting) {
|
||||||
}
|
_wasSelectedText = true;
|
||||||
force = true;
|
setFocus();
|
||||||
}
|
}
|
||||||
if (!force) return;
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ private:
|
||||||
void adjustCurrent(int32 y, History *history) const;
|
void adjustCurrent(int32 y, History *history) const;
|
||||||
HistoryItem *prevItem(HistoryItem *item);
|
HistoryItem *prevItem(HistoryItem *item);
|
||||||
HistoryItem *nextItem(HistoryItem *item);
|
HistoryItem *nextItem(HistoryItem *item);
|
||||||
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
|
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting);
|
||||||
|
|
||||||
void setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode = QClipboard::Clipboard);
|
void setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode = QClipboard::Clipboard);
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,8 @@ struct HistoryTextState {
|
||||||
symbol = state.symbol;
|
symbol = state.symbol;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
HistoryTextState(ClickHandlerPtr link) : link(link) {
|
||||||
|
}
|
||||||
HistoryCursorState cursor = HistoryDefaultCursorState;
|
HistoryCursorState cursor = HistoryDefaultCursorState;
|
||||||
ClickHandlerPtr link;
|
ClickHandlerPtr link;
|
||||||
bool afterSymbol = false;
|
bool afterSymbol = false;
|
||||||
|
@ -656,11 +658,15 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual HistoryTextState getState(QPoint point, HistoryStateRequest request) const WARN_UNUSED_RESULT = 0;
|
[[nodiscard]] virtual HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const = 0;
|
||||||
virtual void updatePressed(QPoint point) {
|
virtual void updatePressed(QPoint point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TextSelection adjustSelection(TextSelection selection, TextSelectType type) const WARN_UNUSED_RESULT {
|
[[nodiscard]] virtual TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const {
|
||||||
return selection;
|
return selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,10 +1057,12 @@ protected:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection skipTextSelection(TextSelection selection) const WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection skipTextSelection(
|
||||||
|
TextSelection selection) const {
|
||||||
return internal::unshiftSelection(selection, _text);
|
return internal::unshiftSelection(selection, _text);
|
||||||
}
|
}
|
||||||
TextSelection unskipTextSelection(TextSelection selection) const WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection unskipTextSelection(
|
||||||
|
TextSelection selection) const {
|
||||||
return internal::shiftSelection(selection, _text);
|
return internal::shiftSelection(selection, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,27 +93,37 @@ public:
|
||||||
|
|
||||||
// if we are in selecting items mode perhaps we want to
|
// if we are in selecting items mode perhaps we want to
|
||||||
// toggle selection instead of activating the pressed link
|
// toggle selection instead of activating the pressed link
|
||||||
virtual bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const = 0;
|
virtual bool toggleSelectionByHandlerClick(
|
||||||
|
const ClickHandlerPtr &p) const = 0;
|
||||||
|
|
||||||
// if we press and drag on this media should we drag the item
|
// if we press and drag on this media should we drag the item
|
||||||
virtual bool dragItem() const WARN_UNUSED_RESULT {
|
[[nodiscard]] virtual bool dragItem() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TextSelection adjustSelection(TextSelection selection, TextSelectType type) const WARN_UNUSED_RESULT {
|
[[nodiscard]] virtual TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const {
|
||||||
return selection;
|
return selection;
|
||||||
}
|
}
|
||||||
virtual bool consumeMessageText(const TextWithEntities &textWithEntities) WARN_UNUSED_RESULT {
|
[[nodiscard]] virtual bool consumeMessageText(
|
||||||
|
const TextWithEntities &textWithEntities) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual uint16 fullSelectionLength() const WARN_UNUSED_RESULT {
|
[[nodiscard]] virtual uint16 fullSelectionLength() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TextSelection skipSelection(TextSelection selection) const WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection skipSelection(
|
||||||
return internal::unshiftSelection(selection, fullSelectionLength());
|
TextSelection selection) const {
|
||||||
|
return internal::unshiftSelection(
|
||||||
|
selection,
|
||||||
|
fullSelectionLength());
|
||||||
}
|
}
|
||||||
TextSelection unskipSelection(TextSelection selection) const WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection unskipSelection(
|
||||||
return internal::shiftSelection(selection, fullSelectionLength());
|
TextSelection selection) const {
|
||||||
|
return internal::shiftSelection(
|
||||||
|
selection,
|
||||||
|
fullSelectionLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we press and drag this link should we drag the item
|
// if we press and drag this link should we drag the item
|
||||||
|
|
|
@ -144,7 +144,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override {
|
||||||
return _caption.adjustSelection(selection, type);
|
return _caption.adjustSelection(selection, type);
|
||||||
}
|
}
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
|
@ -230,7 +232,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override {
|
||||||
return _caption.adjustSelection(selection, type);
|
return _caption.adjustSelection(selection, type);
|
||||||
}
|
}
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
|
@ -382,7 +386,9 @@ public:
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
void updatePressed(QPoint point) override;
|
void updatePressed(QPoint point) override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override {
|
||||||
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
return captioned->_caption.adjustSelection(selection, type);
|
return captioned->_caption.adjustSelection(selection, type);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +501,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override {
|
||||||
return _caption.adjustSelection(selection, type);
|
return _caption.adjustSelection(selection, type);
|
||||||
}
|
}
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
|
@ -795,7 +803,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override;
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
return _title.length() + _description.length();
|
return _title.length() + _description.length();
|
||||||
}
|
}
|
||||||
|
@ -902,7 +912,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override;
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
return _title.length() + _description.length();
|
return _title.length() + _description.length();
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1028,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override;
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
return _title.length() + _description.length();
|
return _title.length() + _description.length();
|
||||||
}
|
}
|
||||||
|
@ -1102,7 +1116,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override;
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
return _title.length() + _description.length();
|
return _title.length() + _description.length();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,9 @@ public:
|
||||||
bool hasPoint(QPoint point) const override;
|
bool hasPoint(QPoint point) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override {
|
||||||
return _text.adjustSelection(selection, type);
|
return _text.adjustSelection(selection, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -66,6 +66,18 @@ public:
|
||||||
rpl::producer<int> scrollToRequests() const {
|
rpl::producer<int> scrollToRequests() const {
|
||||||
return _scrollToRequests.events();
|
return _scrollToRequests.events();
|
||||||
}
|
}
|
||||||
|
struct SelectedItem {
|
||||||
|
explicit SelectedItem(FullMsgId msgId) : msgId(msgId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
FullMsgId msgId;
|
||||||
|
bool canDelete = false;
|
||||||
|
bool canForward = false;
|
||||||
|
};
|
||||||
|
using SelectedItems = std::vector<SelectedItem>;
|
||||||
|
rpl::producer<SelectedItems> selectedItemsValue() const {
|
||||||
|
return _selectedItemsStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
~ListWidget();
|
~ListWidget();
|
||||||
|
|
||||||
|
@ -98,19 +110,51 @@ private:
|
||||||
std::unique_ptr<BaseLayout> item;
|
std::unique_ptr<BaseLayout> item;
|
||||||
bool stale = false;
|
bool stale = false;
|
||||||
};
|
};
|
||||||
|
struct Context;
|
||||||
class Section;
|
class Section;
|
||||||
struct FoundItem {
|
struct FoundItem {
|
||||||
not_null<BaseLayout*> layout;
|
not_null<BaseLayout*> layout;
|
||||||
QRect geometry;
|
QRect geometry;
|
||||||
bool exact = false;
|
bool exact = false;
|
||||||
};
|
};
|
||||||
|
struct SelectionData {
|
||||||
|
explicit SelectionData(TextSelection text) : text(text) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection text;
|
||||||
|
bool canDelete = false;
|
||||||
|
bool canForward = false;
|
||||||
|
};
|
||||||
|
using SelectedMap = base::flat_map<
|
||||||
|
UniversalMsgId,
|
||||||
|
SelectionData,
|
||||||
|
std::less<>>;
|
||||||
|
enum class DragSelectAction {
|
||||||
|
None,
|
||||||
|
Selecting,
|
||||||
|
Deselecting,
|
||||||
|
};
|
||||||
|
struct CursorState {
|
||||||
|
UniversalMsgId itemId = 0;
|
||||||
|
QSize size;
|
||||||
|
QPoint cursor;
|
||||||
|
bool inside = false;
|
||||||
|
|
||||||
|
inline bool operator==(const CursorState &other) const {
|
||||||
|
return (itemId == other.itemId)
|
||||||
|
&& (cursor == other.cursor);
|
||||||
|
}
|
||||||
|
inline bool operator!=(const CursorState &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
int recountHeight();
|
int recountHeight();
|
||||||
void refreshHeight();
|
void refreshHeight();
|
||||||
|
|
||||||
QMargins padding() const;
|
QMargins padding() const;
|
||||||
void updateSelected();
|
|
||||||
bool isMyItem(not_null<const HistoryItem*> item) const;
|
bool isMyItem(not_null<const HistoryItem*> item) const;
|
||||||
bool isItemLayout(
|
bool isItemLayout(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
|
@ -118,6 +162,7 @@ private:
|
||||||
void repaintItem(const HistoryItem *item);
|
void repaintItem(const HistoryItem *item);
|
||||||
void repaintItem(UniversalMsgId msgId);
|
void repaintItem(UniversalMsgId msgId);
|
||||||
void repaintItem(const BaseLayout *item);
|
void repaintItem(const BaseLayout *item);
|
||||||
|
void repaintItem(QRect itemGeometry);
|
||||||
void itemRemoved(not_null<const HistoryItem*> item);
|
void itemRemoved(not_null<const HistoryItem*> item);
|
||||||
void itemLayoutChanged(not_null<const HistoryItem*> item);
|
void itemLayoutChanged(not_null<const HistoryItem*> item);
|
||||||
|
|
||||||
|
@ -126,12 +171,46 @@ private:
|
||||||
void refreshRows();
|
void refreshRows();
|
||||||
SharedMediaMergedSlice::Key sliceKey(
|
SharedMediaMergedSlice::Key sliceKey(
|
||||||
UniversalMsgId universalId) const;
|
UniversalMsgId universalId) const;
|
||||||
BaseLayout *getLayout(const FullMsgId &itemId);
|
BaseLayout *getLayout(UniversalMsgId universalId);
|
||||||
BaseLayout *getExistingLayout(const FullMsgId &itemId) const;
|
BaseLayout *getExistingLayout(UniversalMsgId universalId) const;
|
||||||
std::unique_ptr<BaseLayout> createLayout(
|
std::unique_ptr<BaseLayout> createLayout(
|
||||||
const FullMsgId &itemId,
|
UniversalMsgId universalId,
|
||||||
Type type);
|
Type type);
|
||||||
|
|
||||||
|
SelectedItems collectSelectedItems() const;
|
||||||
|
void pushSelectedItems();
|
||||||
|
FullMsgId computeFullId(UniversalMsgId universalId) const;
|
||||||
|
bool hasSelected() const;
|
||||||
|
bool isSelectedItem(
|
||||||
|
const SelectedMap::const_iterator &i) const;
|
||||||
|
void removeItemSelection(
|
||||||
|
const SelectedMap::const_iterator &i);
|
||||||
|
bool hasSelectedText() const;
|
||||||
|
bool hasSelectedItems() const;
|
||||||
|
void clearSelected();
|
||||||
|
void applyItemSelection(
|
||||||
|
UniversalMsgId universalId,
|
||||||
|
TextSelection selection);
|
||||||
|
void toggleItemSelection(
|
||||||
|
UniversalMsgId universalId);
|
||||||
|
SelectedMap::iterator itemUnderPressSelection();
|
||||||
|
SelectedMap::const_iterator itemUnderPressSelection() const;
|
||||||
|
bool isItemUnderPressSelected() const;
|
||||||
|
bool requiredToStartDragging(not_null<BaseLayout*> layout) const;
|
||||||
|
bool isPressInSelectedText(HistoryTextState state) const;
|
||||||
|
void applyDragSelection();
|
||||||
|
void applyDragSelection(SelectedMap &applyTo) const;
|
||||||
|
bool changeItemSelection(
|
||||||
|
SelectedMap &selected,
|
||||||
|
UniversalMsgId universalId,
|
||||||
|
TextSelection selection) const;
|
||||||
|
|
||||||
|
static bool IsAfter(
|
||||||
|
const CursorState &a,
|
||||||
|
const CursorState &b);
|
||||||
|
static bool SkipSelectFromItem(const CursorState &state);
|
||||||
|
static bool SkipSelectTillItem(const CursorState &state);
|
||||||
|
|
||||||
void markLayoutsStale();
|
void markLayoutsStale();
|
||||||
void clearStaleLayouts();
|
void clearStaleLayouts();
|
||||||
std::vector<Section>::iterator findSectionByItem(
|
std::vector<Section>::iterator findSectionByItem(
|
||||||
|
@ -157,11 +236,25 @@ private:
|
||||||
const QPoint &screenPos,
|
const QPoint &screenPos,
|
||||||
Qt::MouseButton button);
|
Qt::MouseButton button);
|
||||||
void mouseActionUpdate(const QPoint &screenPos);
|
void mouseActionUpdate(const QPoint &screenPos);
|
||||||
|
void mouseActionUpdate();
|
||||||
void mouseActionFinish(
|
void mouseActionFinish(
|
||||||
const QPoint &screenPos,
|
const QPoint &screenPos,
|
||||||
Qt::MouseButton button);
|
Qt::MouseButton button);
|
||||||
void mouseActionCancel();
|
void mouseActionCancel();
|
||||||
void performDrag();
|
void performDrag();
|
||||||
|
style::cursor computeMouseCursor() const;
|
||||||
|
|
||||||
|
void updateDragSelection();
|
||||||
|
void clearDragSelection();
|
||||||
|
void setDragSelection(
|
||||||
|
BaseLayout *dragSelectFrom,
|
||||||
|
BaseLayout *dragSelectTill,
|
||||||
|
DragSelectAction action);
|
||||||
|
|
||||||
|
void trySwitchToWordSelection();
|
||||||
|
void switchToWordSelection();
|
||||||
|
void validateTrippleClickStartTime();
|
||||||
|
void checkMoveToOtherViewer();
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
not_null<Window::Controller*> _controller;
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
|
@ -183,29 +276,24 @@ private:
|
||||||
|
|
||||||
MouseAction _mouseAction = MouseAction::None;
|
MouseAction _mouseAction = MouseAction::None;
|
||||||
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
||||||
QPoint _dragStartPosition;
|
|
||||||
QPoint _mousePosition;
|
QPoint _mousePosition;
|
||||||
BaseLayout *_itemNearestToCursor = nullptr;
|
CursorState _overState;
|
||||||
BaseLayout *_itemUnderCursor = nullptr;
|
CursorState _pressState;
|
||||||
BaseLayout *_itemUnderPress = nullptr;
|
BaseLayout *_overLayout = nullptr;
|
||||||
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
||||||
// uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
using SelectedItems = std::map<
|
SelectedMap _selected;
|
||||||
UniversalMsgId,
|
SelectedMap _dragSelected;
|
||||||
TextSelection,
|
rpl::event_stream<SelectedItems> _selectedItemsStream;
|
||||||
std::less<>>;
|
|
||||||
SelectedItems _selected;
|
|
||||||
style::cursor _cursor = style::cur_default;
|
style::cursor _cursor = style::cur_default;
|
||||||
BaseLayout *_dragSelFrom = nullptr;
|
DragSelectAction _dragSelectAction = DragSelectAction::None;
|
||||||
BaseLayout *_dragSelTo = nullptr;
|
|
||||||
// bool _dragSelecting = false;
|
|
||||||
bool _wasSelectedText = false; // was some text selected in current drag action
|
bool _wasSelectedText = false; // was some text selected in current drag action
|
||||||
Ui::PopupMenu *_contextMenu = nullptr;
|
Ui::PopupMenu *_contextMenu = nullptr;
|
||||||
ClickHandlerPtr _contextMenuLink;
|
ClickHandlerPtr _contextMenuLink;
|
||||||
|
|
||||||
QPoint _trippleClickPoint;
|
QPoint _trippleClickPoint;
|
||||||
QTimer _trippleClickTimer;
|
TimeMs _trippleClickStartTime = 0;
|
||||||
|
|
||||||
rpl::lifetime _viewerLifetime;
|
rpl::lifetime _viewerLifetime;
|
||||||
|
|
||||||
|
|
|
@ -213,14 +213,17 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Gif::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
if (_delete && rtlpoint(point, _width).x() >= _width - st::stickerPanDeleteIconBg.width() && point.y() < st::stickerPanDeleteIconBg.height()) {
|
if (_delete && rtlpoint(point, _width).x() >= _width - st::stickerPanDeleteIconBg.width() && point.y() < st::stickerPanDeleteIconBg.height()) {
|
||||||
link = _delete;
|
return _delete;
|
||||||
} else {
|
} else {
|
||||||
link = _send;
|
return _send;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
|
@ -404,10 +407,13 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sticker::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Sticker::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sticker::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
void Sticker::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
|
@ -491,10 +497,13 @@ void Photo::paint(Painter &p, const QRect &clip, const PaintContext *context) co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Photo::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoData *Photo::getShownPhoto() const {
|
PhotoData *Photo::getShownPhoto() const {
|
||||||
|
@ -633,15 +642,16 @@ void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Video::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
link = _link;
|
return _link;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (QRect(st::inlineThumbSize + st::inlineThumbSkip, 0, _width - st::inlineThumbSize - st::inlineThumbSkip, _height).contains(point)) {
|
if (QRect(st::inlineThumbSize + st::inlineThumbSkip, 0, _width - st::inlineThumbSize - st::inlineThumbSkip, _height).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::prepareThumb(int32 width, int32 height) const {
|
void Video::prepareThumb(int32 width, int32 height) const {
|
||||||
|
@ -773,16 +783,18 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState File::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) {
|
||||||
link = getShownDocument()->loading() ? _cancel : _open;
|
return getShownDocument()->loading() ? _cancel : _open;
|
||||||
return;
|
} else {
|
||||||
}
|
auto left = st::msgFileSize + st::inlineThumbSkip;
|
||||||
auto left = st::msgFileSize + st::inlineThumbSkip;
|
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
||||||
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
return _send;
|
||||||
link = _send;
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
|
@ -933,15 +945,16 @@ void Contact::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contact::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Contact::getState(
|
||||||
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
|
QPoint point,
|
||||||
return;
|
HistoryStateRequest request) const {
|
||||||
}
|
if (!QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
|
||||||
auto left = (st::msgFileSize + st::inlineThumbSkip);
|
auto left = (st::msgFileSize + st::inlineThumbSkip);
|
||||||
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contact::prepareThumb(int width, int height) const {
|
void Contact::prepareThumb(int width, int height) const {
|
||||||
|
@ -1069,10 +1082,11 @@ void Article::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Article::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Article::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (_withThumb && QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (_withThumb && QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
link = _link;
|
return _link;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
auto left = _withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0;
|
auto left = _withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0;
|
||||||
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
||||||
|
@ -1082,13 +1096,12 @@ void Article::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint
|
||||||
auto descriptionLines = 2;
|
auto descriptionLines = 2;
|
||||||
auto descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
|
auto descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
|
||||||
if (rtlrect(left, st::inlineRowMargin + titleHeight + descriptionHeight, _urlWidth, st::normalFont->height, _width).contains(point)) {
|
if (rtlrect(left, st::inlineRowMargin + titleHeight + descriptionHeight, _urlWidth, st::normalFont->height, _width).contains(point)) {
|
||||||
link = _url;
|
return _url;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
link = _send;
|
return _send;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Article::prepareThumb(int width, int height) const {
|
void Article::prepareThumb(int width, int height) const {
|
||||||
|
@ -1253,16 +1266,17 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Game::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
int left = st::inlineThumbSize + st::inlineThumbSkip;
|
int left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||||
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
||||||
link = _send;
|
return _send;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::prepareThumb(int width, int height) const {
|
void Game::prepareThumb(int width, int height) const {
|
||||||
|
|
|
@ -73,7 +73,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -130,7 +132,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PhotoData *getShownPhoto() const;
|
PhotoData *getShownPhoto() const;
|
||||||
|
@ -160,7 +164,9 @@ public:
|
||||||
void preload() const override;
|
void preload() const override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -184,7 +190,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _link;
|
ClickHandlerPtr _link;
|
||||||
|
@ -231,7 +239,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -294,7 +304,9 @@ public:
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QPixmap _thumb;
|
mutable QPixmap _thumb;
|
||||||
|
@ -312,7 +324,9 @@ public:
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _url, _link;
|
ClickHandlerPtr _url, _link;
|
||||||
|
@ -335,7 +349,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void countFrameSize();
|
void countFrameSize();
|
||||||
|
|
|
@ -644,8 +644,10 @@ void Inner::updateSelected() {
|
||||||
}
|
}
|
||||||
if (col < inlineItems.size()) {
|
if (col < inlineItems.size()) {
|
||||||
sel = row * MatrixRowShift + col;
|
sel = row * MatrixRowShift + col;
|
||||||
inlineItems.at(col)->getState(lnk, cursor, QPoint(sx, sy));
|
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
|
||||||
lnkhost = inlineItems.at(col);
|
lnk = result.link;
|
||||||
|
cursor = result.cursor;
|
||||||
|
lnkhost = inlineItems[col];
|
||||||
} else {
|
} else {
|
||||||
row = col = -1;
|
row = col = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,14 +119,15 @@ public:
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
[[nodiscard]] virtual HistoryTextState getState(
|
||||||
link.clear();
|
QPoint point,
|
||||||
cursor = HistoryDefaultCursorState;
|
HistoryStateRequest request) const {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
virtual void getSymbol(uint16 &symbol, bool &after, bool &upon, QPoint point) const { // from text
|
[[nodiscard]] virtual TextSelection adjustSelection(
|
||||||
upon = hasPoint(point);
|
TextSelection selection,
|
||||||
symbol = upon ? 0xFFFF : 0;
|
TextSelectType type) const {
|
||||||
after = false;
|
return selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width() const {
|
int width() const {
|
||||||
|
|
|
@ -104,7 +104,9 @@ void ListWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if (y <= m.y()) {
|
if (y <= m.y()) {
|
||||||
if (auto media = layout->toMediaItem()) {
|
if (auto media = layout->toMediaItem()) {
|
||||||
item = media->getItem();
|
item = media->getItem();
|
||||||
media->getState(lnk, cursorState, m - QPoint(0, y));
|
auto result = media->getState(m - QPoint(0, y), HistoryStateRequest());
|
||||||
|
lnk = result.link;
|
||||||
|
cursorState = result.cursor;
|
||||||
lnkhost = media;
|
lnkhost = media;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1153,7 +1153,11 @@ void MediaView::refreshMediaViewer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
|
void MediaView::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
|
||||||
setContext(context);
|
if (context) {
|
||||||
|
setContext(context);
|
||||||
|
} else {
|
||||||
|
setContext(base::none);
|
||||||
|
}
|
||||||
|
|
||||||
_firstOpenedPeerPhoto = false;
|
_firstOpenedPeerPhoto = false;
|
||||||
_saveMsgStarted = 0;
|
_saveMsgStarted = 0;
|
||||||
|
|
|
@ -214,39 +214,39 @@ public:
|
||||||
SpecificRequestBuilder(SpecificRequestBuilder &&other) = default;
|
SpecificRequestBuilder(SpecificRequestBuilder &&other) = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SpecificRequestBuilder &toDC(ShiftedDcId dcId) noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &toDC(ShiftedDcId dcId) noexcept {
|
||||||
setToDC(dcId);
|
setToDC(dcId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &canWait(TimeMs ms) noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &canWait(TimeMs ms) noexcept {
|
||||||
setCanWait(ms);
|
setCanWait(ms);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result)> callback) WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result)> callback) {
|
||||||
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DonePlainPolicy>>(sender(), std::move(callback)));
|
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DonePlainPolicy>>(sender(), std::move(callback)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result, mtpRequestId requestId)> callback) WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result, mtpRequestId requestId)> callback) {
|
||||||
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DoneRequestIdPolicy>>(sender(), std::move(callback)));
|
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DoneRequestIdPolicy>>(sender(), std::move(callback)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error)> callback) noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error)> callback) noexcept {
|
||||||
setFailHandler(std::move(callback));
|
setFailHandler(std::move(callback));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error, mtpRequestId requestId)> callback) noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error, mtpRequestId requestId)> callback) noexcept {
|
||||||
setFailHandler(std::move(callback));
|
setFailHandler(std::move(callback));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &handleFloodErrors() noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &handleFloodErrors() noexcept {
|
||||||
setFailSkipPolicy(FailSkipPolicy::HandleFlood);
|
setFailSkipPolicy(FailSkipPolicy::HandleFlood);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &handleAllErrors() noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &handleAllErrors() noexcept {
|
||||||
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SpecificRequestBuilder &after(mtpRequestId requestId) noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] SpecificRequestBuilder &after(mtpRequestId requestId) noexcept {
|
||||||
setAfter(requestId);
|
setAfter(requestId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -280,11 +280,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Request, typename = std::enable_if_t<std::is_rvalue_reference<Request&&>::value>, typename = typename Request::Unboxed>
|
template <typename Request, typename = std::enable_if_t<std::is_rvalue_reference<Request&&>::value>, typename = typename Request::Unboxed>
|
||||||
SpecificRequestBuilder<Request> request(Request &&request) noexcept WARN_UNUSED_RESULT;
|
[[nodiscard]] SpecificRequestBuilder<Request> request(Request &&request) noexcept;
|
||||||
|
|
||||||
SentRequestWrap request(mtpRequestId requestId) noexcept WARN_UNUSED_RESULT;
|
[[nodiscard]] SentRequestWrap request(mtpRequestId requestId) noexcept;
|
||||||
|
|
||||||
decltype(auto) requestCanceller() noexcept WARN_UNUSED_RESULT {
|
[[nodiscard]] decltype(auto) requestCanceller() noexcept {
|
||||||
return [this](mtpRequestId requestId) {
|
return [this](mtpRequestId requestId) {
|
||||||
request(requestId).cancel();
|
request(requestId).cancel();
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,12 +66,16 @@ TextWithEntities ComposeNameWithEntities(DocumentData *document) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void ItemBase::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
|
void ItemBase::clickHandlerActiveChanged(
|
||||||
|
const ClickHandlerPtr &action,
|
||||||
|
bool active) {
|
||||||
App::hoveredLinkItem(active ? _parent.get() : nullptr);
|
App::hoveredLinkItem(active ? _parent.get() : nullptr);
|
||||||
Auth().data().requestItemRepaint(_parent);
|
Auth().data().requestItemRepaint(_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemBase::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) {
|
void ItemBase::clickHandlerPressedChanged(
|
||||||
|
const ClickHandlerPtr &action,
|
||||||
|
bool pressed) {
|
||||||
App::pressedLinkItem(pressed ? _parent.get() : nullptr);
|
App::pressedLinkItem(pressed ? _parent.get() : nullptr);
|
||||||
Auth().data().requestItemRepaint(_parent);
|
Auth().data().requestItemRepaint(_parent);
|
||||||
}
|
}
|
||||||
|
@ -306,10 +310,13 @@ void Photo::ensureCheckboxCreated() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Photo::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
if (hasPoint(point)) {
|
if (hasPoint(point)) {
|
||||||
link = _link;
|
return _link;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
|
void Photo::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
|
||||||
|
@ -506,12 +513,15 @@ bool Video::iconAnimated() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Video::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
bool loaded = _data->loaded();
|
bool loaded = _data->loaded();
|
||||||
|
|
||||||
if (hasPoint(point)) {
|
if (hasPoint(point)) {
|
||||||
link = loaded ? _openl : (_data->loading() ? _cancell : _savel);
|
return loaded ? _openl : (_data->loading() ? _cancell : _savel);
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::updateStatusText() {
|
void Video::updateStatusText() {
|
||||||
|
@ -664,7 +674,9 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Voice::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
bool loaded = _data->loaded();
|
bool loaded = _data->loaded();
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
|
||||||
|
@ -676,20 +688,20 @@ void Voice::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint p
|
||||||
|
|
||||||
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
||||||
if (inner.contains(point)) {
|
if (inner.contains(point)) {
|
||||||
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
|
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
auto result = HistoryTextState();
|
||||||
if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(point)) {
|
if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(point)) {
|
||||||
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
|
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
|
||||||
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
||||||
link = textState.link;
|
result.link = textState.link;
|
||||||
cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
result.cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasPoint(point) && !link && !_data->loading()) {
|
if (hasPoint(point) && !result.link && !_data->loading()) {
|
||||||
link = _namel;
|
return _namel;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 Voice::dataProgress() const {
|
float64 Voice::dataProgress() const {
|
||||||
|
@ -954,7 +966,9 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Document::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey());
|
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey());
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
|
||||||
|
@ -968,12 +982,10 @@ void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoin
|
||||||
|
|
||||||
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
||||||
if (inner.contains(point)) {
|
if (inner.contains(point)) {
|
||||||
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
|
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (hasPoint(point) && !_data->loading()) {
|
if (hasPoint(point) && !_data->loading()) {
|
||||||
link = _namel;
|
return _namel;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameleft = _st.fileThumbSize + _st.filePadding.right();
|
nameleft = _st.fileThumbSize + _st.filePadding.right();
|
||||||
|
@ -984,27 +996,24 @@ void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoin
|
||||||
auto rthumb = rtlrect(0, st::linksBorder + _st.filePadding.top(), _st.fileThumbSize, _st.fileThumbSize, _width);
|
auto rthumb = rtlrect(0, st::linksBorder + _st.filePadding.top(), _st.fileThumbSize, _st.fileThumbSize, _width);
|
||||||
|
|
||||||
if (rthumb.contains(point)) {
|
if (rthumb.contains(point)) {
|
||||||
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
|
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data->status != FileUploadFailed) {
|
if (_data->status != FileUploadFailed) {
|
||||||
if (rtlrect(nameleft, datetop, _datew, st::normalFont->height, _width).contains(point)) {
|
if (rtlrect(nameleft, datetop, _datew, st::normalFont->height, _width).contains(point)) {
|
||||||
link = _msgl;
|
return _msgl;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_data->loading() && _data->isValid()) {
|
if (!_data->loading() && _data->isValid()) {
|
||||||
if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(point)) {
|
if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(point)) {
|
||||||
link = _namel;
|
return _namel;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _name.maxWidth()), st::semiboldFont->height, _width).contains(point)) {
|
if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _name.maxWidth()), st::semiboldFont->height, _width).contains(point)) {
|
||||||
link = _namel;
|
return _namel;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 Document::dataProgress() const {
|
float64 Document::dataProgress() const {
|
||||||
|
@ -1301,11 +1310,12 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
|
HistoryTextState Link::getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const {
|
||||||
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||||
if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(point)) {
|
if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(point)) {
|
||||||
link = _photol;
|
return _photol;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
||||||
|
@ -1313,8 +1323,7 @@ void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint po
|
||||||
}
|
}
|
||||||
if (!_title.isEmpty()) {
|
if (!_title.isEmpty()) {
|
||||||
if (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(point)) {
|
if (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(point)) {
|
||||||
link = _photol;
|
return _photol;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
top += st::webPageTitleFont->height;
|
top += st::webPageTitleFont->height;
|
||||||
}
|
}
|
||||||
|
@ -1323,11 +1332,11 @@ void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint po
|
||||||
}
|
}
|
||||||
for (int32 i = 0, l = _links.size(); i < l; ++i) {
|
for (int32 i = 0, l = _links.size(); i < l; ++i) {
|
||||||
if (rtlrect(left, top, qMin(w, _links.at(i).width), st::normalFont->height, _width).contains(point)) {
|
if (rtlrect(left, top, qMin(w, _links.at(i).width), st::normalFont->height, _width).contains(point)) {
|
||||||
link = _links.at(i).lnk;
|
return _links.at(i).lnk;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
top += st::normalFont->height;
|
top += st::normalFont->height;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Link::LinkEntry::LinkEntry(const QString &url, const QString &text)
|
Link::LinkEntry::LinkEntry(const QString &url, const QString &text)
|
||||||
|
|
|
@ -189,7 +189,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||||
|
@ -220,7 +222,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||||
|
@ -260,7 +264,9 @@ public:
|
||||||
|
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float64 dataProgress() const override;
|
float64 dataProgress() const override;
|
||||||
|
@ -292,7 +298,9 @@ public:
|
||||||
|
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
virtual DocumentData *getDocument() const override {
|
virtual DocumentData *getDocument() const override {
|
||||||
return _data;
|
return _data;
|
||||||
|
@ -333,7 +341,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
|
HistoryTextState getState(
|
||||||
|
QPoint point,
|
||||||
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _photol;
|
ClickHandlerPtr _photol;
|
||||||
|
|
|
@ -900,7 +900,9 @@ void OverviewInner::onUpdateSelected() {
|
||||||
item = media->getItem();
|
item = media->getItem();
|
||||||
index = i;
|
index = i;
|
||||||
if (upon) {
|
if (upon) {
|
||||||
media->getState(lnk, cursorState, m - QPoint(col * w + st::overviewPhotoSkip, _marginTop + row * vsize + st::overviewPhotoSkip));
|
auto result = media->getState(m - QPoint(col * w + st::overviewPhotoSkip, _marginTop + row * vsize + st::overviewPhotoSkip), HistoryStateRequest());
|
||||||
|
lnk = result.link;
|
||||||
|
cursorState = result.cursor;
|
||||||
lnkhost = media;
|
lnkhost = media;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,7 +938,9 @@ void OverviewInner::onUpdateSelected() {
|
||||||
if (auto media = _items.at(i)->toMediaItem()) {
|
if (auto media = _items.at(i)->toMediaItem()) {
|
||||||
item = media->getItem();
|
item = media->getItem();
|
||||||
index = i;
|
index = i;
|
||||||
media->getState(lnk, cursorState, m - QPoint(_rowsLeft, _marginTop + top));
|
auto result = media->getState(m - QPoint(_rowsLeft, _marginTop + top), HistoryStateRequest());
|
||||||
|
lnk = result.link;
|
||||||
|
cursorState = result.cursor;
|
||||||
lnkhost = media;
|
lnkhost = media;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -165,7 +165,7 @@ public:
|
||||||
return getStateElided(rtlpoint(point, outerw), width, request);
|
return getStateElided(rtlpoint(point, outerw), width, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType selectType) const WARN_UNUSED_RESULT;
|
[[nodiscard]] TextSelection adjustSelection(TextSelection selection, TextSelectType selectType) const;
|
||||||
bool isFullSelection(TextSelection selection) const {
|
bool isFullSelection(TextSelection selection) const {
|
||||||
return (selection.from == 0) && (selection.to >= _text.size());
|
return (selection.from == 0) && (selection.to >= _text.size());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue