Fix captions selection in column albums.

This commit is contained in:
John Preston 2020-10-29 19:12:43 +03:00
parent 6d9c529a65
commit 6e682643df
11 changed files with 119 additions and 50 deletions

View file

@ -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) {

View file

@ -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,

View file

@ -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);

View file

@ -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 {};
}

View file

@ -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;

View file

@ -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.");
}

View file

@ -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;

View file

@ -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(

View file

@ -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;

View file

@ -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 {};
}

View file

@ -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();