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" = "Do you want to delete {count:_not_used_|# message|# messages}?";
"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_leave" = "Leave";

View File

@ -33,6 +33,16 @@ defaultBoxButton: RoundButton(defaultLightButton) {
font: boxButtonFont;
}
boxTextStyle: TextStyle(defaultTextStyle) {
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
boxLabelStyle: TextStyle(boxTextStyle) {
lineHeight: 22px;
}
attentionBoxButton: RoundButton(defaultBoxButton) {
textFg: attentionButtonFg;
textFgOver: attentionButtonFgOver;
@ -46,7 +56,7 @@ attentionBoxButton: RoundButton(defaultBoxButton) {
defaultBoxCheckbox: Checkbox(defaultCheckbox) {
width: -46px;
textPosition: point(34px, 1px);
font: boxTextFont;
style: boxTextStyle;
}
boxRoundShadow: Shadow {
@ -108,12 +118,9 @@ boxMediumSkip: 20px;
boxButtonPadding: margins(8px, 12px, 13px, 12px);
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
boxLabel: FlatLabel(defaultFlatLabel) {
width: 285px;
align: align(topleft);
style: TextStyle(defaultTextStyle) {
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
style: boxLabelStyle;
}
countryRowHeight: 36px;
@ -131,10 +138,6 @@ countriesScroll: ScrollArea(boxLayerScroll) {
deltab: 3px;
}
boxTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 22px;
}
boxPhotoTitleFont: font(16px semibold);
boxPhotoTitlePosition: point(28px, 20px);
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) {
_text.setText(st::boxTextStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
_text.setText(st::boxLabelStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
}
void ConfirmBox::prepare() {
@ -125,7 +125,7 @@ void ConfirmBox::prepare() {
void ConfirmBox::textUpdated() {
_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());
setMouseTracking(_text.hasLinks());
@ -219,7 +219,7 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, bas
}
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) {
}
@ -229,7 +229,7 @@ void MaxInviteBox::prepare() {
addButton(lang(lng_box_ok), [this] { closeBox(); });
_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());
}
@ -302,8 +302,8 @@ void ConvertToSupergroupBox::prepare() {
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
addButton(lang(lng_cancel), [this] { closeBox(); });
_text.setText(st::boxTextStyle, text.join('\n'), _confirmBoxTextOptions);
_note.setText(st::boxTextStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_text.setText(st::boxLabelStyle, text.join('\n'), _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();
_textHeight = _text.countHeight(_textWidth);
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
@ -408,54 +408,135 @@ bool PinMessageBox::pinFail(const RPCError &error) {
return true;
}
RichDeleteMessageBox::RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId)
: _channel(channel)
, _from(from)
, _msgId(msgId)
, _text(this, lang(lng_selected_delete_sure_this), Ui::FlatLabel::InitType::Simple, st::boxLabel)
, _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) {
DeleteMessagesBox::DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions) : _singleItem(true) {
_ids.push_back(item->fullId());
if (suggestModerateActions && item->suggestBanReportDeleteAll()) {
_moderateFrom = item->from()->asUser();
_moderateInChannel = item->history()->peer->asChannel();
}
}
void RichDeleteMessageBox::prepare() {
t_assert(_channel != nullptr);
DeleteMessagesBox::DeleteMessagesBox(QWidget*, const SelectedItemSet &selected) {
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_cancel), [this] { closeBox(); });
_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);
_text->moveToLeft(st::boxPadding.left(), st::boxPadding.top());
_banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
_reportSpam->moveToLeft(st::boxPadding.left(), _banUser->bottomNoMargins() + st::boxLittleSkip);
_deleteAll->moveToLeft(st::boxPadding.left(), _reportSpam->bottomNoMargins() + st::boxLittleSkip);
if (_moderateFrom) {
_banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
_reportSpam->moveToLeft(st::boxPadding.left(), _banUser->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() {
if (_banUser->checked()) {
MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
void DeleteMessagesBox::deleteAndClear() {
if (!App::main()) {
return;
}
if (_reportSpam->checked()) {
MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId))));
}
if (_deleteAll->checked()) {
App::main()->deleteAllFromUser(_channel, _from);
}
if (auto item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
auto wasLast = (item->history()->lastMsg == item);
item->destroy();
if (_msgId > 0) {
auto forEveryone = true;
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)), forEveryone);
} else if (wasLast) {
App::main()->checkPeerHistory(_channel);
if (_moderateFrom) {
if (_banUser->checked()) {
MTP::send(MTPchannels_KickFromChannel(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
}
if (_reportSpam->checked()) {
MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_vector<MTPint>(1, MTP_int(_ids[0].msg))));
}
if (_deleteAll->checked()) {
App::main()->deleteAllFromUser(_moderateInChannel, _moderateFrom);
}
}
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();
if (wasOnServer) {
idsByPeer[history->peer].push_back(MTP_int(fullId.msg));
} else if (wasLast) {
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();
}

View File

@ -170,9 +170,10 @@ private:
};
class RichDeleteMessageBox : public BoxContent, public RPCSender {
class DeleteMessagesBox : public BoxContent, public RPCSender {
public:
RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId);
DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions);
DeleteMessagesBox(QWidget*, const SelectedItemSet &selected);
protected:
void prepare() override;
@ -182,14 +183,16 @@ protected:
private:
void deleteAndClear();
ChannelData *_channel;
UserData *_from;
MsgId _msgId;
QVector<FullMsgId> _ids;
bool _singleItem = false;
UserData *_moderateFrom = nullptr;
ChannelData *_moderateInChannel = nullptr;
object_ptr<Ui::FlatLabel> _text;
object_ptr<Ui::Checkbox> _banUser;
object_ptr<Ui::Checkbox> _reportSpam;
object_ptr<Ui::Checkbox> _deleteAll;
object_ptr<Ui::FlatLabel> _text = { nullptr };
object_ptr<Ui::Checkbox> _forEveryone = { nullptr };
object_ptr<Ui::Checkbox> _banUser = { nullptr };
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);
_aboutHeight = 0;
} 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();
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
_aboutHeight = 0;

View File

@ -148,7 +148,7 @@ StickersBox::StickersBox(QWidget*, const Stickers::Order &archivedIds)
: _section(Section::ArchivedPart)
, _archived(0, this, archivedIds)
, _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) {

View File

@ -316,18 +316,7 @@ PeerData *getPeerForMouseAction() {
bool hideWindowNoQuit() {
if (!App::quitting()) {
if (auto w = App::wnd()) {
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
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;
}
w->hideNoQuit();
}
}
return false;

View File

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

View File

@ -772,6 +772,18 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
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 {
// Messages from myself are always read.
if (history()->peer->isSelf()) return false;

View File

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

View File

@ -2848,7 +2848,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
_send->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 {
h += st::historyForwardChooseFont->height;
_send->hide();
@ -2862,7 +2862,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
bool HistoryHider::offerPeer(PeerId peer) {
if (!peer) {
_offered = nullptr;
_toText.setText(st::boxTextStyle, QString());
_toText.setText(st::boxLabelStyle, QString());
_toTextWidth = 0;
resizeEvent(nullptr);
return false;
@ -2902,7 +2902,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
return false;
}
_toText.setText(st::boxTextStyle, phrase, _textNameOptions);
_toText.setText(st::boxLabelStyle, phrase, _textNameOptions);
_toTextWidth = _toText.maxWidth();
if (_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();
if (!item || item->type() != HistoryItemMsg) return;
auto message = item->toHistoryMessage();
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1);
if (auto message = item->toHistoryMessage()) {
if (message->uploading()) {
App::main()->cancelUploadLayer();
return;
}
}
App::main()->deleteLayer();
}
void HistoryWidget::confirmDeleteSelectedItems() {

View File

@ -660,43 +660,39 @@ void MainWidget::forwardLayer(int forwardSelected) {
}
void MainWidget::deleteLayer(int selectedCount) {
if (selectedCount == -1 && !_overview) {
if (auto item = App::contextItem()) {
if (item->suggestBanReportDeleteAll()) {
Ui::show(Box<RichDeleteMessageBox>(item->history()->peer->asChannel(), item->from()->asUser(), item->id));
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());
}
}
Ui::show(Box<ConfirmBox>(text, confirmText, cancelText, base::lambda_guarded(this, [this, selectedCount] {
if (selectedCount < 0) {
if (_overview) {
_overview->deleteContextItem(false);
} else {
_history->deleteContextItem(false);
}
if (selectedCount < -1) {
App::uploader()->unpause();
}
if (selectedCount) {
auto forDelete = true;
SelectedItemSet selected;
if (_overview) {
_overview->fillSelectedItems(selected, forDelete);
} else {
if (_overview) {
_overview->deleteSelectedItems(false);
} else {
_history->deleteSelectedItems(false);
}
_history->fillSelectedItems(selected, forDelete);
}
}), base::lambda_guarded(this, [selectedCount] {
if (selectedCount < -1) {
App::uploader()->unpause();
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;
}
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] {
if (_overview) {
_overview->deleteContextItem(false);
} else {
_history->deleteContextItem(false);
}
App::uploader()->unpause();
}), base::lambda_guarded(this, [] {
App::uploader()->unpause();
})));
}

View File

@ -228,7 +228,8 @@ public:
int32 dlgsWidth() const;
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 shareUrlLayer(const QString &url, const QString &text);
void inlineSwitchLayer(const QString &botAndQuery);

View File

@ -204,11 +204,7 @@ void MainWindow::firstShow() {
psFirstShow();
updateTrayMenu();
_mediaView = new MediaView();
}
QWidget *MainWindow::filedialogParent() {
return (_mediaView && _mediaView->isVisible()) ? (QWidget*)_mediaView : (QWidget*)this;
createMediaView();
}
void MainWindow::clearWidgets() {
@ -600,30 +596,6 @@ void MainWindow::layerHidden() {
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) {
if (_main && _main->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);
}
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) {
if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return;
@ -1450,7 +1407,6 @@ MainWindow::~MainWindow() {
_clearManager->stop();
_clearManager = nullptr;
}
delete _mediaView;
delete trayIcon;
delete trayIconMenu;
}

View File

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

View File

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

View File

@ -67,7 +67,7 @@ bool typeHasMediaOverview(MediaOverviewType type) {
} // namespace
MediaView::MediaView() : TWidget(App::wnd())
MediaView::MediaView(QWidget*) : TWidget(nullptr)
, _animStarted(getms())
, _docDownload(this, lang(lng_media_download), 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))
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
, _a_state(animation(this, &MediaView::step_state))
, _dropdown(this, st::mediaviewDropdownMenu) {
, _dropdown(this, st::mediaviewDropdownMenu)
, _dropdownShowTimer(this) {
TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
_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()));
_dropdown->setHiddenCallback([this] { dropdownHidden(); });
_dropdownShowTimer->setSingleShot(true);
connect(_dropdownShowTimer, SIGNAL(timeout()), this, SLOT(onDropdown()));
}
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());
_themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin);
if (_themeApply) {
auto right = width() - _themePreviewRect.x() - _themePreviewRect.width() + st::themePreviewMargin.right();
_themeApply->moveToRight(right, _themePreviewRect.y() + _themePreviewRect.height() - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2);
auto right = qMax(width() - _themePreviewRect.x() - _themePreviewRect.width(), 0) + st::themePreviewMargin.right();
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;
_themeCancel->moveToRight(right, _themeApply->y());
}
@ -2370,7 +2374,9 @@ bool MediaView::updateOverState(OverState newState) {
bool result = true;
if (_over != newState) {
if (newState == OverMore && !_ignoringDropdown) {
QTimer::singleShot(0, this, SLOT(onDropdown()));
_dropdownShowTimer->start(0);
} else {
_dropdownShowTimer->stop();
}
updateOverRect(_over);
updateOverRect(newState);
@ -2393,7 +2399,7 @@ bool MediaView::updateOverState(OverState newState) {
if (i != _animOpacities.end()) {
i->start(1);
} else {
_animOpacities.insert(_over, anim::value());
_animOpacities.insert(_over, anim::value(0, 1));
}
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
public:
MediaView();
MediaView(QWidget*);
void setVisible(bool visible) override;
@ -330,6 +330,7 @@ private:
Ui::PopupMenu *_menu = nullptr;
object_ptr<Ui::DropdownMenu> _dropdown;
object_ptr<QTimer> _dropdownShowTimer;
struct ActionData {
QString text;

View File

@ -2276,16 +2276,21 @@ void OverviewWidget::confirmDeleteContextItem() {
auto item = App::contextItem();
if (!item || item->type() != HistoryItemMsg) return;
auto message = item->toHistoryMessage();
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1);
if (auto message = item->toHistoryMessage()) {
if (message->uploading()) {
App::main()->cancelUploadLayer();
return;
}
}
App::main()->deleteLayer();
}
void OverviewWidget::confirmDeleteSelectedItems() {
SelectedItemSet sel;
_inner->fillSelectedItems(sel);
if (sel.isEmpty()) return;
SelectedItemSet selected;
_inner->fillSelectedItems(selected);
if (selected.isEmpty()) return;
App::main()->deleteLayer(sel.size());
App::main()->deleteLayer(selected.size());
}
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;
void closeWithoutDestroy() override;
int getCustomTitleHeight() const {
return _customTitleHeight;
}
@ -103,6 +101,8 @@ protected:
QTimer psUpdatedPositionTimer;
void closeWithoutDestroy() override;
private:
void createGlobalMenu();
void updateTitleCounter();

View File

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

View File

@ -79,6 +79,13 @@ public:
Radiobuttons radiobuttons;
TextParseOptions _checkboxOptions = {
TextParseMultiline, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
} // namespace
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)
, _st(st)
, _text(text)
, _fullText(text)
, _textWidth(st.font->width(text))
, _text(_st.style, text, _checkboxOptions)
, _checked(checked) {
if (_st.width <= 0) {
resizeToWidth(_textWidth - _st.width);
resizeToWidth(_text.maxWidth() - _st.width);
} 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);
}
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
@ -129,7 +130,7 @@ void Checkbox::finishAnimations() {
}
int Checkbox::naturalWidth() const {
return _st.textPosition.x() + _st.font->width(_fullText);
return _st.textPosition.x() + _text.maxWidth();
}
void Checkbox::paintEvent(QPaintEvent *e) {
@ -157,9 +158,10 @@ void Checkbox::paintEvent(QPaintEvent *e) {
}
if (_checkRect.contains(e->rect())) return;
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
p.setPen(_st.textFg);
p.setFont(_st.font);
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
_text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
}
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)
, _st(st)
, _text(text)
, _fullText(text)
, _textWidth(st.font->width(text))
, _text(_st.style, text, _checkboxOptions)
, _checked(checked)
, _group(radiobuttons.reg(group))
, _value(value) {
if (_st.width <= 0) {
resizeToWidth(_textWidth - _st.width);
resizeToWidth(_text.maxWidth() - _st.width);
} 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);
}
_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 {
return _st.textPosition.x() + _st.font->width(_fullText);
return _st.textPosition.x() + _text.maxWidth();
}
void Radiobutton::paintEvent(QPaintEvent *e) {
@ -278,9 +274,10 @@ void Radiobutton::paintEvent(QPaintEvent *e) {
}
if (_checkRect.contains(e->rect())) return;
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
p.setPen(_st.textFg);
p.setFont(_st.font);
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
_text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
}
void Radiobutton::onClicked() {

View File

@ -63,8 +63,7 @@ signals:
private:
const style::Checkbox &_st;
QString _text, _fullText;
int32 _textWidth;
Text _text;
QRect _checkRect;
bool _checked;
@ -76,12 +75,12 @@ class Radiobutton : public RippleButton {
Q_OBJECT
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;
void setChecked(bool checked);
int32 val() const {
int val() const {
return _value;
}
@ -112,15 +111,14 @@ private:
const style::Checkbox &_st;
QString _text, _fullText;
int32 _textWidth;
Text _text;
QRect _checkRect;
bool _checked;
Animation _a_checked;
void *_group;
int32 _value;
int _value;
};

View File

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

View File

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

View File

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

View File

@ -25,6 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "styles/style_window.h"
#include "platform/platform_window_title.h"
#include "window/window_theme.h"
#include "mediaview.h"
#include "mainwindow.h"
namespace Window {
@ -43,6 +45,57 @@ MainWindow::MainWindow() : QWidget()
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() {
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() {
hide();
}
MainWindow::~MainWindow() = default;
} // namespace Window

View File

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