Fix captions selection in column albums.
This commit is contained in:
parent
6d9c529a65
commit
6e682643df
|
@ -108,12 +108,38 @@ TextForMimeData HistoryItemText(not_null<HistoryItem*> item) {
|
|||
TextForMimeData HistoryGroupText(not_null<const Data::Group*> group) {
|
||||
Expects(!group->items.empty());
|
||||
|
||||
const auto columnAlbum = [&] {
|
||||
const auto item = group->items.front();
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
return !document->isVideoFile();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
const auto hasCaption = [](not_null<HistoryItem*> item) {
|
||||
return !item->clipboardText().empty();
|
||||
};
|
||||
if (columnAlbum) {
|
||||
const auto simple = !ranges::any_of(group->items, hasCaption);
|
||||
if (!simple) {
|
||||
auto result = TextForMimeData();
|
||||
for (const auto &item : group->items) {
|
||||
if (result.empty()) {
|
||||
result = HistoryItemText(item);
|
||||
} else {
|
||||
result.append(qstr("\n\n")).append(HistoryItemText(item));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
auto caption = [&] {
|
||||
auto &&nonempty = ranges::view::all(
|
||||
group->items
|
||||
) | ranges::view::filter([](not_null<HistoryItem*> item) {
|
||||
return !item->clipboardText().empty();
|
||||
}) | ranges::view::take(2);
|
||||
) | ranges::view::filter(
|
||||
hasCaption
|
||||
) | ranges::view::take(2);
|
||||
auto first = nonempty.begin();
|
||||
auto end = nonempty.end();
|
||||
if (first == end) {
|
||||
|
|
|
@ -908,8 +908,7 @@ void Document::drawGrouped(
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const {
|
||||
not_null<QPixmap*> cache) const {
|
||||
p.translate(geometry.topLeft());
|
||||
draw(
|
||||
p,
|
||||
|
@ -924,8 +923,7 @@ TextState Document::getStateGrouped(
|
|||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const {
|
||||
StateRequest request) const {
|
||||
point -= geometry.topLeft();
|
||||
return textState(
|
||||
point,
|
||||
|
|
|
@ -73,14 +73,12 @@ public:
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const override;
|
||||
not_null<QPixmap*> cache) const override;
|
||||
TextState getStateGrouped(
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const override;
|
||||
StateRequest request) const override;
|
||||
|
||||
bool voiceProgressAnimationCallback(crl::time now);
|
||||
|
||||
|
|
|
@ -902,8 +902,7 @@ void Gif::drawGrouped(
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const {
|
||||
not_null<QPixmap*> cache) const {
|
||||
ensureDataMediaCreated();
|
||||
const auto item = _parent->data();
|
||||
const auto loaded = dataLoaded();
|
||||
|
@ -1091,8 +1090,7 @@ TextState Gif::getStateGrouped(
|
|||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const {
|
||||
StateRequest request) const {
|
||||
if (!geometry.contains(point)) {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -80,14 +80,12 @@ public:
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const override;
|
||||
not_null<QPixmap*> cache) const override;
|
||||
TextState getStateGrouped(
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const override;
|
||||
StateRequest request) const override;
|
||||
|
||||
void stopAnimation() override;
|
||||
void checkAnimation() override;
|
||||
|
|
|
@ -182,8 +182,7 @@ TextState Media::getStateGrouped(
|
|||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const {
|
||||
StateRequest request) const {
|
||||
Unexpected("Grouping method call.");
|
||||
}
|
||||
|
||||
|
|
|
@ -178,16 +178,14 @@ public:
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const {
|
||||
not_null<QPixmap*> cache) const {
|
||||
Unexpected("Grouping method call.");
|
||||
}
|
||||
[[nodiscard]] virtual TextState getStateGrouped(
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const;
|
||||
StateRequest request) const;
|
||||
|
||||
[[nodiscard]] virtual bool animating() const {
|
||||
return false;
|
||||
|
|
|
@ -254,14 +254,21 @@ void GroupedMedia::draw(
|
|||
TextSelection selection,
|
||||
crl::time ms) const {
|
||||
const auto groupPadding = groupedPadding();
|
||||
const auto fullSelection = (selection == FullSelection);
|
||||
const auto textSelection = !fullSelection
|
||||
&& !IsSubGroupSelection(selection);
|
||||
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
|
||||
const auto &part = _parts[i];
|
||||
const auto partSelection = (selection == FullSelection)
|
||||
const auto partSelection = fullSelection
|
||||
? FullSelection
|
||||
: textSelection
|
||||
? selection
|
||||
: IsGroupItemSelection(selection, i)
|
||||
? FullSelection
|
||||
: TextSelection();
|
||||
const auto last = (i + 1 == count);
|
||||
if (textSelection) {
|
||||
selection = part.content->skipSelection(selection);
|
||||
}
|
||||
part.content->drawGrouped(
|
||||
p,
|
||||
clip,
|
||||
|
@ -271,8 +278,7 @@ void GroupedMedia::draw(
|
|||
part.sides,
|
||||
cornersFromSides(part.sides),
|
||||
&part.cacheKey,
|
||||
&part.cache,
|
||||
last);
|
||||
&part.cache);
|
||||
}
|
||||
|
||||
// date
|
||||
|
@ -303,20 +309,19 @@ void GroupedMedia::draw(
|
|||
TextState GroupedMedia::getPartState(
|
||||
QPoint point,
|
||||
StateRequest request) const {
|
||||
auto index = 0;
|
||||
auto shift = 0;
|
||||
for (const auto &part : _parts) {
|
||||
++index;
|
||||
if (part.geometry.contains(point)) {
|
||||
const auto last = (index == _parts.size());
|
||||
auto result = part.content->getStateGrouped(
|
||||
part.geometry,
|
||||
part.sides,
|
||||
point,
|
||||
request,
|
||||
last);
|
||||
request);
|
||||
result.symbol += shift;
|
||||
result.itemId = part.item->fullId();
|
||||
return result;
|
||||
}
|
||||
shift += part.content->fullSelectionLength();
|
||||
}
|
||||
return TextState(_parent->data());
|
||||
}
|
||||
|
@ -389,12 +394,69 @@ bool GroupedMedia::dragItemByHandler(const ClickHandlerPtr &p) const {
|
|||
TextSelection GroupedMedia::adjustSelection(
|
||||
TextSelection selection,
|
||||
TextSelectType type) const {
|
||||
return _caption.adjustSelection(selection, type);
|
||||
if (_mode != Mode::Column) {
|
||||
return _caption.adjustSelection(selection, type);
|
||||
}
|
||||
auto checked = 0;
|
||||
for (const auto &part : _parts) {
|
||||
const auto modified = ShiftItemSelection(
|
||||
part.content->adjustSelection(
|
||||
UnshiftItemSelection(selection, checked),
|
||||
type),
|
||||
checked);
|
||||
const auto till = checked + part.content->fullSelectionLength();
|
||||
if (selection.from >= checked && selection.from < till) {
|
||||
selection.from = modified.from;
|
||||
}
|
||||
if (selection.to <= till) {
|
||||
selection.to = modified.to;
|
||||
return selection;
|
||||
}
|
||||
}
|
||||
return selection;
|
||||
}
|
||||
|
||||
uint16 GroupedMedia::fullSelectionLength() const {
|
||||
if (_mode != Mode::Column) {
|
||||
return _caption.length();
|
||||
}
|
||||
auto result = 0;
|
||||
for (const auto &part : _parts) {
|
||||
result += part.content->fullSelectionLength();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GroupedMedia::hasTextForCopy() const {
|
||||
if (_mode != Mode::Column) {
|
||||
return !_caption.isEmpty();
|
||||
}
|
||||
for (const auto &part : _parts) {
|
||||
if (part.content->hasTextForCopy()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TextForMimeData GroupedMedia::selectedText(
|
||||
TextSelection selection) const {
|
||||
return _caption.toTextForMimeData(selection);
|
||||
if (_mode != Mode::Column) {
|
||||
return _caption.toTextForMimeData(selection);
|
||||
}
|
||||
auto result = TextForMimeData();
|
||||
for (const auto &part : _parts) {
|
||||
auto text = part.content->selectedText(selection);
|
||||
if (!text.empty()) {
|
||||
if (result.empty()) {
|
||||
result = std::move(text);
|
||||
} else {
|
||||
result.append(qstr("\n\n")).append(std::move(text));
|
||||
}
|
||||
}
|
||||
selection = part.content->skipSelection(selection);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
auto GroupedMedia::getBubbleSelectionIntervals(
|
||||
|
|
|
@ -48,12 +48,8 @@ public:
|
|||
[[nodiscard]] TextSelection adjustSelection(
|
||||
TextSelection selection,
|
||||
TextSelectType type) const override;
|
||||
uint16 fullSelectionLength() const override {
|
||||
return _caption.length();
|
||||
}
|
||||
bool hasTextForCopy() const override {
|
||||
return !_caption.isEmpty();
|
||||
}
|
||||
uint16 fullSelectionLength() const override;
|
||||
bool hasTextForCopy() const override;
|
||||
|
||||
PhotoData *getPhoto() const override;
|
||||
DocumentData *getDocument() const override;
|
||||
|
|
|
@ -486,8 +486,7 @@ void Photo::drawGrouped(
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const {
|
||||
not_null<QPixmap*> cache) const {
|
||||
ensureDataMediaCreated();
|
||||
_dataMedia->automaticLoad(_realParent->fullId(), _parent->data());
|
||||
|
||||
|
@ -587,8 +586,7 @@ TextState Photo::getStateGrouped(
|
|||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const {
|
||||
StateRequest request) const {
|
||||
if (!geometry.contains(point)) {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -69,14 +69,12 @@ public:
|
|||
RectParts sides,
|
||||
RectParts corners,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache,
|
||||
bool last) const override;
|
||||
not_null<QPixmap*> cache) const override;
|
||||
TextState getStateGrouped(
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
QPoint point,
|
||||
StateRequest request,
|
||||
bool last) const override;
|
||||
StateRequest request) const override;
|
||||
|
||||
TextWithEntities getCaption() const override {
|
||||
return _caption.toTextWithEntities();
|
||||
|
|
Loading…
Reference in New Issue