mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-23 08:46:55 +00:00
Track noforwards flag in specific messages.
This commit is contained in:
parent
886ff7de50
commit
0f443da758
@ -1165,7 +1165,7 @@ bool DocumentData::canBeStreamed(HistoryItem *item) const {
|
||||
&& supportsStreaming()
|
||||
&& (!isVideoFile()
|
||||
|| !cUseExternalVideoPlayer()
|
||||
|| (item && !item->history()->peer->allowsForwarding()));
|
||||
|| (item && !item->allowsForward()));
|
||||
}
|
||||
|
||||
void DocumentData::setInappPlaybackFailed() {
|
||||
|
@ -521,8 +521,7 @@ bool PeerData::canEditMessagesIndefinitely() const {
|
||||
bool PeerData::canExportChatHistory() const {
|
||||
if (isRepliesChat() || !allowsForwarding()) {
|
||||
return false;
|
||||
}
|
||||
if (const auto channel = asChannel()) {
|
||||
} else if (const auto channel = asChannel()) {
|
||||
if (!channel->amIn() && channel->invitePeekExpires()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -236,52 +236,53 @@ enum class MessageFlag : uint32 {
|
||||
MediaIsUnread = (1U << 13),
|
||||
MentionsMe = (1U << 14),
|
||||
IsOrWasScheduled = (1U << 15),
|
||||
NoForwards = (1U << 16),
|
||||
|
||||
// Needs to return back to inline mode.
|
||||
HasSwitchInlineButton = (1U << 16),
|
||||
HasSwitchInlineButton = (1U << 17),
|
||||
|
||||
// For "shared links" indexing.
|
||||
HasTextLinks = (1U << 17),
|
||||
HasTextLinks = (1U << 18),
|
||||
|
||||
// Group / channel create or migrate service message.
|
||||
IsGroupEssential = (1U << 18),
|
||||
IsGroupEssential = (1U << 19),
|
||||
|
||||
// Edited media is generated on the client
|
||||
// and should not update media from server.
|
||||
IsLocalUpdateMedia = (1U << 19),
|
||||
IsLocalUpdateMedia = (1U << 20),
|
||||
|
||||
// Sent from inline bot, need to re-set media when sent.
|
||||
FromInlineBot = (1U << 20),
|
||||
FromInlineBot = (1U << 21),
|
||||
|
||||
// Generated on the client side and should be unread.
|
||||
ClientSideUnread = (1U << 21),
|
||||
ClientSideUnread = (1U << 22),
|
||||
|
||||
// In a supergroup.
|
||||
HasAdminBadge = (1U << 22),
|
||||
HasAdminBadge = (1U << 23),
|
||||
|
||||
// Outgoing message that is being sent.
|
||||
BeingSent = (1U << 23),
|
||||
BeingSent = (1U << 24),
|
||||
|
||||
// Outgoing message and failed to be sent.
|
||||
SendingFailed = (1U << 24),
|
||||
SendingFailed = (1U << 25),
|
||||
|
||||
// No media and only a several emoji text.
|
||||
IsolatedEmoji = (1U << 25),
|
||||
IsolatedEmoji = (1U << 26),
|
||||
|
||||
// Message existing in the message history.
|
||||
HistoryEntry = (1U << 26),
|
||||
HistoryEntry = (1U << 27),
|
||||
|
||||
// Local message, not existing on the server.
|
||||
Local = (1U << 27),
|
||||
Local = (1U << 28),
|
||||
|
||||
// Fake message for some UI element.
|
||||
FakeHistoryItem = (1U << 28),
|
||||
FakeHistoryItem = (1U << 29),
|
||||
|
||||
// Contact sign-up message, notification should be skipped for Silent.
|
||||
IsContactSignUp = (1U << 29),
|
||||
IsContactSignUp = (1U << 30),
|
||||
|
||||
// In channels.
|
||||
IsSponsored = (1U << 30),
|
||||
IsSponsored = (1U << 31),
|
||||
};
|
||||
inline constexpr bool is_flag_type(MessageFlag) { return true; }
|
||||
using MessageFlags = base::flags<MessageFlag>;
|
||||
|
@ -1546,7 +1546,7 @@ void HistoryInner::mouseActionFinish(
|
||||
if (QGuiApplication::clipboard()->supportsSelection()
|
||||
&& !_selected.empty()
|
||||
&& _selected.cbegin()->second != FullSelection
|
||||
&& !hasCopyRestriction()) {
|
||||
&& !hasCopyRestriction(_selected.cbegin()->first)) {
|
||||
const auto [item, selection] = *_selected.cbegin();
|
||||
if (const auto view = item->mainView()) {
|
||||
TextUtilities::SetClipboardText(
|
||||
@ -1723,14 +1723,15 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
}));
|
||||
}
|
||||
};
|
||||
const auto addPhotoActions = [&](not_null<PhotoData*> photo) {
|
||||
const auto addPhotoActions = [&](not_null<PhotoData*> photo, HistoryItem *item) {
|
||||
const auto media = photo->activeMediaView();
|
||||
if (!photo->isNull() && media && media->loaded() && !hasCopyRestriction()) {
|
||||
const auto itemId = item ? item->fullId() : FullMsgId();
|
||||
if (!photo->isNull() && media && media->loaded() && !hasCopyRestriction(item)) {
|
||||
_menu->addAction(tr::lng_context_save_image(tr::now), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
|
||||
savePhotoToFile(photo);
|
||||
}));
|
||||
_menu->addAction(tr::lng_context_copy_image(tr::now), [=] {
|
||||
copyContextImage(photo);
|
||||
copyContextImage(photo, itemId);
|
||||
});
|
||||
}
|
||||
if (photo->hasAttachedStickers()) {
|
||||
@ -1741,14 +1742,13 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
});
|
||||
}
|
||||
};
|
||||
const auto addDocumentActions = [&](not_null<DocumentData*> document) {
|
||||
const auto addDocumentActions = [&](not_null<DocumentData*> document, HistoryItem *item) {
|
||||
if (document->loading()) {
|
||||
_menu->addAction(tr::lng_context_cancel_download(tr::now), [=] {
|
||||
cancelContextDownload(document);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const auto item = _dragStateItem;
|
||||
const auto itemId = item ? item->fullId() : FullMsgId();
|
||||
const auto lnkIsVideo = document->isVideoFile();
|
||||
const auto lnkIsVoice = document->isVoiceMessage();
|
||||
@ -1767,7 +1767,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
openContextGif(itemId);
|
||||
});
|
||||
}
|
||||
if (!hasCopyRestriction()) {
|
||||
if (!hasCopyRestriction(item)) {
|
||||
_menu->addAction(tr::lng_context_save_gif(tr::now), [=] {
|
||||
saveContextGif(itemId);
|
||||
});
|
||||
@ -1778,7 +1778,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
showContextInFolder(document);
|
||||
});
|
||||
}
|
||||
if (!hasCopyRestriction()) {
|
||||
if (!hasCopyRestriction(item)) {
|
||||
_menu->addAction(lnkIsVideo ? tr::lng_context_save_video(tr::now) : (lnkIsVoice ? tr::lng_context_save_audio(tr::now) : (lnkIsAudio ? tr::lng_context_save_audio_file(tr::now) : tr::lng_context_save_file(tr::now))), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
|
||||
saveDocumentToFile(itemId, document);
|
||||
}));
|
||||
@ -1832,7 +1832,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
if (lnkPhoto || lnkDocument) {
|
||||
const auto item = _dragStateItem;
|
||||
const auto itemId = item ? item->fullId() : FullMsgId();
|
||||
if (isUponSelected > 0 && !hasCopyRestriction()) {
|
||||
if (isUponSelected > 0 && !hasCopyRestrictionForSelected()) {
|
||||
_menu->addAction(
|
||||
(isUponSelected > 1
|
||||
? tr::lng_context_copy_selected_items(tr::now)
|
||||
@ -1841,9 +1841,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
}
|
||||
addItemActions(item, item);
|
||||
if (lnkPhoto) {
|
||||
addPhotoActions(lnkPhoto->photo());
|
||||
addPhotoActions(lnkPhoto->photo(), item);
|
||||
} else {
|
||||
addDocumentActions(lnkDocument->document());
|
||||
addDocumentActions(lnkDocument->document(), item);
|
||||
}
|
||||
if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) {
|
||||
_menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_message_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] {
|
||||
@ -1913,7 +1913,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
const auto view = item ? item->mainView() : nullptr;
|
||||
|
||||
if (isUponSelected > 0) {
|
||||
if (!hasCopyRestriction()) {
|
||||
if (!hasCopyRestrictionForSelected()) {
|
||||
_menu->addAction(
|
||||
((isUponSelected > 1)
|
||||
? tr::lng_context_copy_selected_items(tr::now)
|
||||
@ -1936,7 +1936,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
Api::ToggleFavedSticker(document, itemId);
|
||||
});
|
||||
}
|
||||
if (!hasCopyRestriction()) {
|
||||
if (!hasCopyRestriction(item)) {
|
||||
_menu->addAction(tr::lng_context_save_image(tr::now), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
|
||||
saveDocumentToFile(itemId, document);
|
||||
}));
|
||||
@ -1965,7 +1965,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
if (!item->isService()
|
||||
&& view
|
||||
&& !link
|
||||
&& !hasCopyRestriction()
|
||||
&& !hasCopyRestriction(item)
|
||||
&& (view->hasVisibleText() || mediaHasTextForCopy)) {
|
||||
_menu->addAction(tr::lng_context_copy_text(tr::now), [=] {
|
||||
copyContextText(itemId);
|
||||
@ -2048,12 +2048,12 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryInner::hasCopyRestriction() const {
|
||||
return !_peer->allowsForwarding();
|
||||
bool HistoryInner::hasCopyRestriction(HistoryItem *item) const {
|
||||
return !_peer->allowsForwarding() || (item && item->forbidsForward());
|
||||
}
|
||||
|
||||
bool HistoryInner::showCopyRestriction() {
|
||||
if (!hasCopyRestriction()) {
|
||||
bool HistoryInner::showCopyRestriction(HistoryItem *item) {
|
||||
if (!hasCopyRestriction(item)) {
|
||||
return false;
|
||||
}
|
||||
Ui::ShowMultilineToast({
|
||||
@ -2064,8 +2064,29 @@ bool HistoryInner::showCopyRestriction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HistoryInner::hasCopyRestrictionForSelected() const {
|
||||
if (hasCopyRestriction()) {
|
||||
return true;
|
||||
}
|
||||
for (const auto &[item, selection] : _selected) {
|
||||
if (item && item->forbidsForward()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HistoryInner::showCopyRestrictionForSelected() {
|
||||
for (const auto &[item, selection] : _selected) {
|
||||
if (showCopyRestriction(item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HistoryInner::copySelectedText() {
|
||||
if (!showCopyRestriction()) {
|
||||
if (!showCopyRestrictionForSelected()) {
|
||||
TextUtilities::SetClipboardText(getSelectedText());
|
||||
}
|
||||
}
|
||||
@ -2092,11 +2113,14 @@ void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
|
||||
}));
|
||||
}
|
||||
|
||||
void HistoryInner::copyContextImage(not_null<PhotoData*> photo) {
|
||||
void HistoryInner::copyContextImage(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId itemId) {
|
||||
const auto item = session().data().message(itemId);
|
||||
const auto media = photo->activeMediaView();
|
||||
if (photo->isNull() || !media || !media->loaded()) {
|
||||
return;
|
||||
} else if (!showCopyRestriction()) {
|
||||
} else if (!showCopyRestriction(item)) {
|
||||
const auto image = media->image(Data::PhotoSize::Large)->original();
|
||||
QGuiApplication::clipboard()->setImage(image);
|
||||
}
|
||||
@ -2137,25 +2161,25 @@ void HistoryInner::openContextGif(FullMsgId itemId) {
|
||||
}
|
||||
|
||||
void HistoryInner::saveContextGif(FullMsgId itemId) {
|
||||
if (hasCopyRestriction()) {
|
||||
return;
|
||||
} else if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
Api::ToggleSavedGif(document, item->fullId(), true);
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
if (!hasCopyRestriction(item)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
Api::ToggleSavedGif(document, item->fullId(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryInner::copyContextText(FullMsgId itemId) {
|
||||
if (showCopyRestriction()) {
|
||||
return;
|
||||
} else if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto group = session().data().groups().find(item)) {
|
||||
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||
} else {
|
||||
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
if (!showCopyRestriction(item)) {
|
||||
if (const auto group = session().data().groups().find(item)) {
|
||||
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||
} else {
|
||||
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2248,7 +2272,7 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
|
||||
#ifdef Q_OS_MAC
|
||||
} else if (e->key() == Qt::Key_E
|
||||
&& e->modifiers().testFlag(Qt::ControlModifier)
|
||||
&& !showCopyRestriction()) {
|
||||
&& !showCopyRestrictionForSelected()) {
|
||||
TextUtilities::SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
||||
#endif // Q_OS_MAC
|
||||
} else if (e == QKeySequence::Delete) {
|
||||
|
@ -265,7 +265,7 @@ private:
|
||||
void saveDocumentToFile(
|
||||
FullMsgId contextId,
|
||||
not_null<DocumentData*> document);
|
||||
void copyContextImage(not_null<PhotoData*> photo);
|
||||
void copyContextImage(not_null<PhotoData*> photo, FullMsgId itemId);
|
||||
void showStickerPackInfo(not_null<DocumentData*> document);
|
||||
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
@ -343,8 +343,10 @@ private:
|
||||
void copySelectedText();
|
||||
|
||||
void setupSharingDisallowed();
|
||||
[[nodiscard]] bool hasCopyRestriction() const;
|
||||
bool showCopyRestriction();
|
||||
[[nodiscard]] bool hasCopyRestriction(HistoryItem *item = nullptr) const;
|
||||
bool showCopyRestriction(HistoryItem *item = nullptr);
|
||||
[[nodiscard]] bool hasCopyRestrictionForSelected() const;
|
||||
bool showCopyRestrictionForSelected();
|
||||
[[nodiscard]] bool hasSelectRestriction() const;
|
||||
|
||||
// Does any of the shown histories has this flag set.
|
||||
|
@ -645,6 +645,10 @@ bool HistoryItem::canStopPoll() const {
|
||||
return canBeEdited() && isRegular();
|
||||
}
|
||||
|
||||
bool HistoryItem::forbidsForward() const {
|
||||
return (_flags & MessageFlag::NoForwards);
|
||||
}
|
||||
|
||||
bool HistoryItem::canDelete() const {
|
||||
if (isSponsored()) {
|
||||
return false;
|
||||
@ -1088,7 +1092,8 @@ MessageFlags FlagsFromMTP(
|
||||
| ((flags & MTP::f_reply_to) ? Flag::HasReplyInfo : Flag())
|
||||
| ((flags & MTP::f_reply_markup) ? Flag::HasReplyMarkup : Flag())
|
||||
| ((flags & MTP::f_from_scheduled) ? Flag::IsOrWasScheduled : Flag())
|
||||
| ((flags & MTP::f_views) ? Flag::HasViews : Flag());
|
||||
| ((flags & MTP::f_views) ? Flag::HasViews : Flag())
|
||||
| ((flags & MTP::f_noforwards) ? Flag::NoForwards : Flag());
|
||||
}
|
||||
|
||||
MessageFlags FlagsFromMTP(
|
||||
|
@ -375,6 +375,7 @@ public:
|
||||
[[nodiscard]] bool canPin() const;
|
||||
[[nodiscard]] bool canBeEdited() const;
|
||||
[[nodiscard]] bool canStopPoll() const;
|
||||
[[nodiscard]] bool forbidsForward() const;
|
||||
[[nodiscard]] virtual bool allowsSendNow() const;
|
||||
[[nodiscard]] virtual bool allowsForward() const;
|
||||
[[nodiscard]] virtual bool allowsEdit(TimeId now) const;
|
||||
|
@ -1039,6 +1039,7 @@ void HistoryMessage::applySentMessage(
|
||||
|
||||
bool HistoryMessage::allowsForward() const {
|
||||
return isRegular()
|
||||
&& !forbidsForward()
|
||||
&& history()->peer->allowsForwarding()
|
||||
&& (!_media || _media->allowsForward());
|
||||
}
|
||||
|
@ -128,8 +128,10 @@ void ToggleFavedSticker(
|
||||
void AddPhotoActions(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
not_null<PhotoData*> photo,
|
||||
HistoryItem *item,
|
||||
not_null<ListWidget*> list) {
|
||||
if (!list->hasCopyRestriction()) {
|
||||
const auto contextId = item ? item->fullId() : FullMsgId();
|
||||
if (!list->hasCopyRestriction(item)) {
|
||||
menu->addAction(
|
||||
tr::lng_context_save_image(tr::now),
|
||||
App::LambdaDelayed(
|
||||
@ -137,7 +139,8 @@ void AddPhotoActions(
|
||||
&photo->session(),
|
||||
[=] { SavePhotoToFile(photo); }));
|
||||
menu->addAction(tr::lng_context_copy_image(tr::now), [=] {
|
||||
if (!list->showCopyRestriction()) {
|
||||
const auto item = photo->owner().message(contextId);
|
||||
if (!list->showCopyRestriction(item)) {
|
||||
CopyImage(photo);
|
||||
}
|
||||
});
|
||||
@ -187,12 +190,14 @@ void ShowInFolder(not_null<DocumentData*> document) {
|
||||
|
||||
void AddSaveDocumentAction(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
Data::FileOrigin origin,
|
||||
HistoryItem *item,
|
||||
not_null<DocumentData*> document,
|
||||
not_null<ListWidget*> list) {
|
||||
if (list->hasCopyRestriction()) {
|
||||
if (list->hasCopyRestriction(item)) {
|
||||
return;
|
||||
}
|
||||
const auto origin = Data::FileOrigin(
|
||||
item ? item->fullId() : FullMsgId());
|
||||
const auto save = [=] {
|
||||
DocumentSaveClickHandler::Save(
|
||||
origin,
|
||||
@ -219,7 +224,7 @@ void AddSaveDocumentAction(
|
||||
void AddDocumentActions(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId contextId,
|
||||
HistoryItem *item,
|
||||
not_null<ListWidget*> list) {
|
||||
if (document->loading()) {
|
||||
menu->addAction(tr::lng_context_cancel_download(tr::now), [=] {
|
||||
@ -227,8 +232,9 @@ void AddDocumentActions(
|
||||
});
|
||||
return;
|
||||
}
|
||||
const auto contextId = item ? item->fullId() : FullMsgId();
|
||||
const auto session = &document->session();
|
||||
if (const auto item = session->data().message(contextId)) {
|
||||
if (item) {
|
||||
const auto notAutoplayedGif = [&] {
|
||||
return document->isGifv()
|
||||
&& !Data::AutoDownload::ShouldAutoPlay(
|
||||
@ -241,7 +247,7 @@ void AddDocumentActions(
|
||||
OpenGif(list->controller(), contextId);
|
||||
});
|
||||
}
|
||||
if (document->isGifv() && !list->hasCopyRestriction()) {
|
||||
if (document->isGifv() && !list->hasCopyRestriction(item)) {
|
||||
menu->addAction(tr::lng_context_save_gif(tr::now), [=] {
|
||||
SaveGif(list->controller(), contextId);
|
||||
});
|
||||
@ -276,7 +282,7 @@ void AddDocumentActions(
|
||||
tr::lng_context_attached_stickers(tr::now),
|
||||
std::move(callback));
|
||||
}
|
||||
AddSaveDocumentAction(menu, contextId, document, list);
|
||||
AddSaveDocumentAction(menu, item, document, list);
|
||||
}
|
||||
|
||||
void AddPostLinkAction(
|
||||
@ -911,12 +917,12 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
|
||||
const auto hasSelection = !request.selectedItems.empty()
|
||||
|| !request.selectedText.empty();
|
||||
|
||||
if (request.overSelection && !list->hasCopyRestriction()) {
|
||||
if (request.overSelection && !list->hasCopyRestrictionForSelected()) {
|
||||
const auto text = request.selectedItems.empty()
|
||||
? tr::lng_context_copy_selected(tr::now)
|
||||
: tr::lng_context_copy_selected_items(tr::now);
|
||||
result->addAction(text, [=] {
|
||||
if (!list->showCopyRestriction()) {
|
||||
if (!list->showCopyRestrictionForSelected()) {
|
||||
TextUtilities::SetClipboardText(list->getSelectedText());
|
||||
}
|
||||
});
|
||||
@ -924,9 +930,9 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
|
||||
|
||||
AddTopMessageActions(result, request, list);
|
||||
if (linkPhoto) {
|
||||
AddPhotoActions(result, photo, list);
|
||||
AddPhotoActions(result, photo, item, list);
|
||||
} else if (linkDocument) {
|
||||
AddDocumentActions(result, document, itemId, list);
|
||||
AddDocumentActions(result, document, item, list);
|
||||
} else if (poll) {
|
||||
AddPollActions(result, poll, item, list->elementContext());
|
||||
} else if (!request.overSelection && view && !hasSelection) {
|
||||
@ -934,19 +940,15 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
|
||||
const auto media = view->media();
|
||||
const auto mediaHasTextForCopy = media && media->hasTextForCopy();
|
||||
if (const auto document = media ? media->getDocument() : nullptr) {
|
||||
AddDocumentActions(
|
||||
result,
|
||||
document,
|
||||
view->data()->fullId(),
|
||||
list);
|
||||
AddDocumentActions(result, document, view->data(), list);
|
||||
}
|
||||
if (!link
|
||||
&& (view->hasVisibleText() || mediaHasTextForCopy)
|
||||
&& !list->hasCopyRestriction()) {
|
||||
&& !list->hasCopyRestriction(view->data())) {
|
||||
const auto asGroup = (request.pointState != PointState::GroupPart);
|
||||
result->addAction(tr::lng_context_copy_text(tr::now), [=] {
|
||||
if (!list->showCopyRestriction()) {
|
||||
if (const auto item = owner->message(itemId)) {
|
||||
if (const auto item = owner->message(itemId)) {
|
||||
if (!list->showCopyRestriction(item)) {
|
||||
if (asGroup) {
|
||||
if (const auto group = owner->groups().find(item)) {
|
||||
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||
|
@ -1169,12 +1169,13 @@ bool ListWidget::isEmpty() const {
|
||||
&& (_itemsHeight + _itemsRevealHeight == 0);
|
||||
}
|
||||
|
||||
bool ListWidget::hasCopyRestriction() const {
|
||||
return _delegate->listCopyRestrictionType() != CopyRestrictionType::None;
|
||||
bool ListWidget::hasCopyRestriction(HistoryItem *item) const {
|
||||
return _delegate->listCopyRestrictionType(item)
|
||||
!= CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
bool ListWidget::showCopyRestriction() {
|
||||
const auto type = _delegate->listCopyRestrictionType();
|
||||
bool ListWidget::showCopyRestriction(HistoryItem *item) {
|
||||
const auto type = _delegate->listCopyRestrictionType(item);
|
||||
if (type == CopyRestrictionType::None) {
|
||||
return false;
|
||||
}
|
||||
@ -1186,6 +1187,29 @@ bool ListWidget::showCopyRestriction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ListWidget::hasCopyRestrictionForSelected() const {
|
||||
if (hasCopyRestriction()) {
|
||||
return true;
|
||||
}
|
||||
for (const auto [itemId, selection] : _selected) {
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
if (item->forbidsForward()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ListWidget::showCopyRestrictionForSelected() {
|
||||
for (const auto [itemId, selection] : _selected) {
|
||||
if (showCopyRestriction(session().data().message(itemId))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ListWidget::hasSelectRestriction() const {
|
||||
return _delegate->listSelectRestrictionType()
|
||||
!= CopyRestrictionType::None;
|
||||
@ -1922,12 +1946,14 @@ void ListWidget::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
} else if (e == QKeySequence::Copy
|
||||
&& (hasSelectedText() || hasSelectedItems())
|
||||
&& !showCopyRestriction()) {
|
||||
&& !showCopyRestriction()
|
||||
&& !hasCopyRestrictionForSelected()) {
|
||||
TextUtilities::SetClipboardText(getSelectedText());
|
||||
#ifdef Q_OS_MAC
|
||||
} else if (e->key() == Qt::Key_E
|
||||
&& e->modifiers().testFlag(Qt::ControlModifier)
|
||||
&& !showCopyRestriction()) {
|
||||
&& !showCopyRestriction()
|
||||
&& !hasCopyRestrictionForSelected()) {
|
||||
TextUtilities::SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
||||
#endif // Q_OS_MAC
|
||||
} else if (e == QKeySequence::Delete) {
|
||||
@ -2451,7 +2477,7 @@ void ListWidget::mouseActionFinish(
|
||||
if (QGuiApplication::clipboard()->supportsSelection()
|
||||
&& _selectedTextItem
|
||||
&& _selectedTextRange.from != _selectedTextRange.to
|
||||
&& !hasCopyRestriction()) {
|
||||
&& !hasCopyRestriction(_selectedTextItem)) {
|
||||
if (const auto view = viewForItem(_selectedTextItem)) {
|
||||
TextUtilities::SetClipboardText(
|
||||
view->selectedText(_selectedTextRange),
|
||||
@ -3091,8 +3117,9 @@ void ConfirmSendNowSelectedItems(not_null<ListWidget*> widget) {
|
||||
}
|
||||
|
||||
CopyRestrictionType CopyRestrictionTypeFor(
|
||||
not_null<PeerData*> peer) {
|
||||
return peer->allowsForwarding()
|
||||
not_null<PeerData*> peer,
|
||||
HistoryItem *item) {
|
||||
return (peer->allowsForwarding() && (!item || !item->forbidsForward()))
|
||||
? CopyRestrictionType::None
|
||||
: peer->isBroadcast()
|
||||
? CopyRestrictionType::Channel
|
||||
|
@ -100,7 +100,11 @@ public:
|
||||
const FullMsgId &context) = 0;
|
||||
virtual void listHandleViaClick(not_null<UserData*> bot) = 0;
|
||||
virtual not_null<Ui::ChatTheme*> listChatTheme() = 0;
|
||||
virtual CopyRestrictionType listCopyRestrictionType() = 0;
|
||||
virtual CopyRestrictionType listCopyRestrictionType(
|
||||
HistoryItem *item) = 0;
|
||||
CopyRestrictionType listCopyRestrictionType() {
|
||||
return listCopyRestrictionType(nullptr);
|
||||
}
|
||||
virtual CopyRestrictionType listSelectRestrictionType() = 0;
|
||||
|
||||
};
|
||||
@ -212,8 +216,10 @@ public:
|
||||
[[nodiscard]] bool loadedAtBottom() const;
|
||||
[[nodiscard]] bool isEmpty() const;
|
||||
|
||||
[[nodiscard]] bool hasCopyRestriction() const;
|
||||
[[nodiscard]] bool showCopyRestriction();
|
||||
[[nodiscard]] bool hasCopyRestriction(HistoryItem *item = nullptr) const;
|
||||
[[nodiscard]] bool showCopyRestriction(HistoryItem *item = nullptr);
|
||||
[[nodiscard]] bool hasCopyRestrictionForSelected() const;
|
||||
[[nodiscard]] bool showCopyRestrictionForSelected();
|
||||
[[nodiscard]] bool hasSelectRestriction() const;
|
||||
|
||||
// AbstractTooltipShower interface
|
||||
@ -617,7 +623,8 @@ void ConfirmForwardSelectedItems(not_null<ListWidget*> widget);
|
||||
void ConfirmSendNowSelectedItems(not_null<ListWidget*> widget);
|
||||
|
||||
[[nodiscard]] CopyRestrictionType CopyRestrictionTypeFor(
|
||||
not_null<PeerData*> peer);
|
||||
not_null<PeerData*> peer,
|
||||
HistoryItem *item = nullptr);
|
||||
[[nodiscard]] CopyRestrictionType SelectRestrictionTypeFor(
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
|
@ -2217,7 +2217,7 @@ std::optional<QSize> Message::rightActionSize() const {
|
||||
bool Message::displayFastShare() const {
|
||||
const auto item = message();
|
||||
const auto peer = item->history()->peer;
|
||||
if (!item->isRegular() || !peer->allowsForwarding()) {
|
||||
if (!item->allowsForward()) {
|
||||
return false;
|
||||
} else if (peer->isChannel()) {
|
||||
return !peer->isMegagroup();
|
||||
|
@ -676,8 +676,9 @@ not_null<Ui::ChatTheme*> PinnedWidget::listChatTheme() {
|
||||
return _theme.get();
|
||||
}
|
||||
|
||||
CopyRestrictionType PinnedWidget::listCopyRestrictionType() {
|
||||
return CopyRestrictionTypeFor(_history->peer);
|
||||
CopyRestrictionType PinnedWidget::listCopyRestrictionType(
|
||||
HistoryItem *item) {
|
||||
return CopyRestrictionTypeFor(_history->peer, item);
|
||||
}
|
||||
|
||||
CopyRestrictionType PinnedWidget::listSelectRestrictionType() {
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
const FullMsgId &context) override;
|
||||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
|
@ -1921,8 +1921,9 @@ not_null<Ui::ChatTheme*> RepliesWidget::listChatTheme() {
|
||||
return _theme.get();
|
||||
}
|
||||
|
||||
CopyRestrictionType RepliesWidget::listCopyRestrictionType() {
|
||||
return CopyRestrictionTypeFor(_history->peer);
|
||||
CopyRestrictionType RepliesWidget::listCopyRestrictionType(
|
||||
HistoryItem *item) {
|
||||
return CopyRestrictionTypeFor(_history->peer, item);
|
||||
}
|
||||
|
||||
CopyRestrictionType RepliesWidget::listSelectRestrictionType() {
|
||||
|
@ -139,7 +139,7 @@ public:
|
||||
const FullMsgId &context) override;
|
||||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
|
@ -1232,7 +1232,8 @@ not_null<Ui::ChatTheme*> ScheduledWidget::listChatTheme() {
|
||||
return _theme.get();
|
||||
}
|
||||
|
||||
CopyRestrictionType ScheduledWidget::listCopyRestrictionType() {
|
||||
CopyRestrictionType ScheduledWidget::listCopyRestrictionType(
|
||||
HistoryItem *item) {
|
||||
return CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
const FullMsgId &context) override;
|
||||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
|
@ -593,10 +593,9 @@ void Document::ensureDataMediaCreated() const {
|
||||
|
||||
bool Document::downloadInCorner() const {
|
||||
return _data->isAudioFile()
|
||||
&& _realParent->history()->peer->allowsForwarding()
|
||||
&& _realParent->allowsForward()
|
||||
&& _data->canBeStreamed(_realParent)
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& _realParent->isRegular();
|
||||
&& !_data->inappPlaybackFailed();
|
||||
}
|
||||
|
||||
void Document::drawCornerDownload(
|
||||
|
@ -264,10 +264,9 @@ QSize Gif::videoSize() const {
|
||||
bool Gif::downloadInCorner() const {
|
||||
return _data->isVideoFile()
|
||||
&& (_data->loading() || !autoplayEnabled())
|
||||
&& _realParent->history()->peer->allowsForwarding()
|
||||
&& _realParent->allowsForward()
|
||||
&& _data->canBeStreamed(_realParent)
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& !_parent->data()->isSending();
|
||||
&& !_data->inappPlaybackFailed();
|
||||
}
|
||||
|
||||
bool Gif::autoplayEnabled() const {
|
||||
|
@ -556,7 +556,8 @@ QSize OverlayWidget::flipSizeByRotation(QSize size) const {
|
||||
}
|
||||
|
||||
bool OverlayWidget::hasCopyRestriction() const {
|
||||
return _history && !_history->peer->allowsForwarding();
|
||||
return (_history && !_history->peer->allowsForwarding())
|
||||
|| (_message && _message->forbidsForward());
|
||||
}
|
||||
|
||||
bool OverlayWidget::showCopyRestriction() {
|
||||
|
@ -969,10 +969,9 @@ Document::Document(
|
||||
|
||||
bool Document::downloadInCorner() const {
|
||||
return _data->isAudioFile()
|
||||
&& parent()->history()->peer->allowsForwarding()
|
||||
&& parent()->allowsForward()
|
||||
&& _data->canBeStreamed(parent())
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& parent()->isRegular();
|
||||
&& !_data->inappPlaybackFailed();
|
||||
}
|
||||
|
||||
void Document::initDimensions() {
|
||||
|
Loading…
Reference in New Issue
Block a user