Delete for everyone checkbox added. Various bugfixes.

This commit is contained in:
John Preston 2016-12-31 19:19:22 +04:00
parent 218f991547
commit eec5b78054
28 changed files with 414 additions and 260 deletions

View File

@ -959,6 +959,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_selected_delete_sure_this" = "Do you want to delete this message?"; "lng_selected_delete_sure_this" = "Do you want to delete this message?";
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?"; "lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
"lng_delete_photo_sure" = "Do you want to delete this photo?"; "lng_delete_photo_sure" = "Do you want to delete this photo?";
"lng_delete_for_everyone_this_hint" = "This will delete it for everyone in this chat.";
"lng_delete_for_everyone_hint" = "This will delete {count:_not_used_|it|them} for everyone in this chat.";
"lng_delete_for_me_chat_this_hint" = "This will delete it just for you, not for other participants of the chat.";
"lng_delete_for_me_chat_hint" = "This will delete {count:_not_used_|it|them} just for you, not for other participants of the chat.";
"lng_delete_for_me_this_hint" = "This will delete it just for you.";
"lng_delete_for_me_hint" = "This will delete {count:_not_used_|it|them} just for you.";
"lng_delete_for_everyone_check" = "Delete for everyone";
"lng_delete_for_other_check" = "Delete for {user}";
"lng_box_delete" = "Delete"; "lng_box_delete" = "Delete";
"lng_box_leave" = "Leave"; "lng_box_leave" = "Leave";

View File

@ -33,6 +33,16 @@ defaultBoxButton: RoundButton(defaultLightButton) {
font: boxButtonFont; font: boxButtonFont;
} }
boxTextStyle: TextStyle(defaultTextStyle) {
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
boxLabelStyle: TextStyle(boxTextStyle) {
lineHeight: 22px;
}
attentionBoxButton: RoundButton(defaultBoxButton) { attentionBoxButton: RoundButton(defaultBoxButton) {
textFg: attentionButtonFg; textFg: attentionButtonFg;
textFgOver: attentionButtonFgOver; textFgOver: attentionButtonFgOver;
@ -46,7 +56,7 @@ attentionBoxButton: RoundButton(defaultBoxButton) {
defaultBoxCheckbox: Checkbox(defaultCheckbox) { defaultBoxCheckbox: Checkbox(defaultCheckbox) {
width: -46px; width: -46px;
textPosition: point(34px, 1px); textPosition: point(34px, 1px);
font: boxTextFont; style: boxTextStyle;
} }
boxRoundShadow: Shadow { boxRoundShadow: Shadow {
@ -108,12 +118,9 @@ boxMediumSkip: 20px;
boxButtonPadding: margins(8px, 12px, 13px, 12px); boxButtonPadding: margins(8px, 12px, 13px, 12px);
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px); boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
boxLabel: FlatLabel(defaultFlatLabel) { boxLabel: FlatLabel(defaultFlatLabel) {
width: 285px;
align: align(topleft); align: align(topleft);
style: TextStyle(defaultTextStyle) { style: boxLabelStyle;
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
} }
countryRowHeight: 36px; countryRowHeight: 36px;
@ -131,10 +138,6 @@ countriesScroll: ScrollArea(boxLayerScroll) {
deltab: 3px; deltab: 3px;
} }
boxTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 22px;
}
boxPhotoTitleFont: font(16px semibold); boxPhotoTitleFont: font(16px semibold);
boxPhotoTitlePosition: point(28px, 20px); boxPhotoTitlePosition: point(28px, 20px);
boxPhotoPadding: margins(28px, 28px, 28px, 18px); boxPhotoPadding: margins(28px, 28px, 28px, 18px);

View File

@ -112,7 +112,7 @@ base::lambda<void()> ConfirmBox::generateInformCallback(const base::lambda_copy<
} }
void ConfirmBox::init(const QString &text) { void ConfirmBox::init(const QString &text) {
_text.setText(st::boxTextStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions); _text.setText(st::boxLabelStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
} }
void ConfirmBox::prepare() { void ConfirmBox::prepare() {
@ -125,7 +125,7 @@ void ConfirmBox::prepare() {
void ConfirmBox::textUpdated() { void ConfirmBox::textUpdated() {
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight)); _textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight);
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom()); setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
setMouseTracking(_text.hasLinks()); setMouseTracking(_text.hasLinks());
@ -219,7 +219,7 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, bas
} }
MaxInviteBox::MaxInviteBox(QWidget*, const QString &link) MaxInviteBox::MaxInviteBox(QWidget*, const QString &link)
: _text(st::boxTextStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) : _text(st::boxLabelStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
, _link(link) { , _link(link) {
} }
@ -229,7 +229,7 @@ void MaxInviteBox::prepare() {
addButton(lang(lng_box_ok), [this] { closeBox(); }); addButton(lang(lng_box_ok), [this] { closeBox(); });
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight)); _textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight);
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom()); setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom());
} }
@ -302,8 +302,8 @@ void ConvertToSupergroupBox::prepare() {
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); }); addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
_text.setText(st::boxTextStyle, text.join('\n'), _confirmBoxTextOptions); _text.setText(st::boxLabelStyle, text.join('\n'), _confirmBoxTextOptions);
_note.setText(st::boxTextStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions); _note.setText(st::boxLabelStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = _text.countHeight(_textWidth); _textHeight = _text.countHeight(_textWidth);
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth)); setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
@ -408,55 +408,136 @@ bool PinMessageBox::pinFail(const RPCError &error) {
return true; return true;
} }
RichDeleteMessageBox::RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId) DeleteMessagesBox::DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions) : _singleItem(true) {
: _channel(channel) _ids.push_back(item->fullId());
, _from(from) if (suggestModerateActions && item->suggestBanReportDeleteAll()) {
, _msgId(msgId) _moderateFrom = item->from()->asUser();
, _text(this, lang(lng_selected_delete_sure_this), Ui::FlatLabel::InitType::Simple, st::boxLabel) _moderateInChannel = item->history()->peer->asChannel();
, _banUser(this, lang(lng_ban_user), false, st::defaultBoxCheckbox) }
, _reportSpam(this, lang(lng_report_spam), false, st::defaultBoxCheckbox)
, _deleteAll(this, lang(lng_delete_all_from), false, st::defaultBoxCheckbox) {
} }
void RichDeleteMessageBox::prepare() { DeleteMessagesBox::DeleteMessagesBox(QWidget*, const SelectedItemSet &selected) {
t_assert(_channel != nullptr); auto count = selected.size();
t_assert(count > 0);
_ids.reserve(count);
for_const (auto item, selected) {
_ids.push_back(item->fullId());
}
}
void DeleteMessagesBox::prepare() {
auto text = QString();
if (_moderateFrom) {
t_assert(_moderateInChannel != nullptr);
text = lang(lng_selected_delete_sure_this);
_banUser.create(this, lang(lng_ban_user), false, st::defaultBoxCheckbox);
_reportSpam.create(this, lang(lng_report_spam), false, st::defaultBoxCheckbox);
_deleteAll.create(this, lang(lng_delete_all_from), false, st::defaultBoxCheckbox);
} else {
text = _singleItem ? lang(lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, _ids.size());
auto canDeleteAllForEveryone = true;
auto now = ::date(unixtime());
auto deleteForUser = (UserData*)nullptr;
auto peer = (PeerData*)nullptr;
auto forEveryoneText = lang(lng_delete_for_everyone_check);
for_const (auto fullId, _ids) {
if (auto item = App::histItemById(fullId)) {
peer = item->history()->peer;
if (!item->canDeleteForEveryone(now)) {
canDeleteAllForEveryone = false;
break;
} else if (auto user = item->history()->peer->asUser()) {
if (!deleteForUser || deleteForUser == user) {
deleteForUser = user;
forEveryoneText = lng_delete_for_other_check(lt_user, user->firstName);
} else {
forEveryoneText = lang(lng_delete_for_everyone_check);
}
}
} else {
canDeleteAllForEveryone = false;
}
}
if (canDeleteAllForEveryone) {
_forEveryone.create(this, forEveryoneText, false, st::defaultBoxCheckbox);
} else if (peer && peer->isChannel()) {
if (peer->isMegagroup()) {
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_everyone_this_hint) : lng_delete_for_everyone_hint(lt_count, _ids.size()));
}
} else if (peer->isChat()) {
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_me_chat_this_hint) : lng_delete_for_me_chat_hint(lt_count, _ids.size()));
} else {
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_me_this_hint) : lng_delete_for_me_hint(lt_count, _ids.size()));
}
}
_text.create(this, text, Ui::FlatLabel::InitType::Simple, st::boxLabel);
addButton(lang(lng_box_delete), [this] { deleteAndClear(); }); addButton(lang(lng_box_delete), [this] { deleteAndClear(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
_text->resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()); _text->resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxMediumSkip + _banUser->heightNoMargins() + st::boxLittleSkip + _reportSpam->heightNoMargins() + st::boxLittleSkip + _deleteAll->heightNoMargins() + st::boxPadding.bottom()); auto fullHeight = st::boxPadding.top() + _text->height() + st::boxPadding.bottom();
if (_moderateFrom) {
fullHeight += st::boxMediumSkip + _banUser->heightNoMargins() + st::boxLittleSkip + _reportSpam->heightNoMargins() + st::boxLittleSkip + _deleteAll->heightNoMargins();
} else if (_forEveryone) {
fullHeight += st::boxMediumSkip + _forEveryone->heightNoMargins();
}
setDimensions(st::boxWidth, fullHeight);
} }
void RichDeleteMessageBox::resizeEvent(QResizeEvent *e) { void DeleteMessagesBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e); BoxContent::resizeEvent(e);
_text->moveToLeft(st::boxPadding.left(), st::boxPadding.top()); _text->moveToLeft(st::boxPadding.left(), st::boxPadding.top());
if (_moderateFrom) {
_banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip); _banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
_reportSpam->moveToLeft(st::boxPadding.left(), _banUser->bottomNoMargins() + st::boxLittleSkip); _reportSpam->moveToLeft(st::boxPadding.left(), _banUser->bottomNoMargins() + st::boxLittleSkip);
_deleteAll->moveToLeft(st::boxPadding.left(), _reportSpam->bottomNoMargins() + st::boxLittleSkip); _deleteAll->moveToLeft(st::boxPadding.left(), _reportSpam->bottomNoMargins() + st::boxLittleSkip);
} else if (_forEveryone) {
_forEveryone->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
}
} }
void RichDeleteMessageBox::deleteAndClear() { void DeleteMessagesBox::deleteAndClear() {
if (!App::main()) {
return;
}
if (_moderateFrom) {
if (_banUser->checked()) { if (_banUser->checked()) {
MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived)); MTP::send(MTPchannels_KickFromChannel(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
} }
if (_reportSpam->checked()) { if (_reportSpam->checked()) {
MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId)))); MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_vector<MTPint>(1, MTP_int(_ids[0].msg))));
} }
if (_deleteAll->checked()) { if (_deleteAll->checked()) {
App::main()->deleteAllFromUser(_channel, _from); App::main()->deleteAllFromUser(_moderateInChannel, _moderateFrom);
} }
if (auto item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) { }
auto wasLast = (item->history()->lastMsg == item);
if (!_singleItem) {
App::main()->clearSelectedItems();
}
QMap<PeerData*, QVector<MTPint>> idsByPeer;
for_const (auto fullId, _ids) {
if (auto item = App::histItemById(fullId)) {
auto history = item->history();
auto wasOnServer = (item->id > 0);
auto wasLast = (history->lastMsg == item);
item->destroy(); item->destroy();
if (_msgId > 0) { if (wasOnServer) {
auto forEveryone = true; idsByPeer[history->peer].push_back(MTP_int(fullId.msg));
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)), forEveryone);
} else if (wasLast) { } else if (wasLast) {
App::main()->checkPeerHistory(_channel); App::main()->checkPeerHistory(history->peer);
} }
} }
}
auto forEveryone = _forEveryone ? _forEveryone->checked() : false;
for (auto i = idsByPeer.cbegin(), e = idsByPeer.cend(); i != e; ++i) {
App::main()->deleteMessages(i.key(), i.value(), forEveryone);
}
Ui::hideLayer(); Ui::hideLayer();
} }

View File

@ -170,9 +170,10 @@ private:
}; };
class RichDeleteMessageBox : public BoxContent, public RPCSender { class DeleteMessagesBox : public BoxContent, public RPCSender {
public: public:
RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId); DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions);
DeleteMessagesBox(QWidget*, const SelectedItemSet &selected);
protected: protected:
void prepare() override; void prepare() override;
@ -182,14 +183,16 @@ protected:
private: private:
void deleteAndClear(); void deleteAndClear();
ChannelData *_channel; QVector<FullMsgId> _ids;
UserData *_from; bool _singleItem = false;
MsgId _msgId; UserData *_moderateFrom = nullptr;
ChannelData *_moderateInChannel = nullptr;
object_ptr<Ui::FlatLabel> _text; object_ptr<Ui::FlatLabel> _text = { nullptr };
object_ptr<Ui::Checkbox> _banUser; object_ptr<Ui::Checkbox> _forEveryone = { nullptr };
object_ptr<Ui::Checkbox> _reportSpam; object_ptr<Ui::Checkbox> _banUser = { nullptr };
object_ptr<Ui::Checkbox> _deleteAll; object_ptr<Ui::Checkbox> _reportSpam = { nullptr };
object_ptr<Ui::Checkbox> _deleteAll = { nullptr };
}; };

View File

@ -374,7 +374,7 @@ void MembersBox::Inner::refresh() {
resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom); resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom);
_aboutHeight = 0; _aboutHeight = 0;
} else { } else {
_about.setText(st::boxTextStyle, lng_channel_only_last_shown(lt_count, _rows.size())); _about.setText(st::boxLabelStyle, lng_channel_only_last_shown(lt_count, _rows.size()));
_aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom(); _aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom();
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) { if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
_aboutHeight = 0; _aboutHeight = 0;

View File

@ -148,7 +148,7 @@ StickersBox::StickersBox(QWidget*, const Stickers::Order &archivedIds)
: _section(Section::ArchivedPart) : _section(Section::ArchivedPart)
, _archived(0, this, archivedIds) , _archived(0, this, archivedIds)
, _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top()) , _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top())
, _about(st::boxTextStyle, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) { , _about(st::boxLabelStyle, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) {
} }
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) { void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {

View File

@ -316,18 +316,7 @@ PeerData *getPeerForMouseAction() {
bool hideWindowNoQuit() { bool hideWindowNoQuit() {
if (!App::quitting()) { if (!App::quitting()) {
if (auto w = App::wnd()) { if (auto w = App::wnd()) {
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { w->hideNoQuit();
if (w->minimizeToTray()) {
Ui::showChatsList();
return true;
}
} else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
w->closeWithoutDestroy();
w->updateIsActive(Global::OfflineBlurTimeout());
w->updateGlobalMenu();
Ui::showChatsList();
return true;
}
} }
} }
return false; return false;

View File

@ -48,6 +48,14 @@ constexpr int kSetMyActionForMs = 10000;
auto GlobalPinnedIndex = 0; auto GlobalPinnedIndex = 0;
HistoryItem *createUnsupportedMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from) {
QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org")));
EntitiesInText entities;
textParseEntities(text, _historyTextNoMonoOptions.flags, &entities);
entities.push_front(EntityInText(EntityInTextItalic, 0, text.size()));
return HistoryMessage::create(history, msgId, flags, replyTo, viaBotId, date, from, { text, entities });
}
} // namespace } // namespace
void historyInit() { void historyInit() {
@ -741,7 +749,7 @@ void Histories::clearPinned() {
} }
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) { HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
MsgId msgId = 0; auto msgId = MsgId(0);
switch (msg.type()) { switch (msg.type()) {
case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break; case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break;
case mtpc_message: msgId = msg.c_message().vid.v; break; case mtpc_message: msgId = msg.c_message().vid.v; break;
@ -749,7 +757,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
} }
if (!msgId) return nullptr; if (!msgId) return nullptr;
HistoryItem *result = App::histItemById(channelId(), msgId); auto result = App::histItemById(channelId(), msgId);
if (result) { if (result) {
if (!result->detached() && detachExistingItem) { if (!result->detached() && detachExistingItem) {
result->detach(); result->detach();
@ -769,37 +777,42 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
break; break;
case mtpc_message: { case mtpc_message: {
const auto &m(msg.c_message()); auto &m = msg.c_message();
int badMedia = 0; // 1 - unsupported, 2 - empty enum class MediaCheckResult {
Good,
Unsupported,
Empty,
};
auto badMedia = MediaCheckResult::Good;
if (m.has_media()) switch (m.vmedia.type()) { if (m.has_media()) switch (m.vmedia.type()) {
case mtpc_messageMediaEmpty: case mtpc_messageMediaEmpty:
case mtpc_messageMediaContact: break; case mtpc_messageMediaContact: break;
case mtpc_messageMediaGeo: case mtpc_messageMediaGeo:
switch (m.vmedia.c_messageMediaGeo().vgeo.type()) { switch (m.vmedia.c_messageMediaGeo().vgeo.type()) {
case mtpc_geoPoint: break; case mtpc_geoPoint: break;
case mtpc_geoPointEmpty: badMedia = 2; break; case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaVenue: case mtpc_messageMediaVenue:
switch (m.vmedia.c_messageMediaVenue().vgeo.type()) { switch (m.vmedia.c_messageMediaVenue().vgeo.type()) {
case mtpc_geoPoint: break; case mtpc_geoPoint: break;
case mtpc_geoPointEmpty: badMedia = 2; break; case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaPhoto: case mtpc_messageMediaPhoto:
switch (m.vmedia.c_messageMediaPhoto().vphoto.type()) { switch (m.vmedia.c_messageMediaPhoto().vphoto.type()) {
case mtpc_photo: break; case mtpc_photo: break;
case mtpc_photoEmpty: badMedia = 2; break; case mtpc_photoEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaDocument: case mtpc_messageMediaDocument:
switch (m.vmedia.c_messageMediaDocument().vdocument.type()) { switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
case mtpc_document: break; case mtpc_document: break;
case mtpc_documentEmpty: badMedia = 2; break; case mtpc_documentEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaWebPage: case mtpc_messageMediaWebPage:
@ -808,25 +821,21 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
case mtpc_webPageEmpty: case mtpc_webPageEmpty:
case mtpc_webPagePending: break; case mtpc_webPagePending: break;
case mtpc_webPageNotModified: case mtpc_webPageNotModified:
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaGame: case mtpc_messageMediaGame:
switch (m.vmedia.c_messageMediaGame().vgame.type()) { switch (m.vmedia.c_messageMediaGame().vgame.type()) {
case mtpc_game: break; case mtpc_game: break;
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
break; break;
case mtpc_messageMediaUnsupported: case mtpc_messageMediaUnsupported:
default: badMedia = 1; break; default: badMedia = MediaCheckResult::Unsupported; break;
} }
if (badMedia == 1) { if (badMedia == MediaCheckResult::Unsupported) {
QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org"))); result = createUnsupportedMessage(this, m.vid.v, m.vflags.v, m.vreply_to_msg_id.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v);
EntitiesInText entities; } else if (badMedia == MediaCheckResult::Empty) {
textParseEntities(text, _historyTextNoMonoOptions.flags, &entities);
entities.push_front(EntityInText(EntityInTextItalic, 0, text.size()));
result = HistoryMessage::create(this, m.vid.v, m.vflags.v, m.vreply_to_msg_id.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, { text, entities });
} else if (badMedia) {
result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, m.has_from_id() ? m.vfrom_id.v : 0); result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, m.has_from_id() ? m.vfrom_id.v : 0);
} else { } else {
result = HistoryMessage::create(this, m); result = HistoryMessage::create(this, m);
@ -834,18 +843,23 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
} break; } break;
case mtpc_messageService: { case mtpc_messageService: {
const auto &d(msg.c_messageService()); auto &m = msg.c_messageService();
result = HistoryService::create(this, d); if (m.vaction.type() == mtpc_messageActionPhoneCall) {
auto viaBotId = 0;
result = createUnsupportedMessage(this, m.vid.v, mtpCastFlags(m.vflags.v), m.vreply_to_msg_id.v, viaBotId, date(m.vdate), m.vfrom_id.v);
} else {
result = HistoryService::create(this, m);
}
if (applyServiceAction) { if (applyServiceAction) {
const auto &action(d.vaction); auto &action = m.vaction;
switch (d.vaction.type()) { switch (action.type()) {
case mtpc_messageActionChatAddUser: { case mtpc_messageActionChatAddUser: {
const auto &d(action.c_messageActionChatAddUser()); auto &d = action.c_messageActionChatAddUser();
if (peer->isMegagroup()) { if (peer->isMegagroup()) {
const auto &v(d.vusers.c_vector().v); auto &v = d.vusers.c_vector().v;
for (int32 i = 0, l = v.size(); i < l; ++i) { for (auto i = 0, l = v.size(); i != l; ++i) {
if (UserData *user = App::userLoaded(peerFromUser(v.at(i)))) { if (auto user = App::userLoaded(peerFromUser(v[i]))) {
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) { if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) {
peer->asChannel()->mgInfo->lastParticipants.push_front(user); peer->asChannel()->mgInfo->lastParticipants.push_front(user);
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
@ -863,7 +877,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
} break; } break;
case mtpc_messageActionChatJoinedByLink: { case mtpc_messageActionChatJoinedByLink: {
const auto &d(action.c_messageActionChatJoinedByLink()); auto &d = action.c_messageActionChatJoinedByLink();
if (peer->isMegagroup()) { if (peer->isMegagroup()) {
if (result->from()->isUser()) { if (result->from()->isUser()) {
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) { if (peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) {
@ -881,13 +895,13 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
} break; } break;
case mtpc_messageActionChatDeletePhoto: { case mtpc_messageActionChatDeletePhoto: {
ChatData *chat = peer->asChat(); auto chat = peer->asChat();
if (chat) chat->setPhoto(MTP_chatPhotoEmpty()); if (chat) chat->setPhoto(MTP_chatPhotoEmpty());
} break; } break;
case mtpc_messageActionChatDeleteUser: { case mtpc_messageActionChatDeleteUser: {
const auto &d(action.c_messageActionChatDeleteUser()); auto &d = action.c_messageActionChatDeleteUser();
PeerId uid = peerFromUser(d.vuser_id); auto uid = peerFromUser(d.vuser_id);
if (lastKeyboardFrom == uid) { if (lastKeyboardFrom == uid) {
clearLastKeyboard(); clearLastKeyboard();
} }
@ -952,7 +966,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
} break; } break;
case mtpc_messageActionChatEditTitle: { case mtpc_messageActionChatEditTitle: {
auto &d(action.c_messageActionChatEditTitle()); auto &d = action.c_messageActionChatEditTitle();
if (auto chat = peer->asChat()) { if (auto chat = peer->asChat()) {
chat->setName(qs(d.vtitle)); chat->setName(qs(d.vtitle));
} }
@ -961,18 +975,18 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
case mtpc_messageActionChatMigrateTo: { case mtpc_messageActionChatMigrateTo: {
peer->asChat()->flags |= MTPDchat::Flag::f_deactivated; peer->asChat()->flags |= MTPDchat::Flag::f_deactivated;
//const auto &d(action.c_messageActionChatMigrateTo()); //auto &d = action.c_messageActionChatMigrateTo();
//PeerData *channel = App::channelLoaded(d.vchannel_id.v); //auto channel = App::channelLoaded(d.vchannel_id.v);
} break; } break;
case mtpc_messageActionChannelMigrateFrom: { case mtpc_messageActionChannelMigrateFrom: {
//const auto &d(action.c_messageActionChannelMigrateFrom()); //auto &d = action.c_messageActionChannelMigrateFrom();
//PeerData *chat = App::chatLoaded(d.vchat_id.v); //auto chat = App::chatLoaded(d.vchat_id.v);
} break; } break;
case mtpc_messageActionPinMessage: { case mtpc_messageActionPinMessage: {
if (d.has_reply_to_msg_id() && result && result->history()->peer->isMegagroup()) { if (m.has_reply_to_msg_id() && result && result->history()->peer->isMegagroup()) {
result->history()->peer->asChannel()->mgInfo->pinnedMsgId = d.vreply_to_msg_id.v; result->history()->peer->asChannel()->mgInfo->pinnedMsgId = m.vreply_to_msg_id.v;
if (App::main()) emit App::main()->peerUpdated(result->history()->peer); if (App::main()) emit App::main()->peerUpdated(result->history()->peer);
} }
} break; } break;

View File

@ -772,6 +772,18 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
return false; return false;
} }
bool HistoryItem::canDeleteForEveryone(const QDateTime &cur) const {
auto messageToMyself = (peerToUser(_history->peer->id) == MTP::authedId());
auto messageTooOld = messageToMyself ? false : (date.secsTo(cur) >= Global::EditTimeLimit());
if (id < 0 || messageToMyself || messageTooOld) return false;
if (history()->peer->isChannel()) return false;
if (auto msg = toHistoryMessage()) {
return !isPost() && out();
}
return false;
}
bool HistoryItem::unread() const { bool HistoryItem::unread() const {
// Messages from myself are always read. // Messages from myself are always read.
if (history()->peer->isSelf()) return false; if (history()->peer->isSelf()) return false;

View File

@ -704,6 +704,7 @@ public:
} }
bool canEdit(const QDateTime &cur) const; bool canEdit(const QDateTime &cur) const;
bool canDeleteForEveryone(const QDateTime &cur) const;
bool suggestBanReportDeleteAll() const { bool suggestBanReportDeleteAll() const {
ChannelData *channel = history()->peer->asChannel(); ChannelData *channel = history()->peer->asChannel();

View File

@ -2848,7 +2848,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
_send->show(); _send->show();
_cancel->show(); _cancel->show();
} }
h += st::boxTopMargin + qMax(st::boxTextFont->height, st::boxTextStyle.lineHeight) + st::boxButtonPadding.top() + _send->height() + st::boxButtonPadding.bottom(); h += st::boxTopMargin + qMax(st::boxTextFont->height, st::boxLabelStyle.lineHeight) + st::boxButtonPadding.top() + _send->height() + st::boxButtonPadding.bottom();
} else { } else {
h += st::historyForwardChooseFont->height; h += st::historyForwardChooseFont->height;
_send->hide(); _send->hide();
@ -2862,7 +2862,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
bool HistoryHider::offerPeer(PeerId peer) { bool HistoryHider::offerPeer(PeerId peer) {
if (!peer) { if (!peer) {
_offered = nullptr; _offered = nullptr;
_toText.setText(st::boxTextStyle, QString()); _toText.setText(st::boxLabelStyle, QString());
_toTextWidth = 0; _toTextWidth = 0;
resizeEvent(nullptr); resizeEvent(nullptr);
return false; return false;
@ -2902,7 +2902,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
return false; return false;
} }
_toText.setText(st::boxTextStyle, phrase, _textNameOptions); _toText.setText(st::boxLabelStyle, phrase, _textNameOptions);
_toTextWidth = _toText.maxWidth(); _toTextWidth = _toText.maxWidth();
if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) { if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) {
_toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right(); _toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right();
@ -8352,8 +8352,13 @@ void HistoryWidget::confirmDeleteContextItem() {
auto item = App::contextItem(); auto item = App::contextItem();
if (!item || item->type() != HistoryItemMsg) return; if (!item || item->type() != HistoryItemMsg) return;
auto message = item->toHistoryMessage(); if (auto message = item->toHistoryMessage()) {
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1); if (message->uploading()) {
App::main()->cancelUploadLayer();
return;
}
}
App::main()->deleteLayer();
} }
void HistoryWidget::confirmDeleteSelectedItems() { void HistoryWidget::confirmDeleteSelectedItems() {

View File

@ -660,43 +660,39 @@ void MainWidget::forwardLayer(int forwardSelected) {
} }
void MainWidget::deleteLayer(int selectedCount) { void MainWidget::deleteLayer(int selectedCount) {
if (selectedCount == -1 && !_overview) { if (selectedCount) {
if (auto item = App::contextItem()) { auto forDelete = true;
if (item->suggestBanReportDeleteAll()) { SelectedItemSet selected;
Ui::show(Box<RichDeleteMessageBox>(item->history()->peer->asChannel(), item->from()->asUser(), item->id)); if (_overview) {
_overview->fillSelectedItems(selected, forDelete);
} else {
_history->fillSelectedItems(selected, forDelete);
}
if (!selected.isEmpty()) {
Ui::show(Box<DeleteMessagesBox>(selected));
}
} else if (auto item = App::contextItem()) {
auto suggestModerateActions = !_overview;
Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
}
}
void MainWidget::cancelUploadLayer() {
auto item = App::contextItem();
if (!item) {
return; return;
} }
}
}
auto text = (selectedCount < 0) ? lang(selectedCount < -1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, selectedCount);
auto confirmText = lang((selectedCount < -1) ? lng_selected_upload_stop : lng_box_delete);
auto cancelText = lang((selectedCount < -1) ? lng_continue : lng_cancel);
if (selectedCount < -1) {
if (auto item = App::contextItem()) {
App::uploader()->pause(item->fullId()); App::uploader()->pause(item->fullId());
} Ui::show(Box<ConfirmBox>(lang(lng_selected_cancel_sure_this), lang(lng_selected_upload_stop), lang(lng_continue), base::lambda_guarded(this, [this] {
}
Ui::show(Box<ConfirmBox>(text, confirmText, cancelText, base::lambda_guarded(this, [this, selectedCount] {
if (selectedCount < 0) {
if (_overview) { if (_overview) {
_overview->deleteContextItem(false); _overview->deleteContextItem(false);
} else { } else {
_history->deleteContextItem(false); _history->deleteContextItem(false);
} }
if (selectedCount < -1) {
App::uploader()->unpause(); App::uploader()->unpause();
} }), base::lambda_guarded(this, [] {
} else {
if (_overview) {
_overview->deleteSelectedItems(false);
} else {
_history->deleteSelectedItems(false);
}
}
}), base::lambda_guarded(this, [selectedCount] {
if (selectedCount < -1) {
App::uploader()->unpause(); App::uploader()->unpause();
}
}))); })));
} }

View File

@ -228,7 +228,8 @@ public:
int32 dlgsWidth() const; int32 dlgsWidth() const;
void forwardLayer(int forwardSelected = 0); // -1 - send paths void forwardLayer(int forwardSelected = 0); // -1 - send paths
void deleteLayer(int selectedCount = -1); // -1 - context item, else selected, -2 - cancel upload void deleteLayer(int selectedCount = 0); // 0 - context item
void cancelUploadLayer();
void shareContactLayer(UserData *contact); void shareContactLayer(UserData *contact);
void shareUrlLayer(const QString &url, const QString &text); void shareUrlLayer(const QString &url, const QString &text);
void inlineSwitchLayer(const QString &botAndQuery); void inlineSwitchLayer(const QString &botAndQuery);

View File

@ -204,11 +204,7 @@ void MainWindow::firstShow() {
psFirstShow(); psFirstShow();
updateTrayMenu(); updateTrayMenu();
_mediaView = new MediaView(); createMediaView();
}
QWidget *MainWindow::filedialogParent() {
return (_mediaView && _mediaView->isVisible()) ? (QWidget*)_mediaView : (QWidget*)this;
} }
void MainWindow::clearWidgets() { void MainWindow::clearWidgets() {
@ -600,30 +596,6 @@ void MainWindow::layerHidden() {
checkHistoryActivation(); checkHistoryActivation();
} }
void MainWindow::onReActivate() {
if (auto w = App::wnd()) {
if (auto f = QApplication::focusWidget()) {
f->clearFocus();
}
w->windowHandle()->requestActivate();
w->activate();
if (auto f = QApplication::focusWidget()) {
f->clearFocus();
}
w->setInnerFocus();
}
}
void MainWindow::hideMediaview() {
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->hide();
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
onReActivate();
QTimer::singleShot(200, this, SLOT(onReActivate()));
#endif
}
}
bool MainWindow::contentOverlapped(const QRect &globalRect) { bool MainWindow::contentOverlapped(const QRect &globalRect) {
if (_main && _main->contentOverlapped(globalRect)) return true; if (_main && _main->contentOverlapped(globalRect)) return true;
if (_layerBg && _layerBg->contentOverlapped(globalRect)) return true; if (_layerBg && _layerBg->contentOverlapped(globalRect)) return true;
@ -712,21 +684,6 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
return Platform::MainWindow::eventFilter(obj, e); return Platform::MainWindow::eventFilter(obj, e);
} }
bool MainWindow::minimizeToTray() {
if (App::quitting() || !psHasTrayIcon()) return false;
closeWithoutDestroy();
if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) {
trayIcon->showMessage(str_const_toString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000);
cSetSeenTrayTooltip(true);
Local::writeSettings();
}
updateIsActive(Global::OfflineBlurTimeout());
updateTrayMenu();
updateGlobalMenu();
return true;
}
void MainWindow::updateTrayMenu(bool force) { void MainWindow::updateTrayMenu(bool force) {
if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return; if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return;
@ -1450,7 +1407,6 @@ MainWindow::~MainWindow() {
_clearManager->stop(); _clearManager->stop();
_clearManager = nullptr; _clearManager = nullptr;
} }
delete _mediaView;
delete trayIcon; delete trayIcon;
delete trayIconMenu; delete trayIconMenu;
} }

View File

@ -80,8 +80,6 @@ public:
void firstShow(); void firstShow();
QWidget *filedialogParent();
void inactivePress(bool inactive); void inactivePress(bool inactive);
bool inactivePress() const; bool inactivePress() const;
@ -142,7 +140,6 @@ public:
void changingMsgId(HistoryItem *row, MsgId newId); void changingMsgId(HistoryItem *row, MsgId newId);
bool isActive(bool cached = true) const; bool isActive(bool cached = true) const;
void hideMediaview();
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override; QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
@ -184,7 +181,6 @@ public slots:
void quitFromTray(); void quitFromTray();
void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
bool minimizeToTray();
void toggleTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); void toggleTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
void toggleDisplayNotifyFromTray(); void toggleDisplayNotifyFromTray();
@ -202,8 +198,6 @@ public slots:
void onLogout(); void onLogout();
void updateGlobalMenu(); // for OS X top menu void updateGlobalMenu(); // for OS X top menu
void onReActivate();
void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
signals: signals:
@ -283,8 +277,6 @@ private:
using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>; using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>;
NotifyWhenAlerts _notifyWhenAlerts; NotifyWhenAlerts _notifyWhenAlerts;
MediaView *_mediaView = nullptr;
}; };
class PreLaunchWindow : public TWidget { class PreLaunchWindow : public TWidget {

View File

@ -200,7 +200,7 @@ mediaviewCaptionRadius: 2px;
themePreviewSize: size(903px, 584px); themePreviewSize: size(903px, 584px);
themePreviewBg: windowBg; themePreviewBg: windowBg;
themePreviewOverlayOpacity: 0.7; themePreviewOverlayOpacity: 0.8;
themePreviewMargin: margins(36px, 52px, 36px, 88px); themePreviewMargin: margins(36px, 52px, 36px, 88px);
themePreviewTitleTop: 14px; themePreviewTitleTop: 14px;
themePreviewTitleFg: windowBoldFg; themePreviewTitleFg: windowBoldFg;

View File

@ -67,7 +67,7 @@ bool typeHasMediaOverview(MediaOverviewType type) {
} // namespace } // namespace
MediaView::MediaView() : TWidget(App::wnd()) MediaView::MediaView(QWidget*) : TWidget(nullptr)
, _animStarted(getms()) , _animStarted(getms())
, _docDownload(this, lang(lng_media_download), st::mediaviewFileLink) , _docDownload(this, lang(lng_media_download), st::mediaviewFileLink)
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink) , _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
@ -75,7 +75,8 @@ MediaView::MediaView() : TWidget(App::wnd())
, _radial(animation(this, &MediaView::step_radial)) , _radial(animation(this, &MediaView::step_radial))
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction) , _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
, _a_state(animation(this, &MediaView::step_state)) , _a_state(animation(this, &MediaView::step_state))
, _dropdown(this, st::mediaviewDropdownMenu) { , _dropdown(this, st::mediaviewDropdownMenu)
, _dropdownShowTimer(this) {
TextCustomTagsMap custom; TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
_saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom); _saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom);
@ -121,6 +122,8 @@ MediaView::MediaView() : TWidget(App::wnd())
connect(_docCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel())); connect(_docCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel()));
_dropdown->setHiddenCallback([this] { dropdownHidden(); }); _dropdown->setHiddenCallback([this] { dropdownHidden(); });
_dropdownShowTimer->setSingleShot(true);
connect(_dropdownShowTimer, SIGNAL(timeout()), this, SLOT(onDropdown()));
} }
void MediaView::moveToScreen() { void MediaView::moveToScreen() {
@ -1333,8 +1336,9 @@ void MediaView::updateThemePreviewGeometry() {
auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height()); auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height());
_themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin); _themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin);
if (_themeApply) { if (_themeApply) {
auto right = width() - _themePreviewRect.x() - _themePreviewRect.width() + st::themePreviewMargin.right(); auto right = qMax(width() - _themePreviewRect.x() - _themePreviewRect.width(), 0) + st::themePreviewMargin.right();
_themeApply->moveToRight(right, _themePreviewRect.y() + _themePreviewRect.height() - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2); auto bottom = qMin(height(), _themePreviewRect.y() + _themePreviewRect.height());
_themeApply->moveToRight(right, bottom - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2);
right += _themeApply->width() + st::themePreviewButtonsSkip; right += _themeApply->width() + st::themePreviewButtonsSkip;
_themeCancel->moveToRight(right, _themeApply->y()); _themeCancel->moveToRight(right, _themeApply->y());
} }
@ -2370,7 +2374,9 @@ bool MediaView::updateOverState(OverState newState) {
bool result = true; bool result = true;
if (_over != newState) { if (_over != newState) {
if (newState == OverMore && !_ignoringDropdown) { if (newState == OverMore && !_ignoringDropdown) {
QTimer::singleShot(0, this, SLOT(onDropdown())); _dropdownShowTimer->start(0);
} else {
_dropdownShowTimer->stop();
} }
updateOverRect(_over); updateOverRect(_over);
updateOverRect(newState); updateOverRect(newState);
@ -2393,7 +2399,7 @@ bool MediaView::updateOverState(OverState newState) {
if (i != _animOpacities.end()) { if (i != _animOpacities.end()) {
i->start(1); i->start(1);
} else { } else {
_animOpacities.insert(_over, anim::value()); _animOpacities.insert(_over, anim::value(0, 1));
} }
if (!_a_state.animating()) _a_state.start(); if (!_a_state.animating()) _a_state.start();
} }

View File

@ -47,7 +47,7 @@ class MediaView : public TWidget, private base::Subscriber, public RPCSender, pu
Q_OBJECT Q_OBJECT
public: public:
MediaView(); MediaView(QWidget*);
void setVisible(bool visible) override; void setVisible(bool visible) override;
@ -330,6 +330,7 @@ private:
Ui::PopupMenu *_menu = nullptr; Ui::PopupMenu *_menu = nullptr;
object_ptr<Ui::DropdownMenu> _dropdown; object_ptr<Ui::DropdownMenu> _dropdown;
object_ptr<QTimer> _dropdownShowTimer;
struct ActionData { struct ActionData {
QString text; QString text;

View File

@ -2276,16 +2276,21 @@ void OverviewWidget::confirmDeleteContextItem() {
auto item = App::contextItem(); auto item = App::contextItem();
if (!item || item->type() != HistoryItemMsg) return; if (!item || item->type() != HistoryItemMsg) return;
auto message = item->toHistoryMessage(); if (auto message = item->toHistoryMessage()) {
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1); if (message->uploading()) {
App::main()->cancelUploadLayer();
return;
}
}
App::main()->deleteLayer();
} }
void OverviewWidget::confirmDeleteSelectedItems() { void OverviewWidget::confirmDeleteSelectedItems() {
SelectedItemSet sel; SelectedItemSet selected;
_inner->fillSelectedItems(sel); _inner->fillSelectedItems(selected);
if (sel.isEmpty()) return; if (selected.isEmpty()) return;
App::main()->deleteLayer(sel.size()); App::main()->deleteLayer(selected.size());
} }
void OverviewWidget::deleteContextItem(bool forEveryone) { void OverviewWidget::deleteContextItem(bool forEveryone) {

View File

@ -51,8 +51,6 @@ public:
virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0; virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
void closeWithoutDestroy() override;
int getCustomTitleHeight() const { int getCustomTitleHeight() const {
return _customTitleHeight; return _customTitleHeight;
} }
@ -103,6 +101,8 @@ protected:
QTimer psUpdatedPositionTimer; QTimer psUpdatedPositionTimer;
void closeWithoutDestroy() override;
private: private:
void createGlobalMenu(); void createGlobalMenu();
void updateTitleCounter(); void updateTitleCounter();

View File

@ -927,7 +927,7 @@ void PhotoCancelClickHandler::onClickImpl() const {
if (auto media = item->getMedia()) { if (auto media = item->getMedia()) {
if (media->type() == MediaTypePhoto && static_cast<HistoryPhoto*>(media)->photo() == data) { if (media->type() == MediaTypePhoto && static_cast<HistoryPhoto*>(media)->photo() == data) {
App::contextItem(item); App::contextItem(item);
App::main()->deleteLayer(-2); App::main()->cancelUploadLayer();
} }
} }
} }
@ -1240,7 +1240,7 @@ void DocumentCancelClickHandler::onClickImpl() const {
if (auto media = item->getMedia()) { if (auto media = item->getMedia()) {
if (media->getDocument() == data) { if (media->getDocument() == data) {
App::contextItem(item); App::contextItem(item);
App::main()->deleteLayer(-2); App::main()->cancelUploadLayer();
} }
} }
} }

View File

@ -79,6 +79,13 @@ public:
Radiobuttons radiobuttons; Radiobuttons radiobuttons;
TextParseOptions _checkboxOptions = {
TextParseMultiline, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
} // namespace } // namespace
void RadiobuttonGroup::remove(Radiobutton * const &radio) { void RadiobuttonGroup::remove(Radiobutton * const &radio) {
@ -90,17 +97,11 @@ void RadiobuttonGroup::remove(Radiobutton * const &radio) {
Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple) Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
, _st(st) , _st(st)
, _text(text) , _text(_st.style, text, _checkboxOptions)
, _fullText(text)
, _textWidth(st.font->width(text))
, _checked(checked) { , _checked(checked) {
if (_st.width <= 0) { if (_st.width <= 0) {
resizeToWidth(_textWidth - _st.width); resizeToWidth(_text.maxWidth() - _st.width);
} else { } else {
if (_st.width < _st.textPosition.x() + _textWidth + (_st.textPosition.x() - _st.diameter)) {
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1));
_textWidth = _st.font->width(_text);
}
resizeToWidth(_st.width); resizeToWidth(_st.width);
} }
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter); _checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
@ -129,7 +130,7 @@ void Checkbox::finishAnimations() {
} }
int Checkbox::naturalWidth() const { int Checkbox::naturalWidth() const {
return _st.textPosition.x() + _st.font->width(_fullText); return _st.textPosition.x() + _text.maxWidth();
} }
void Checkbox::paintEvent(QPaintEvent *e) { void Checkbox::paintEvent(QPaintEvent *e) {
@ -157,9 +158,10 @@ void Checkbox::paintEvent(QPaintEvent *e) {
} }
if (_checkRect.contains(e->rect())) return; if (_checkRect.contains(e->rect())) return;
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
p.setPen(_st.textFg); p.setPen(_st.textFg);
p.setFont(_st.font); _text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
} }
void Checkbox::onClicked() { void Checkbox::onClicked() {
@ -195,19 +197,13 @@ QPoint Checkbox::prepareRippleStartPosition() const {
Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple) Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
, _st(st) , _st(st)
, _text(text) , _text(_st.style, text, _checkboxOptions)
, _fullText(text)
, _textWidth(st.font->width(text))
, _checked(checked) , _checked(checked)
, _group(radiobuttons.reg(group)) , _group(radiobuttons.reg(group))
, _value(value) { , _value(value) {
if (_st.width <= 0) { if (_st.width <= 0) {
resizeToWidth(_textWidth - _st.width); resizeToWidth(_text.maxWidth() - _st.width);
} else { } else {
if (_st.width < _st.textPosition.x() + _textWidth + (_st.textPosition.x() - _st.diameter)) {
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1));
_textWidth = _st.font->width(_text);
}
resizeToWidth(_st.width); resizeToWidth(_st.width);
} }
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter); _checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
@ -235,7 +231,7 @@ void Radiobutton::setChecked(bool checked) {
} }
int Radiobutton::naturalWidth() const { int Radiobutton::naturalWidth() const {
return _st.textPosition.x() + _st.font->width(_fullText); return _st.textPosition.x() + _text.maxWidth();
} }
void Radiobutton::paintEvent(QPaintEvent *e) { void Radiobutton::paintEvent(QPaintEvent *e) {
@ -278,9 +274,10 @@ void Radiobutton::paintEvent(QPaintEvent *e) {
} }
if (_checkRect.contains(e->rect())) return; if (_checkRect.contains(e->rect())) return;
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
p.setPen(_st.textFg); p.setPen(_st.textFg);
p.setFont(_st.font); _text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
} }
void Radiobutton::onClicked() { void Radiobutton::onClicked() {

View File

@ -63,8 +63,7 @@ signals:
private: private:
const style::Checkbox &_st; const style::Checkbox &_st;
QString _text, _fullText; Text _text;
int32 _textWidth;
QRect _checkRect; QRect _checkRect;
bool _checked; bool _checked;
@ -76,12 +75,12 @@ class Radiobutton : public RippleButton {
Q_OBJECT Q_OBJECT
public: public:
Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox); Radiobutton(QWidget *parent, const QString &group, int value, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox);
bool checked() const; bool checked() const;
void setChecked(bool checked); void setChecked(bool checked);
int32 val() const { int val() const {
return _value; return _value;
} }
@ -112,15 +111,14 @@ private:
const style::Checkbox &_st; const style::Checkbox &_st;
QString _text, _fullText; Text _text;
int32 _textWidth;
QRect _checkRect; QRect _checkRect;
bool _checked; bool _checked;
Animation _a_checked; Animation _a_checked;
void *_group; void *_group;
int32 _value; int _value;
}; };

View File

@ -311,7 +311,8 @@ bool InnerDropdown::eventFilter(QObject *obj, QEvent *e) {
int InnerDropdown::resizeGetHeight(int newWidth) { int InnerDropdown::resizeGetHeight(int newWidth) {
auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom(); auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
if (auto widget = static_cast<TWidget*>(_scroll->widget())) { if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
widget->resizeToWidth(newWidth - _st.padding.left() - _st.padding.right() - _st.scrollMargin.left() - _st.scrollMargin.right()); auto containerWidth = newWidth - _st.padding.left() - _st.padding.right() - _st.scrollMargin.left() - _st.scrollMargin.right();
widget->resizeToWidth(containerWidth);
newHeight += widget->height(); newHeight += widget->height();
} }
if (_maxHeight > 0) { if (_maxHeight > 0) {
@ -332,7 +333,7 @@ void InnerDropdown::Container::setVisibleTopBottom(int visibleTop, int visibleBo
} }
void InnerDropdown::Container::resizeToContent() { void InnerDropdown::Container::resizeToContent() {
auto newWidth = _st.scrollPadding.top() + _st.scrollPadding.bottom(); auto newWidth = _st.scrollPadding.left() + _st.scrollPadding.right();
auto newHeight = _st.scrollPadding.top() + _st.scrollPadding.bottom(); auto newHeight = _st.scrollPadding.top() + _st.scrollPadding.bottom();
if (auto child = static_cast<TWidget*>(children().front())) { if (auto child = static_cast<TWidget*>(children().front())) {
newWidth += child->width(); newWidth += child->width();
@ -344,8 +345,8 @@ void InnerDropdown::Container::resizeToContent() {
} }
int InnerDropdown::Container::resizeGetHeight(int newWidth) { int InnerDropdown::Container::resizeGetHeight(int newWidth) {
int innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right(); auto innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right();
int result = _st.scrollPadding.top() + _st.scrollPadding.bottom(); auto result = _st.scrollPadding.top() + _st.scrollPadding.bottom();
if (auto child = static_cast<TWidget*>(children().front())) { if (auto child = static_cast<TWidget*>(children().front())) {
child->resizeToWidth(innerWidth); child->resizeToWidth(innerWidth);
child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top());

View File

@ -34,6 +34,7 @@ TextParseOptions _labelOptions = {
0, // maxh 0, // maxh
Qt::LayoutDirectionAuto, // dir Qt::LayoutDirectionAuto, // dir
}; };
TextParseOptions _labelMarkedOptions = { TextParseOptions _labelMarkedOptions = {
TextParseMultiline | TextParseRichText | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands | TextParseMono, // flags TextParseMultiline | TextParseRichText | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands | TextParseMono, // flags
0, // maxw 0, // maxw

View File

@ -109,7 +109,7 @@ Checkbox {
radioSkip: pixels; radioSkip: pixels;
checkIcon: icon; checkIcon: icon;
font: font; style: TextStyle;
duration: int; duration: int;
rippleAreaPosition: point; rippleAreaPosition: point;
@ -641,7 +641,7 @@ defaultCheckbox: Checkbox {
checkIcon: defaultCheckboxIcon; checkIcon: defaultCheckboxIcon;
radioSkip: 65px; // * 0.1 radioSkip: 65px; // * 0.1
font: normalFont; style: defaultTextStyle;
duration: 120; duration: 120;
rippleAreaSize: 38px; rippleAreaSize: 38px;

View File

@ -25,6 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "styles/style_window.h" #include "styles/style_window.h"
#include "platform/platform_window_title.h" #include "platform/platform_window_title.h"
#include "window/window_theme.h" #include "window/window_theme.h"
#include "mediaview.h"
#include "mainwindow.h"
namespace Window { namespace Window {
@ -43,6 +45,57 @@ MainWindow::MainWindow() : QWidget()
subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); }); subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); });
} }
bool MainWindow::hideNoQuit() {
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->hide();
return true;
}
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
if (minimizeToTray()) {
Ui::showChatsList();
return true;
}
} else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
closeWithoutDestroy();
updateIsActive(Global::OfflineBlurTimeout());
updateGlobalMenu();
Ui::showChatsList();
return true;
}
}
void MainWindow::hideMediaview() {
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->hide();
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
onReActivate();
QTimer::singleShot(200, this, SLOT(onReActivate()));
#endif
}
}
void MainWindow::onReActivate() {
if (auto w = App::wnd()) {
if (auto f = QApplication::focusWidget()) {
f->clearFocus();
}
w->windowHandle()->requestActivate();
w->activate();
if (auto f = QApplication::focusWidget()) {
f->clearFocus();
}
w->setInnerFocus();
}
}
QWidget *MainWindow::filedialogParent() {
return (_mediaView && _mediaView->isVisible()) ? (QWidget*)_mediaView : (QWidget*)this;
}
void MainWindow::createMediaView() {
_mediaView.create(nullptr);
}
void MainWindow::init() { void MainWindow::init() {
initHook(); initHook();
@ -197,11 +250,25 @@ void MainWindow::savePosition(Qt::WindowState state) {
} }
} }
MainWindow::~MainWindow() { bool MainWindow::minimizeToTray() {
if (App::quitting() || !psHasTrayIcon()) return false;
closeWithoutDestroy();
if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) {
trayIcon->showMessage(str_const_toString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000);
cSetSeenTrayTooltip(true);
Local::writeSettings();
}
updateIsActive(Global::OfflineBlurTimeout());
updateTrayMenu();
updateGlobalMenu();
return true;
} }
void MainWindow::closeWithoutDestroy() { void MainWindow::closeWithoutDestroy() {
hide(); hide();
} }
MainWindow::~MainWindow() = default;
} // namespace Window } // namespace Window

View File

@ -22,6 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "window/window_title.h" #include "window/window_title.h"
class MediaView;
namespace Window { namespace Window {
class TitleWidget; class TitleWidget;
@ -32,6 +34,9 @@ class MainWindow : public QWidget, protected base::Subscriber {
public: public:
MainWindow(); MainWindow();
bool hideNoQuit();
void hideMediaview();
void init(); void init();
HitTestResult hitTest(const QPoint &p) const; HitTestResult hitTest(const QPoint &p) const;
@ -46,7 +51,7 @@ public:
return _titleText; return _titleText;
} }
virtual void closeWithoutDestroy(); QWidget *filedialogParent();
virtual ~MainWindow(); virtual ~MainWindow();
@ -54,6 +59,9 @@ public:
return _body.data(); return _body.data();
} }
public slots:
bool minimizeToTray();
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
@ -71,15 +79,22 @@ protected:
virtual void unreadCounterChangedHook() { virtual void unreadCounterChangedHook() {
} }
virtual void closeWithoutDestroy() {
hide();
}
// This one is overriden in Windows for historical reasons. // This one is overriden in Windows for historical reasons.
virtual int32 screenNameChecksum(const QString &name) const; virtual int32 screenNameChecksum(const QString &name) const;
void setPositionInited(); void setPositionInited();
void createMediaView();
private slots: private slots:
void savePositionByTimer() { void savePositionByTimer() {
savePosition(); savePosition();
} }
void onReActivate();
private: private:
void updatePalette(); void updatePalette();
@ -95,6 +110,8 @@ private:
QString _titleText; QString _titleText;
object_ptr<MediaView> _mediaView = { nullptr };
}; };
} // namespace Window } // namespace Window