Fix copy selected items text in old and new lists.

This commit is contained in:
John Preston 2018-01-27 20:26:24 +03:00
parent e5f3bed801
commit 600737c44f
9 changed files with 175 additions and 169 deletions

View File

@ -130,6 +130,8 @@ QString WithCaptionNotificationText(
caption); caption);
} }
} // namespace
TextWithEntities WithCaptionClipboardText( TextWithEntities WithCaptionClipboardText(
const QString &attachType, const QString &attachType,
TextWithEntities &&caption) { TextWithEntities &&caption) {
@ -143,8 +145,6 @@ TextWithEntities WithCaptionClipboardText(
return result; return result;
} }
} // namespace
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) { Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
} }

View File

@ -364,4 +364,8 @@ private:
}; };
TextWithEntities WithCaptionClipboardText(
const QString &attachType,
TextWithEntities &&caption);
} // namespace Data } // namespace Data

View File

@ -1767,56 +1767,46 @@ TextWithEntities HistoryInner::getSelectedText() const {
} }
const auto timeFormat = qsl(", [dd.MM.yy hh:mm]\n"); const auto timeFormat = qsl(", [dd.MM.yy hh:mm]\n");
auto groupLeadersAdded = base::flat_set<not_null<Element*>>(); auto groups = base::flat_set<not_null<const Data::Group*>>();
auto fullSize = 0; auto fullSize = 0;
auto texts = base::flat_map<std::pair<int, MsgId>, TextWithEntities>(); auto texts = base::flat_map<Data::MessagePosition, TextWithEntities>();
const auto addItem = [&](not_null<HistoryView::Element*> view) { const auto wrapItem = [&](
const auto item = view->data(); not_null<HistoryItem*> item,
TextWithEntities &&unwrapped) {
auto time = item->date.toString(timeFormat); auto time = item->date.toString(timeFormat);
auto part = TextWithEntities(); auto part = TextWithEntities();
auto unwrapped = HistoryItemText(item);
auto size = item->author()->name.size() auto size = item->author()->name.size()
+ time.size() + time.size()
+ unwrapped.text.size(); + unwrapped.text.size();
part.text.reserve(size); part.text.reserve(size);
part.text.append(item->author()->name).append(time);
TextUtilities::Append(part, std::move(unwrapped));
texts.emplace(item->position(), part);
fullSize += size;
};
const auto addItem = [&](not_null<HistoryItem*> item) {
wrapItem(item, HistoryItemText(item));
};
const auto addGroup = [&](not_null<const Data::Group*> group) {
Expects(!group->items.empty());
auto y = itemTop(view); wrapItem(group->items.back(), HistoryGroupText(group));
if (y >= 0) {
part.text.append(item->author()->name).append(time);
TextUtilities::Append(part, std::move(unwrapped));
texts.emplace(std::make_pair(y, item->id), part);
fullSize += size;
}
}; };
for (const auto [item, selection] : selected) { for (const auto [item, selection] : selected) {
const auto view = item->mainView();
if (!view) {
continue;
}
if (const auto group = Auth().data().groups().find(item)) { if (const auto group = Auth().data().groups().find(item)) {
// #TODO group copy if (groups.contains(group)) {
//if (groupLeadersAdded.contains(group->leader)) { continue;
// continue; }
//} if (isSelectedGroup(&selected, group)) {
//const auto leaderSelection = computeRenderSelection( groups.emplace(group);
// &selected, addGroup(group);
// group->leader); } else {
//if (leaderSelection == FullSelection) { addItem(item);
// groupLeadersAdded.emplace(group->leader); }
// addItem(group->leader);
//} else if (view == group->leader) {
// const auto leaderFullSelection = AddGroupItemSelection(
// TextSelection(),
// int(group->others.size()));
// addItem(view, leaderFullSelection);
//} else {
// addItem(view);
//}
} else { } else {
addItem(view); addItem(item);
} }
} }
@ -2686,16 +2676,22 @@ bool HistoryInner::isSelected(
return (i != toItems->cend()) && (i->second == FullSelection); return (i != toItems->cend()) && (i->second == FullSelection);
} }
bool HistoryInner::isSelectedGroup(
not_null<SelectedItems*> toItems,
not_null<const Data::Group*> group) const {
for (const auto other : group->items) {
if (!isSelected(toItems, other)) {
return false;
}
}
return true;
}
bool HistoryInner::isSelectedAsGroup( bool HistoryInner::isSelectedAsGroup(
not_null<SelectedItems*> toItems, not_null<SelectedItems*> toItems,
not_null<HistoryItem*> item) const { not_null<HistoryItem*> item) const {
if (const auto group = Auth().data().groups().find(item)) { if (const auto group = Auth().data().groups().find(item)) {
for (const auto other : group->items) { return isSelectedGroup(toItems, group);
if (!isSelected(toItems, other)) {
return false;
}
}
return true;
} }
return isSelected(toItems, item); return isSelected(toItems, item);
} }

View File

@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/scroll_area.h" #include "ui/widgets/scroll_area.h"
#include "history/view/history_view_top_bar_widget.h" #include "history/view/history_view_top_bar_widget.h"
namespace Data {
class Group;
} // namespace Data
namespace HistoryView { namespace HistoryView {
class ElementDelegate; class ElementDelegate;
struct TextState; struct TextState;
@ -244,6 +248,9 @@ private:
bool isSelected( bool isSelected(
not_null<SelectedItems*> toItems, not_null<SelectedItems*> toItems,
not_null<HistoryItem*> item) const; not_null<HistoryItem*> item) const;
bool isSelectedGroup(
not_null<SelectedItems*> toItems,
not_null<const Data::Group*> group) const;
bool isSelectedAsGroup( bool isSelectedAsGroup(
not_null<SelectedItems*> toItems, not_null<SelectedItems*> toItems,
not_null<HistoryItem*> item) const; not_null<HistoryItem*> item) const;

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h" #include "history/history_item_components.h"
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_web_page.h" #include "data/data_web_page.h"
#include "data/data_groups.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/text_options.h" #include "ui/text_options.h"
@ -55,11 +56,27 @@ TextWithEntities WrapAsForwarded(
return result; return result;
} }
TextWithEntities WrapAsItem(
not_null<HistoryItem*> item,
TextWithEntities &&result) {
if (const auto reply = item->Get<HistoryMessageReply>()) {
if (const auto message = reply->replyToMsg) {
result = WrapAsReply(std::move(result), message);
}
}
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
result = WrapAsForwarded(std::move(result), forwarded);
}
return result;
}
TextWithEntities HistoryItemText(not_null<HistoryItem*> item) { TextWithEntities HistoryItemText(not_null<HistoryItem*> item) {
const auto media = item->media(); const auto media = item->media();
auto textResult = item->clipboardText();
auto mediaResult = media ? media->clipboardText() : TextWithEntities(); auto mediaResult = media ? media->clipboardText() : TextWithEntities();
auto textResult = mediaResult.text.isEmpty()
? item->clipboardText()
: TextWithEntities();
auto logEntryOriginalResult = [&] { auto logEntryOriginalResult = [&] {
const auto entry = item->Get<HistoryMessageLogEntryOriginal>(); const auto entry = item->Get<HistoryMessageLogEntryOriginal>();
if (!entry) { if (!entry) {
@ -94,13 +111,26 @@ TextWithEntities HistoryItemText(not_null<HistoryItem*> item) {
result.text += qstr("\n\n"); result.text += qstr("\n\n");
TextUtilities::Append(result, std::move(logEntryOriginalResult)); TextUtilities::Append(result, std::move(logEntryOriginalResult));
} }
if (const auto reply = item->Get<HistoryMessageReply>()) { return WrapAsItem(item, std::move(result));
if (const auto message = reply->replyToMsg) { }
result = WrapAsReply(std::move(result), message);
} TextWithEntities HistoryGroupText(not_null<const Data::Group*> group) {
} Expects(!group->items.empty());
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
result = WrapAsForwarded(std::move(result), forwarded); auto caption = [&] {
} const auto first = begin(group->items);
return result; const auto result = (*first)->clipboardText();
if (result.text.isEmpty()) {
return result;
}
for (auto i = first + 1; i != end(group->items); ++i) {
if (!(*i)->clipboardText().text.isEmpty()) {
return TextWithEntities();
}
}
return result;
}();
return WrapAsItem(group->items.back(), Data::WithCaptionClipboardText(
lang(lng_in_dlg_album),
std::move(caption)));
} }

View File

@ -7,4 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
class HistoryItem;
namespace Data {
class Group;
} // namespace Data
TextWithEntities HistoryItemText(not_null<HistoryItem*> item); TextWithEntities HistoryItemText(not_null<HistoryItem*> item);
TextWithEntities HistoryGroupText(not_null<const Data::Group*> group);

View File

@ -280,16 +280,6 @@ TextSelection HistoryGroupedMedia::adjustSelection(
TextWithEntities HistoryGroupedMedia::selectedText( TextWithEntities HistoryGroupedMedia::selectedText(
TextSelection selection) const { TextSelection selection) const {
return _caption.originalTextWithEntities(selection, ExpandLinksAll); return _caption.originalTextWithEntities(selection, ExpandLinksAll);
// #TODO group select
//if (!IsSubGroupSelection(selection)) {
// return WithCaptionSelectedText(
// lang(lng_in_dlg_album),
// _caption,
// selection);
//} else if (IsGroupItemSelection(selection, int(_parts.size()) - 1)) {
// return main()->selectedText(FullSelection);
//}
//return TextWithEntities();
} }
void HistoryGroupedMedia::clickHandlerActiveChanged( void HistoryGroupedMedia::clickHandlerActiveChanged(

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_media_types.h" #include "history/history_media_types.h"
#include "history/history_message.h" #include "history/history_message.h"
#include "history/history_item_components.h" #include "history/history_item_components.h"
#include "history/history_item_text.h"
#include "history/view/history_view_context_menu.h" #include "history/view/history_view_context_menu.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "history/view/history_view_message.h" #include "history/view/history_view_message.h"
@ -527,53 +528,22 @@ bool ListWidget::overSelectedItems() const {
return false; return false;
} }
//bool ListWidget::applyItemSelection( bool ListWidget::isSelectedGroup(
// SelectedMap &applyTo, const SelectedMap &applyTo,
// FullMsgId itemId) const { not_null<const Data::Group*> group) const {
// if (applyTo.size() >= MaxSelectedItems) { for (const auto other : group->items) {
// return false; if (!applyTo.contains(other->fullId())) {
// } return false;
// auto [iterator, ok] = applyTo.try_emplace( }
// itemId, }
// SelectionData()); return true;
// if (!ok) { }
// return false;
// }
// const auto item = App::histItemById(itemId);
// if (!item) {
// applyTo.erase(iterator);
// return false;
// }
// iterator->second.canDelete = item->canDelete();
// iterator->second.canForward = item->allowsForward();
// return true;
//}
//
//void ListWidget::toggleItemSelection(FullMsgId itemId) {
// auto it = _selected.find(itemId);
// if (it == _selected.cend()) {
// if (_selectedTextItem) {
// clearTextSelection();
// }
// if (applyItemSelection(_selected, itemId)) {
// repaintItem(itemId);
// pushSelectedItems();
// }
// } else {
// removeItemSelection(it);
// }
//}
bool ListWidget::isSelectedAsGroup( bool ListWidget::isSelectedAsGroup(
const SelectedMap &applyTo, const SelectedMap &applyTo,
not_null<HistoryItem*> item) const { not_null<HistoryItem*> item) const {
if (const auto group = Auth().data().groups().find(item)) { if (const auto group = Auth().data().groups().find(item)) {
for (const auto other : group->items) { return isSelectedGroup(applyTo, group);
if (!applyTo.contains(other->fullId())) {
return false;
}
}
return true;
} }
return applyTo.contains(item->fullId()); return applyTo.contains(item->fullId());
} }
@ -1135,72 +1105,69 @@ TextWithEntities ListWidget::getSelectedText() const {
return _selectedText; return _selectedText;
} }
// #TODO selection const auto timeFormat = qsl(", [dd.MM.yy hh:mm]\n");
//const auto timeFormat = qsl(", [dd.MM.yy hh:mm]\n"); auto groups = base::flat_set<not_null<const Data::Group*>>();
//auto groupLeadersAdded = base::flat_set<not_null<Element*>>(); auto fullSize = 0;
//auto fullSize = 0; auto texts = std::vector<std::pair<
//auto texts = base::flat_map<std::pair<int, MsgId>, TextWithEntities>(); not_null<HistoryItem*>,
TextWithEntities>>();
texts.reserve(selected.size());
//const auto addItem = [&]( const auto wrapItem = [&](
// not_null<HistoryView::Element*> view, not_null<HistoryItem*> item,
// TextSelection selection) { TextWithEntities &&unwrapped) {
// const auto item = view->data(); auto time = item->date.toString(timeFormat);
// auto time = item->date.toString(timeFormat); auto part = TextWithEntities();
// auto part = TextWithEntities(); auto size = item->author()->name.size()
// auto unwrapped = view->selectedText(selection); + time.size()
// auto size = item->author()->name.size() + unwrapped.text.size();
// + time.size() part.text.reserve(size);
// + unwrapped.text.size(); part.text.append(item->author()->name).append(time);
// part.text.reserve(size); TextUtilities::Append(part, std::move(unwrapped));
texts.push_back(std::make_pair(std::move(item), std::move(part)));
fullSize += size;
};
const auto addItem = [&](not_null<HistoryItem*> item) {
wrapItem(item, HistoryItemText(item));
};
const auto addGroup = [&](not_null<const Data::Group*> group) {
Expects(!group->items.empty());
// auto y = itemTop(view); wrapItem(group->items.back(), HistoryGroupText(group));
// if (y >= 0) { };
// part.text.append(item->author()->name).append(time);
// TextUtilities::Append(part, std::move(unwrapped));
// texts.emplace(std::make_pair(y, item->id), part);
// fullSize += size;
// }
//};
//for (const auto [item, selection] : selected) { for (const auto [itemId, data] : selected) {
// const auto view = item->mainView(); if (const auto item = App::histItemById(itemId)) {
// if (!view) { if (const auto group = Auth().data().groups().find(item)) {
// continue; if (groups.contains(group)) {
// } continue;
}
// if (const auto group = Auth().data().groups().find(item)) { if (isSelectedGroup(selected, group)) {
// // #TODO group copy groups.emplace(group);
// //if (groupLeadersAdded.contains(group->leader)) { addGroup(group);
// // continue; } else {
// //} addItem(item);
// //const auto leaderSelection = computeRenderSelection( }
// // &selected, } else {
// // group->leader); addItem(item);
// //if (leaderSelection == FullSelection) { }
// // groupLeadersAdded.emplace(group->leader); }
// // addItem(group->leader, FullSelection); }
// //} else if (view == group->leader) { ranges::sort(texts, [&](
// // const auto leaderFullSelection = AddGroupItemSelection( const std::pair<not_null<HistoryItem*>, TextWithEntities> &a,
// // TextSelection(), const std::pair<not_null<HistoryItem*>, TextWithEntities> &b) {
// // int(group->others.size())); return _delegate->listIsLessInOrder(a.first, b.first);
// // addItem(view, leaderFullSelection); });
// //} else {
// // addItem(view, FullSelection);
// //}
// } else {
// addItem(view, FullSelection);
// }
//}
auto result = TextWithEntities(); auto result = TextWithEntities();
//auto sep = qsl("\n\n"); auto sep = qsl("\n\n");
//result.text.reserve(fullSize + (texts.size() - 1) * sep.size()); result.text.reserve(fullSize + (texts.size() - 1) * sep.size());
//for (auto i = texts.begin(), e = texts.end(); i != e;) { for (auto i = begin(texts), e = end(texts); i != e;) {
// TextUtilities::Append(result, std::move(i->second)); TextUtilities::Append(result, std::move(i->second));
// if (++i != e) { if (++i != e) {
// result.text.append(sep); result.text.append(sep);
// } }
//} }
return result; return result;
} }

View File

@ -22,6 +22,10 @@ namespace Window {
class Controller; class Controller;
} // namespace Window } // namespace Window
namespace Data {
class Group;
} // namespace Data
namespace HistoryView { namespace HistoryView {
struct TextState; struct TextState;
@ -288,8 +292,6 @@ private:
void setTextSelection( void setTextSelection(
not_null<Element*> view, not_null<Element*> view,
TextSelection selection); TextSelection selection);
//bool applyItemSelection(SelectedMap &applyTo, FullMsgId itemId) const;
//void toggleItemSelection(FullMsgId itemId);
bool isGoodForSelection(not_null<HistoryItem*> item) const; bool isGoodForSelection(not_null<HistoryItem*> item) const;
bool isGoodForSelection( bool isGoodForSelection(
@ -306,6 +308,9 @@ private:
SelectedMap &applyTo, SelectedMap &applyTo,
not_null<HistoryItem*> item, not_null<HistoryItem*> item,
SelectAction action) const; SelectAction action) const;
bool isSelectedGroup(
const SelectedMap &applyTo,
not_null<const Data::Group*> group) const;
bool isSelectedAsGroup( bool isSelectedAsGroup(
const SelectedMap &applyTo, const SelectedMap &applyTo,
not_null<HistoryItem*> item) const; not_null<HistoryItem*> item) const;